I have a page where I get an object from Storage inside of constructor. But when I want to get a property of this object in html an exception is thrown Cannot read property "..." of undefined
.
I set data in one page and load another page.
First page:
let detailsResponse = this.agentService.getAgentDetails(data.data.session.ssid, data.data.session.device);
detailsResponse.then(agent => {
this.storage.set('agent', JSON.stringify(agent.data)).then(() => {
this.navCtrl.push(TabsPage);
});
});
Other page:
import {Storage} from '@ionic/storage';
....
constructor(public navCtrl: NavController,
public navParams: NavParams,
public toastCtrl: ToastController,
public alertCtrl: AlertController,
public storage: Storage) {
this.storage.get('agent').then((agent) => {
this.sessionAgent = JSON.parse(agent);
});
}
I am sure that the sessionAgent object is not null, but when I want to get a property I get the exception instead:
<ion-fab top right edge>
<button color="default" ion-fab>{{sessionAgent.status.value}}</button>
<ion-fab-list>
<button color="secondary" *ngIf="sessionAgent.status.value == 'Offline'" (click)="doOnline()" ion-fab>On</button>
<button color="danger" *ngIf="sessionAgent.status.value == 'Online'" (click)="doOffline()" ion-fab>Off</button>
</ion-fab-list>
</ion-fab>
But when I put a *ngIf
check before accessing the object in html, it solves the problem.
<ion-fab top right edge *ngIf="sessionAgent != null">
<button color="default" ion-fab>{{sessionAgent.status.value}}</button>
<ion-fab-list>
<button color="secondary" *ngIf="sessionAgent.status.value == 'Offline'" (click)="doOnline()" ion-fab>On</button>
<button color="danger" *ngIf="sessionAgent.status.value == 'Online'" (click)="doOffline()" ion-fab>Off</button>
</ion-fab-list>
</ion-fab>
I cannot understand the reason of this behavior. Where should I populate my objects (rest service calls, locale storage) before loading pages?
Fetching data from storage is asynchronous and while you are fetching the object, Angular will want to initialize the page. But since the object is not there yet it will throw an exception.
You should make use of NavParams here. Because that will make you get the object syncronously.
First page:
this.navParams.push(TabsPage, { data: agent.data });
Other page:
constructor(private navParams: NavParams){
this.sessionAgent = this.navParams.get('data');
}
To protect from async values not being fetched yet you could use the
Safe Navigation operator:
<button color="default" ion-fab>{{sessionAgent?.status?.value}}</button>