Angular 6, AGM selects first address in google aut

2020-02-11 07:40发布

问题:

Am using AGM for google address suggestion in my angular project. I want to select the first address if user didn't select any.

Please anyone give some suggestions for this.

Thanks in advance.

回答1:

After so much time spending on searching for the solution finally found it,

If you have already implemented the google address suggestion(autocomplete) in Angular 2,4 5 & 6 and want to select the First suggestion by default, Here we go with working example,

We have to create an services separately and need to subscribe it. I have given working example below this,

Important: Be patient to look into it and alter names and all It will definitely work.


app.component.ts

import { Component } from '@angular/core';
import { MapsAPILoader } from '@agm/core';
import { PlacePredictionService } from './place-prediction.service';

import { Observable } from 'rxjs/Observable';

@Component({
   selector: 'app-root',
   templateUrl: './app.component.html',
   styleUrls: ['./app.component.css']
})
export class AppComponent {

  private searchTerm: string;
  private results$: Observable<any[]>;

  testResult = [{description: 'test'},{description: 'test'}];

  constructor(
    private mapsAPILoader: MapsAPILoader,
    private placePredictionService: PlacePredictionService
  ){}

  onSearch(term: string){

  this.searchTerm = term;

  if (this.searchTerm === '') return;

  this.results$ = this.placePredictionService.getPlacePredictions(term);

 }

}

place-prediction.service.ts

import { Injectable } from "@angular/core";
import { MapsAPILoader } from "@agm/core";

import { Observable } from "rxjs/Observable";

import "rxjs/add/observable/of";
import "rxjs/add/observable/bindCallback";

@Injectable()
export class PlacePredictionService {
  private autocompleteService;

  constructor(private mapsAPILoader: MapsAPILoader) {

    this.mapsAPILoader.load().then(() => {
      this.autocompleteService = new 
      google.maps.places.AutocompleteService();
    });

  }

  // Wrapper for Google Places Autocomplete Prediction API, returns 
  observable

  getPlacePredictions(term: string): Observable<any[]> {
    return Observable.create(observer => {
    // API Call

    this.autocompleteService.getPlacePredictions({ input: term }, data => {
      let previousData: Array<any[]>;

      // Data validation

      if (data) {
        console.log(data);
        previousData = data;
        observer.next(data);
        observer.complete();
      }

      // If no data, emit previous data

      if (!data) {
        console.log("PreviousData: ");
        observer.next(previousData);
        observer.complete();

        // Error Handling

      } else {
        observer.error(status);
      }

    });

    });

    }
  }

app.component.html

<h1>Google Places Test</h1>

<p>Angular 5 &amp; RxJS refresher</p>

<input
  type="search"
  placeholder="Search for place" 
  autocomplete="off"
  autocapitalize="off"
  autofocus
  #search
  (keyup)="onSearch(search.value)"/> 

 <p>{{ searchTerm }}</p>

 <ul>

   <li *ngFor="let result of results$ | async "> {{result.description}} 
   </li>

 </ul>

For me it is worked, If you face any problem please add your comment(or mail me @ saravanava3@gmail.com), If I am aware about your query I will reply back



回答2:

I couldn't make it work. Maybe because of using Angular 7. Here is my attempt using BehaviorSubject.

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AgmCoreModule } from '@agm/core';

import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AgmCoreModule.forRoot({
      apiKey: 'YOUR API KEY',
      libraries: ['places']
    })
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

google-result.model.ts

export interface GoogleResult {
  description: string;
  id: string;
  matched_substrings: Matchedsubstring[];
  place_id: string;
  reference: string;
  structured_formatting: Structuredformatting;
  terms: Term[];
  types: string[];
}

interface Term {
  offset: number;
  value: string;
}

interface Structuredformatting {
  main_text: string;
  main_text_matched_substrings: Matchedsubstring[];
  secondary_text: string;
}

interface Matchedsubstring {
  length: number;
  offset: number;
}

place-prediction.service.ts

import { Injectable } from '@angular/core';
import { MapsAPILoader } from '@agm/core';
import { Observable, BehaviorSubject } from 'rxjs';
import { GoogleResult } from './google-result.model';

declare var google: any;

@Injectable({
  providedIn: 'root',
})
export class PlacePredictionService {
  private data: BehaviorSubject<any> = new BehaviorSubject<any>([]);
  currentData = this.data.asObservable();

  public autocompleteService: any;

  constructor(private mapsAPILoader: MapsAPILoader) {
    this.mapsAPILoader.load().then(() => {
      this.autocompleteService = new google.maps.places.AutocompleteService();
    });
  }

  getPlacePredictions(term: string): Observable<Object[]> {
    return this.autocompleteService.getPlacePredictions({ input: term }, (data: GoogleResult[]) => {
      if (data) {
        console.log(data);
        this.data.next(data);
      }
    });
  }
}

app.component.html

<h2>Google Places Test</h2>

<p>Angular 7 &amp; RxJS refresher</p>

<input
  type="search"
  placeholder="Search for place"
  autocomplete="off"
  autocapitalize="off"
  autofocus
  #search
  (keyup)="onSearch(search.value)"
/>

<p>{{ searchTerm }}</p>

<ul>
  <li *ngFor="let result of googlePlacesResults">
    <p>{{ result.description }}</p>
  </li>
</ul>

app.component.ts

import { Component, OnInit } from '@angular/core';

import { PlacePredictionService } from './place-prediction.service';
import { GoogleResult } from './google-result.model';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent implements OnInit {
  searchTerm: string;
  googlePlacesResults: GoogleResult[] = [];

  title = 'google-place-prediction';

  constructor(private placePredictionService: PlacePredictionService) {}

  ngOnInit() {
    this.getData();
  }

  getData() {
    this.placePredictionService.currentData.subscribe((response: GoogleResult[]) => {
      this.googlePlacesResults = response;
    });
  }

  onSearch(term: string) {
    this.searchTerm = term;

    if (this.searchTerm === '') {
      return;
    }

    this.placePredictionService.getPlacePredictions(term);
  }
}

results