Failed to navigate: Cannot read property 'lng' of undefined.ERROR Error: Uncaught (in promise): TypeError: Cannot read property 'lng' of undefined


#1

I would like to show the location map according to the location information from service.I get location information correctly.But I get an undefined error in html.Where do i make mistakes

map.html

 <ion-header>

 <ion-navbar>
 <ion-title>Map</ion-title>
 </ion-navbar>

 </ion-header>


   <ion-content> 
      <sebm-google-map id="map"  [latitude]="map.lat" [longitude]="map.lng" 
       [zoom]="map.zoom">
      </sebm-google-map>
 </ion-content>

map.ts

import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams } from 'ionic-angular';   
import {AgmCoreModule,SebmGoogleMap} from 'angular2-google-maps/core';
import {DataApi} from '../../app/shared/shared';

@IonicPage()
@Component({
selector: 'page-map',
templateUrl: 'map.html',


 })
 export class MapPage {

   map : any;
   constructor(public navCtrl: NavController, public navParams: 
   NavParams,private dataApi : DataApi) {
   }

   ionViewDidLoad() {
    console.log('ionViewDidLoad MapPage');
    let games = this.navParams.data;
    let tourneyData = this.dataApi.getCurrentTourney();
    let location = tourneyData.locations[games.locationId];

    this.map = {
    lat :  location.latitude,
    lng : location.longitude,
    zoom : 60,
    markerLabel : games.location
    };
   console.log(this.map.lat);
   console.log(this.map.lng);
   console.log(this.map.markerLabel);
 }

}

data-api.service.ts

import {Injectable} from '@angular/core';
 import {Http,Response} from '@angular/http';

 import 'rxjs';
 import {Observable} from 'rxjs/Observable';
 @Injectable()
 export class DataApi {

 private url = 'https://ionic2-9dc0a.firebaseio.com';   // https://ionic2-9dc0a.firebaseio.com
 currentTourney : any = {};
 private tourneyData = {};
 constructor(private http:Http){
}
  getTournaments(){
    return new Promise(resolve =>{
      this.http.get(`${this.url}/tournaments.json`) 
      .subscribe(res => resolve(res.json()))
    });
  }


 /*   getAdress(): Promise<Team> {
     return this.http.get(this.url)
    .map(rsp => rsp.json())
    .toPromise();
}
 */       

  getTournamentData(tourneyId,forceRefresh : boolean = false) : Observable<any>{

    if(!forceRefresh && this.tourneyData[tourneyId]){
      this.currentTourney = this.tourneyData[tourneyId];
      console.log("no need to make Http call");
      return Observable.of(this.currentTourney);

    }
    console.log("about to make Http call")
    return this.http.get(`${this.url}/tournaments-data/${tourneyId}.json`)
    .map((response:Response) =>{
        this.currentTourney = response.json();
        return this.currentTourney;
    });
  }


  getCurrentTourney(){
    return this.currentTourney;
  }

  refreshCurrentTourney(){
    return this.getTournamentData(this.currentTourney.tournament.id,true);
  }

}

#2

My guess would be that at the moment your map is created, map.lat and map.lng are still undefined. Make sure that the map is created only once you have a latitude and longitude to set. Because it probably fails if you’re trying to set it when map.lat and map.lng are not set yet.


#3

your service is sending requests --> they are async and http is returning observables.

you can not simply do this:

let variable = myService.asyncStuff()

you need to wait until the request has finished:

this.dataApi.getCurrentTourney(data).subscribe(() => {
  // data is defined
});

Read about observables … please


#4

A solution came from Stackoverflow,and my problem is solved.Thank you for your help.

   <ion-content> 
      <sebm-google-map id="map"  [latitude]="map.lat" [longitude]="map.lng" 
       [zoom]="map.zoom">
      </sebm-google-map>
 </ion-content>
 <ion-content> 
      <sebm-google-map id="map"  [latitude]="map?.lat" [longitude]="map?.lng" 
       [zoom]="map?.zoom">
      </sebm-google-map>
 </ion-content>

#5

But you should listen to @bengtler advise. Then you wouldn’t need the elvis operator. Do you even know why it fixed your issue?


#6

No, I do not know. :smiley: Just solved my problem.I will consider your suggestion carefully.thank you


#7

Please please do some reading before just pasting something from stackOverflow and celebrate if it works, because you become a better programmer when you truly understand what you’re doing :slight_smile: And better programmers make better apps.


#8

Why is “?” working, I had the same problem, and ? did the work. Also I checked for @bengtler solution but doesn’t fixed the problem without elvis operator


#9

I think the Elvis operator is an antipattern.

Part of the contract between template and controller should be that the controller is responsible for having all properties accessed by the template be in a sane state at all times. That is not the template’s job.