Skip to content

Commit

Permalink
Change Google Maps loading strategy (#40)
Browse files Browse the repository at this point in the history
  • Loading branch information
artfulsage authored Jan 11, 2021
1 parent 03fccd3 commit eca775d
Show file tree
Hide file tree
Showing 12 changed files with 87 additions and 71 deletions.
3 changes: 3 additions & 0 deletions src/src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import { MatIconModule } from '@angular/material/icon';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { MatMenuModule } from '@angular/material/menu';
import { environment } from 'src/environments/environment';
import { GoogleMapsConfigModule } from 'src/app/google-maps';

@NgModule({
declarations: [
Expand All @@ -31,6 +33,7 @@ import { MatMenuModule } from '@angular/material/menu';
MatFormFieldModule,
MatInputModule,
MatMenuModule,
GoogleMapsConfigModule.forRoot(environment.googleMapApiKey),
],
providers: [],
bootstrap: [AppComponent]
Expand Down
3 changes: 3 additions & 0 deletions src/src/app/google-maps/api-key.token.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { InjectionToken } from '@angular/core';

export const GOOGLE_MAPS_API_KEY = new InjectionToken<string>('Google Maps API key');
20 changes: 20 additions & 0 deletions src/src/app/google-maps/config.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { HttpClientJsonpModule, HttpClientModule } from '@angular/common/http';
import { ModuleWithProviders, NgModule } from '@angular/core';
import { GOOGLE_MAPS_API_KEY } from 'src/app/google-maps/api-key.token';

@NgModule({
imports: [
HttpClientModule,
HttpClientJsonpModule,
],
})
export class GoogleMapsConfigModule {
static forRoot(googleMapsApiKey: string): ModuleWithProviders<GoogleMapsConfigModule> {
return <ModuleWithProviders<GoogleMapsConfigModule>> {
ngModule: GoogleMapsConfigModule,
providers: [
{ provide: GOOGLE_MAPS_API_KEY, useValue: googleMapsApiKey, },
],
};
}
}
2 changes: 2 additions & 0 deletions src/src/app/google-maps/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './config.module';
export * from './script-loader';
40 changes: 40 additions & 0 deletions src/src/app/google-maps/script-loader.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { HttpClient, HttpParams } from '@angular/common/http';
import { Inject, Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, Resolve, RouterStateSnapshot } from '@angular/router';
import { Observable, of } from 'rxjs';
import { catchError, map, publishReplay, refCount } from 'rxjs/operators';
import { GOOGLE_MAPS_API_KEY } from './api-key.token';

const SCRIPT_URL = 'https://maps.googleapis.com/maps/api/js';

@Injectable({
providedIn: 'root',
})
export class GoogleMapsScriptLoader implements Resolve<boolean> {
readonly scriptLoaded$: Observable<boolean>;

constructor(
@Inject(GOOGLE_MAPS_API_KEY) apiKey: string,
httpClient: HttpClient,
) {
this.scriptLoaded$ = this._loadScript(httpClient, apiKey)
.pipe(
publishReplay(1),
refCount(),
);
}

resolve(_route: ActivatedRouteSnapshot, _state: RouterStateSnapshot): Observable<boolean> {
return this.scriptLoaded$;
}

_loadScript(httpClient: HttpClient, apiKey: string): Observable<boolean> {
const queryParams = new HttpParams().append('key', apiKey);
const url = `${SCRIPT_URL}?${queryParams.toString()}`;

return httpClient.jsonp(url, 'callback').pipe(
map(() => true),
catchError(() => of(false)),
);
}
}
30 changes: 14 additions & 16 deletions src/src/app/main/components/google-map/google-map.component.html
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
<ng-container *ngIf="loaded$ | async">
<google-map
class="map"
height="100%"
(mapClick)="addMarker($event)"
[options]="options"
width="100%"
>
<ng-container *ngFor="let marker of addedMarkersForMap$ | async">
<map-marker [position]="marker"></map-marker>
</ng-container>
<google-map
class="map"
height="100%"
(mapClick)="addMarker($event)"
[options]="options"
width="100%"
>
<ng-container *ngFor="let marker of addedMarkersForMap$ | async">
<map-marker [position]="marker"></map-marker>
</ng-container>

<ng-container *ngFor="let marker of gottenMarkersForMap$ | async">
<map-marker [position]="marker"></map-marker>
</ng-container>
</google-map>
</ng-container>
<ng-container *ngFor="let marker of gottenMarkersForMap$ | async">
<map-marker [position]="marker"></map-marker>
</ng-container>
</google-map>
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { map, scan, shareReplay, tap } from 'rxjs/operators';

import { GoogleMapViewConfig } from '../../models/google-map-view-config';
import { Marker } from '../../models/marker';
import { GoogleMapScriptLoaderService } from '../../services/google-map-script-loader.service';
import { GoogleMapViewConfigService } from '../../services/google-map-view-config.service';
import { MarkerStorageService } from '../../services/marker-storage.service';

Expand All @@ -15,7 +14,6 @@ import { MarkerStorageService } from '../../services/marker-storage.service';
styleUrls: ['./google-map.component.css'],
})
export class GoogleMapComponent {
readonly loaded$ = this._loader.loadScript().pipe(shareReplay());
readonly options = this._config.options;

private readonly _addedMarker$ = new ReplaySubject<Marker>(1);
Expand All @@ -38,7 +36,6 @@ export class GoogleMapComponent {
constructor(
@Inject(GoogleMapViewConfigService)
private readonly _config: GoogleMapViewConfig,
private readonly _loader: GoogleMapScriptLoaderService,
private readonly _markerStorage: MarkerStorageService
) {}

Expand Down
5 changes: 4 additions & 1 deletion src/src/app/main/main.routes.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { Routes } from '@angular/router';

import { GoogleMapsScriptLoader } from 'src/app/google-maps';
import { MainComponent } from './main.component';

export const routes: Routes = [
{
path: '',
component: MainComponent,
resolve: {
googleMapsScriptLoaded: GoogleMapsScriptLoader,
},
},
];
13 changes: 1 addition & 12 deletions src/src/app/main/maps.module.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,11 @@
import { CommonModule } from '@angular/common';
import { HttpClientJsonpModule, HttpClientModule } from '@angular/common/http';
import { NgModule } from '@angular/core';

import { environment } from '../../environments/environment';
import { GoogleMapApiConfig } from './models/google-map-api-config';
import { GoogleMapViewConfig } from './models/google-map-view-config';
import { GoogleMapApiConfigService } from './services/google-map-api-config.service';
import { GoogleMapViewConfigService } from './services/google-map-view-config.service';

@NgModule({
imports: [CommonModule, HttpClientModule, HttpClientJsonpModule],
imports: [CommonModule],
providers: [
{
provide: GoogleMapApiConfigService,
useValue: <GoogleMapApiConfig>{
googleMapApiKey: environment.googleMapApiKey,
},
},
{
provide: GoogleMapViewConfigService,
useValue: <GoogleMapViewConfig>{
Expand Down
3 changes: 0 additions & 3 deletions src/src/app/main/models/google-map-api-config.ts

This file was deleted.

7 changes: 0 additions & 7 deletions src/src/app/main/services/google-map-api-config.service.ts

This file was deleted.

29 changes: 0 additions & 29 deletions src/src/app/main/services/google-map-script-loader.service.ts

This file was deleted.

0 comments on commit eca775d

Please sign in to comment.