Search code examples
javascriptangularfirebasegoogle-cloud-firestoreangularfire

Bind AngularFire data to a property after waiting for async data


I want to get a specific document from Firestore with AngularFire using URL params that contains lat/lng coordinates and then bind those coordinates to a google-map component's [center] property to display the map dynamically depending on which item is viewed. But the data isn't connecting to the google map property, so it's defaulting to centering on the Google HQ location.

The master component List passes an id for an event in the URL hike/:hikeId which I extract and then use AngularFire to get the document.

hike-detail.component.html

<h1>Hike Detail</h1>
<h3>Name: <span>{{ (hikeInfo | async)?.name }}</span></h3>  // Displays Hike A
<google-map
    [center]="hikeInfo.center | async"
    width="100%">
</google-map>

hike-detail.component.ts

import { Component, OnInit, Input } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import { Location } from '@angular/common';
import { AngularFirestore, AngularFirestoreDocument } from '@angular/fire/firestore';
import { Observable } from 'rxjs';
import { stringify } from 'querystring';
import { map } from 'rxjs/operators';


@Component({
  selector: 'app-hike-detail',
  templateUrl: './hike-detail.component.html',
  styleUrls: ['./hike-detail.component.css']
})
export class HikeDetailComponent implements OnInit {
  hikeId;
  hikeInfo;
  center: google.maps.LatLngLiteral;

  constructor(
    private route: ActivatedRoute,
    private location: Location,
    private router: Router,
    private firestore: AngularFirestore
  ) { }

  ngOnInit(): void {
    this.hikeId = this.route.snapshot.paramMap.get('id');
    this.hikeInfo = this.firestore.collection('hikes').doc(this.hikeId).valueChanges(); 
  }
}

Database

firestore
   -- hikes
      -- key
         -- name: Hike A
         -- center: {
             lat: 28.12,
             lng: 32.71
            }

It currently displays the name and a google map with the generic Google HQ as the center aka the [center] binding does not work.


Solution

  • Inside ngOnInit() subscribe to the observable and get the value:

    this.hikeInfo = this.firestore.collection('hikes').doc(this.hikeId).valueChanges(); 
    this.hikeInfo.subscribe(items => {
      console.log(items);
      this.center = items.center;
    });
    

    Then you can do in the html:

    <google-map
        [center]="center"
        width="100%">
    </google-map>