Google Map in Sharepoint SPFx with Angular

1) Introduction

This article is going to describe how to set up Sharepoint Framework (SPFx) Development with Angular using a template project created by Sahil Malik which is available at https://github.com/maliksahil/SPFxAngularCLI

I modified Sahil's work, integrated Google Map API and Goodzer API to an Angular Sharepoint SPFx web part. The modified code is available at https://github.com/shahimsadakath/spfx-google-map-sample


If you are new to Sharepoint SPFx and you haven't set up your development environment yet. My previous article at http://shadotnet.blogspot.com/2018/05/starting-sharepoint-framework-spfx.html will be useful.

Let's get started.

2) Steps to integrate Goodzer API


  1. Register yourself at https://developer.goodzer.com/signup/ and get a free API Key 
  2. I added a file named app.settings.ts to store the API Key as shown below in src->app folder
export class AppSettings {    
         public static GOODZER_API_ENDPOINT='https://api.goodzer.com/products/v0.1/';
          public static GOODZER_API_KEY ='{your_API_Key}';
            public static GMAP_URL = "https://maps.google.com/maps/api/js?key={your_API_Key}";
               }


              3. I added goodzer.service.ts in src -> services to access the Goodzer API as shown below


          import { Injectable } from '@angular/core';

          import {Http,Headers,RequestOptions, Response } from '@angular/http';

          import { AppSettings } from '../app.settings';

          import { Observable } from 'rxjs';
          import 'rxjs/add/operator/map'

          @Injectable()
          export class GoodzerService {
               constructor(private http: Http) { 
                 
             }

             searchLocations(searchText:string,latitude:string,longitude:string) : Observable<any>
             {
                  let headers: Headers = new Headers();
             headers.append('Accept', 'application/json');
             headers.append('Content-Type', 'application/json');
             headers.append('Access-Control-Allow-Origin', '*');

             let options = new RequestOptions({
               headers: headers
             });

            
                 
                 return this.http.get(AppSettings.GOODZER_API_ENDPOINT
                   +'/search_locations/?query='+
                   searchText+
                   '&lat='+latitude+'&lng='+longitude+'&radius=5.0&apiKey='+AppSettings.GOODZER_API_KEY,options)
                      .map((response: Response) => {
                          //console.log(response);
                          return response.json();
                      }).catch(this.handleError);
             }

             searchStores(searchText:string,latitude:string,longitude:string) : Observable<any>
             {
                  let headers: Headers = new Headers();
             headers.append('Accept', 'application/json');
             headers.append('Content-Type', 'application/json');
             headers.append('Access-Control-Allow-Origin', '*');

             let options = new RequestOptions({
               headers: headers
             });

            
                 
                 return this.http.get(AppSettings.GOODZER_API_ENDPOINT
                   +'/search_stores/?query='+
                   searchText+
                   '&lat='+latitude+'&lng='+longitude+'&radius=5.0&apiKey='+AppSettings.GOODZER_API_KEY,options)
                      .map((response: Response) => {
                          
                          return response.json();
                      }).catch(this.handleError);
             }

             searchInStores(searchText:string,storeId:string) : Observable<any>
             {
                  let headers: Headers = new Headers();
             headers.append('Accept', 'application/json');
             headers.append('Content-Type', 'application/json');
             headers.append('Access-Control-Allow-Origin', '*');

             let options = new RequestOptions({
               headers: headers
             });

            
                 
                 return this.http.get(AppSettings.GOODZER_API_ENDPOINT
                   +'/search_in_store/?query='+
                   searchText+
                   '&storeId='+storeId+'&apiKey='+AppSettings.GOODZER_API_KEY,options)
                      .map((response: Response) => {
                          console.log(response);
                          return response.json();
                      }).catch(this.handleError);
             }

             private handleError (error: Response | any) {
                  // In a real world app, we might use a remote logging infrastructure
                  let errMsg: string;
                  if (error instanceof Response) {
                    const body = error.json() || '';
                    const err = body.error || JSON.stringify(body);
                    errMsg = `${error.status} - ${error.statusText || ''} ${err}`;
                  }else {
                    errMsg = error.message ? error.message : error.toString();
                  }
                  //console.log(error);
                  return Observable.throw(errMsg);
              }

          }

          3) Steps to integrate Google Maps API


          1. Register yourself at https://developers.google.com/maps/documentation/javascript/get-api-key and get an API key
          2. Replace the GMAP_URL within app.settings.ts with the API Key
          3. Add the following method to app.component.ts to inject the scripts required generate map and call method in the constructor
          addMapsScript() {    if (!document.querySelectorAll(`[src="${AppSettings.GMAP_URL}"]`).length) { 
                document.body.appendChild(Object.assign(
                  document.createElement('script'), {
                    type: 'text/javascript',
                    src: AppSettings.GMAP_URL,
                    onload: () => this.doMapInitLogic()
                  }));
              } else {
                this.doMapInitLogic();
              }
            }

          4) Demo


          1. Go to the folder of the project (E:\Software\Sharepoint\SPFxAngular\SPFxAngular in my case) from windows command prompt
          2. Type "gulp serve" and hit enter
          3. Add the Web Part to the Sharepoint workbench
          4. By default the map will Load the GPS Coordinates of New York as shown below

          5. But you can Edit the web part as shown below and change the coordinates to any city within United States, I changed it to Chicago.












          6. Then reload the page now you will see that city Chicago as below















          7. Type any product in Search Bar and Press Search button, it will call the Goodzer API to find the shops having the product you searched for and mark them on the map.


           










          8. You can click on any shop and Get the direction by clicking "Get Directions" button as shown below












          5) References and Further Reading

          https://docs.microsoft.com/en-us/sharepoint/dev/spfx/sharepoint-framework-overview
          https://developer.goodzer.com/docs/
          https://developers.google.com/maps/documentation/javascript/tutorial
          https://www.youtube.com/watch?v=_OgEqWtouuU


          Comments