Hello everybody:
I’m trying to set a value in ionic 2, taking the value from a mock service, but when I try to get the value of the object outside the then
, tells me that it’s undefined
The code involved is:
saveCar(data) {
this.carInfo = data;
}
ngAfterViewInit() {
this.carService.getInfo(this.picture).then((data) => {
this.saveCar(data);
});
console.log(this.carInfo);
}
I’ve tried to set the value without calling a function, and the result it’s the same.
Do you have any ideas?
Thank you for your help.
Regards.
Seems fair to me that it tells you it’s undefined
If you’re sure that data is indeed returned, move the logging somewhere else. Log this.carInfo
after you’ve saved it, then it’ll show your data returned from the Promise.
// first we retrieve the data
ngAfterViewInit() {
this.carService.getInfo(this.picture).then((data) => {
// here we're receiving data from the promise
this.saveCar(data);
});
}
saveCar(data) { // Now we're getting here from within the then
this.carInfo = data; // data get's assigned to this.carInfo instance
console.log(this.carInfo); // log the carInfo
}
Yes, I didn’t get corretly the concept of async 
Very thank you!
Anyway, after this problem is solved, The information that I want to show in the html does not appear.
<ion-row *ngIf="carInfo != null">
<ion-item>
<ion-label fixed>Car Plate</ion-label>
<ion-input type="text" [(ngModel)]="carInfo.plate" placeholder="plate"></ion-input>
</ion-item>
</ion-row>
Why is not updated?
Thanks
Works for me, so the bug must be somewhere outside what you’ve posted here:
Observable.of({plate: 'abc123'}).delay(2000).subscribe(ci => this.carInfo = ci);
Your exact template code, and after 2 seconds I see “Car Plate abc123”.
It wasn’t a bug at all, the view didn’t update after getting the information.
My solution was to use ngZone when updating the value:
saveCar(data) {
this._ngZone.runOutsideAngular(() => {
this.carInfo = data;
this._ngZone.run(() => { console.log("Updated value: " + this.carInfo) });
});
}
Thank you for your help!
Sorry, but that’s not the proper solution. If you have to manually be messing with zones, you are not feeding the data properly. This is going to continue being a problem until you resolve the ultimate issue, and band-aiding things with zone.run()
and setTimeout()
is not the way to go.
Why am I not getting the data properly? Where do I have to put your code line? The code related to the service is the following (now I’m dealing only with mock data):
getInfo(picture): Promise<CarInfo> {
return Promise.resolve(this.car);
}
Thank you in advance.
Please post the entire CarService
.
import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
import 'rxjs/add/operator/map';
export class CarInfo {
plate: string;
brand: string;
model: string;
}
@Injectable()
export class CarInfoDetection {
car: CarInfo;
constructor(public http: Http) {
console.log('Hello CarInfoDetection Provider');
this.car = { 'plate': "12312312", 'brand': 'BMW', 'model': "X1" }
}
getInfo(picture): Promise<CarInfo> {
return Promise.resolve(this.car);
}
}
I add that provider verbatim to my vanilla tabs scratch project, add it to the providers
of my app module, change my home page to look like this:
constructor(private _cars: CarInfoDetection) {}
ngAfterViewInit() {
this._cars.getInfo(null).then(ci => this.carInfo = ci);
}
No messing with zones, “Car Plate 12312312” shows up as expected.
mmmmm… Now it works. The only change I’ve made is that now I don’t use ngModel , I use only read-only bindings
<ion-card-content>
<ion-item>
<h2>Car Plate:</h2>
<p>{{carInfo.plate}}</p>
</ion-item>
<ion-item>
<h2>Brand:</h2>
<p>{{carInfo.brand}}</p>
</ion-item>
<ion-item>
<h2>Model:</h2>
<p>{{carInfo.model}}</p>
</ion-item>
</ion-card-content>
The code related with the service and with the component was the same. Also I’ve changed the code only to use ngModel and the result works. Seems weird.
Anyway, thank you for your help