Reputation: 11596
I have attached the plunker of my angular2 code piece. I want to print a field from my JSON but unable to print that as initially my Object is null and it is being populated via a Promise.
This is my component file
import {Component, NgModule, OnInit} from '@angular/core'
import {BrowserModule} from '@angular/platform-browser'
class MyData {
xyz : MySubData;
}
class MySubData {
name : string;
}
@Component({
selector: 'my-app',
template: `
<div>
<h2>Hello {{name}}</h2>
{{abc.xyz.name}}
</div>
`,
})
export class App implements OnInit {
abc : MyData = null;
constructor() {
this.name = 'Angular2'
}
ngOnInit() {
setTimeout(() => {
this.abc = new MyData();
this.abc.xyz = new MySubData();
this.abc.xyz.name = "Binita";
}, 2000);
}
}
@NgModule({
imports: [ BrowserModule ],
declarations: [ App ],
bootstrap: [ App ]
})
export class AppModule {}
When I am removing the line {{abc.xyz.name}}
from my template it is running fine.
I have use set time out in my code because I am getting my data from Promise (i.e asynchronous call).
I can understand initially as abc
is null
, my code is unable to find abc.xyz.name. But I don't want to put any if condition to check. Because I have several property inside a JSON and it is not possible for each property to write if condition.
Earlier in angularjs 1 if abc is null then it would automatically replace it with blank string. I want to do the same thing in angular2. Please suggest.
Below is the plunker
https://plnkr.co/edit/u1NqNF0penz7OS55QmoU?p=preview
Upvotes: 52
Views: 131173
Reputation: 1243
the best way in angular is utilizing resolver
guard. this guard help you get data before rendering view, while now you rendering data first then you get data, that's why you face with such an error. I prepare a video on YouTube, you can get idea there. follow this video
Upvotes: 0
Reputation: 750
Safe navigation operator or Existential Operator or Null Propagation Operator is supported in Angular Template. Suppose you have Component class
myObj:any = {
doSomething: function () { console.log('doing something'); return 'doing something'; },
};
myArray:any;
constructor() { }
ngOnInit() {
this.myArray = [this.myObj];
}
You can use it in template html file as following:
<div>test-1: {{ myObj?.doSomething()}}</div>
<div>test-2: {{ myArray[0].doSomething()}}</div>
<div>test-3: {{ myArray[2]?.doSomething()}}</div>
Upvotes: 0
Reputation: 50643
That's because abc
is undefined at the moment of the template rendering. You can use safe navigation operator (?
) to "protect" template until HTTP call is completed:
{{abc?.xyz?.name}}
You can read more about safe navigation operator here.
Update:
Safe navigation operator can't be used in arrays, you will have to take advantage of NgIf
directive to overcome this problem:
<div *ngIf="arr && arr.length > 0">
{{arr[0].name}}
</div>
Read more about NgIf
directive here.
Upvotes: 126