Skip to content

Commit

Permalink
feat(package): simplify the library by adding the `matGoogleMapsAutoc…
Browse files Browse the repository at this point in the history
…omplete` directive
  • Loading branch information
AnthonyNahas committed Aug 9, 2018
1 parent 93efcf9 commit f2b7b63
Show file tree
Hide file tree
Showing 2 changed files with 148 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import {MatGoogleMapsAutocompleteDirective} from './mat-google-maps-autocomplete.directive';
import {async, TestBed} from '@angular/core/testing';
import {Component, DebugElement, ElementRef, NgZone} from '@angular/core';
import {MapsAPILoader} from '@agm/core';
import {environment} from '../../../demo/src/environments/environment';
import {MockNgZone} from '../testing/mock-ng-zone';

@Component({
template: `<input type="text">`
})
class TestGoogleMapsAutoCompleteComponent {
}

describe('MatGoogleMapsAutocompleteDirective', () => {

let directive: MatGoogleMapsAutocompleteDirective;
let inputEl: DebugElement;

const elementRefPartial: Partial<ElementRef> = {};
const mapsAPILoaderPartial: Partial<MapsAPILoader> = {};
const ngZonePartial: Partial<NgZone> = {run: (fn: Function) => fn()};

// spyOn(ngZonePartial, 'run').and.callFake((fn: Function) => fn());

const googleMapsParams = {
apiKey: environment.GOOGLE_MAPS_API_KEY,
libraries: ['places'],
language: 'en',
// region: 'DE'
};

beforeEach(async(() => {

TestBed.configureTestingModule({
// imports: [AgmCoreModule.forRoot(googleMapsParams)],
declarations: [],
providers: [
{provide: ElementRef, useValue: elementRefPartial},
{provide: MapsAPILoader, useValue: mapsAPILoaderPartial},
{provide: NgZone, useClass: MockNgZone},
]
}).compileComponents();
}));

beforeEach(() => {
directive = new MatGoogleMapsAutocompleteDirective(
TestBed.get(ElementRef),
TestBed.get(MapsAPILoader),
TestBed.get(NgZone));
});

it('should create an instance', () => {
expect(directive).toBeTruthy();
});
});
93 changes: 93 additions & 0 deletions src/module/directives/mat-google-maps-autocomplete.directive.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import {Directive, ElementRef, EventEmitter, Input, NgZone, OnInit, Output} from '@angular/core';
import {MapsAPILoader} from '@agm/core';
import {Location} from '../interfaces/location.interface';
import PlaceResult = google.maps.places.PlaceResult;
import AutocompleteOptions = google.maps.places.AutocompleteOptions;

@Directive({
selector: '[matGoogleMapsAutocomplete]',
exportAs: '[matGoogleMapsAutocomplete]',
})
export class MatGoogleMapsAutocompleteDirective implements OnInit {

@Input()
address: PlaceResult | string;

@Input()
country: string | string[];

@Input()
placeIdOnly?: boolean;

@Input()
strictBounds?: boolean;

@Input()
types?: string[];

@Input()
type?: string;

@Input()
autoCompleteOptions: AutocompleteOptions = {};

@Output()
onChange: EventEmitter<PlaceResult | string | null> = new EventEmitter<PlaceResult | string | null>();

@Output()
onAutocompleteSelected: EventEmitter<PlaceResult> = new EventEmitter<PlaceResult>();

@Output()
onLocationSelected: EventEmitter<Location> = new EventEmitter<Location>();

constructor(public elemRef: ElementRef,
public mapsAPILoader: MapsAPILoader,
private _ngZone: NgZone) {
}

ngOnInit(): void {
const options = {
// types: ['address'],
componentRestrictions: {country: this.country},
placeIdOnly: this.placeIdOnly,
strictBounds: this.strictBounds,
types: this.types,
type: this.type
};

this.autoCompleteOptions = Object.assign(this.autoCompleteOptions, options);
this.initGoogleMapsAutocomplete();

}

public initGoogleMapsAutocomplete() {
this.mapsAPILoader
.load()
.then(() => {
const autocomplete = new google.maps.places.Autocomplete(this.elemRef.nativeElement, this.autoCompleteOptions);
autocomplete.addListener('place_changed', () => {
this._ngZone.run(() => {
// get the place result
const place: PlaceResult = autocomplete.getPlace();

if (!place.place_id || place.geometry === undefined || place.geometry === null) {
// place result is not valid
return;
} else {
// show dialog to select a address from the input
// emit failed event
}
this.address = place.formatted_address;
this.onAutocompleteSelected.emit(place);
this.onLocationSelected.emit(
{
latitude: place.geometry.location.lat(),
longitude: place.geometry.location.lng()
})
});
});
})
.catch((err) => console.log(err));
}

}

0 comments on commit f2b7b63

Please sign in to comment.