I have a component that asks my service for an Observable object (that is, the underlying http.get returns one single object).
The object (an observable) is used in conjunction with an async pipe in my template.
Unfortunately, I get an error:
Cannot read property 'lastname' of null
I have been breaking my head on this one. A similar type of code works correctly on a list of objects (in conjunction with *ngFor).
<li>{{(person | async)?.lastname}}</li>
Method in my service:
getPerson(id: string): Observable<Person> {
let url = this.personsUrl + "/" + id;
return this.http.get(url, {headers: new Headers({'Accept':'application/json'})})
.map(r => r.json())
.catch(this.handleError); //error handler
}
In my component:
//... imports omitted
@Component({
moduleId: module.id,
selector: 'app-details-person',
templateUrl: 'details-person.component.html',
styleUrls: ['details-person.component.css'],
})
export class DetailsPersonComponent implements OnInit, OnDestroy
{
person: Observable<Person>;
sub: Subscription;
constructor(private personService: PersonService, private route: ActivatedRoute) {
}
ngOnInit() {
this.sub = this.route.params.subscribe(params => {
let persId = params['id'];
this.person = this.personService.getPerson(persId);
});
}
ngOnDestroy(): void {
this.sub.unsubscribe();
}
}
Apparently the observable is/returns a null object value in the pipe.
I have checked if I am really getting a nonempty Observable from my service and I can confirm that there exists an (underlying) object returned from my service.
Of course, I could subscribe to the observable in my component after having retrieved the Observable from the service, but I would really like to use the async construct.
Btw, another question: Is there already a pattern on how to handle errors that occur in the async pipe? (A downside of using async pipes…. errors are delayed until rendering time of the view.
Best Answer
The first time your view renders,
person
is not defined, since that component property only gets created asynchronously, when the route params subscription fires. You need to initially create an empty observable. Instead oftry
I normally handle errors in a service by