Unable to assign data returned from http Get to typescript object with same structure

The variable this.personId is assigned asynchronously. So by the time getPerson() is called, it’s still undefined.

Instead of nested subscriptions, you could use RxJS higher order mapping operator like switchMap to map from one observable to another.

ngOnInit() {
  this.route.params.pipe(
    switchMap(params => this.service.getPerson(params['person-id']))
  ).subscribe((data: Person) => {
    console.log(data);
    this.person = data;
  })
}

Option 2: async pipe

If you aren’t using this.person in the controller, you could skip the subscription there and use async pipe in the template

Controller

import { Observable } from 'rxjs';

export class DisplayPersonComponent implements OnInit {
  person$: Observable<Person>; // <-- type `Observable`
  
  constructor(private route: ActivatedRoute, private service : PersonService) { }

  ngOnInit() {
    this.person$ = this.route.params.pipe(
      switchMap(params => this.service.getPerson(params['person-id']))
    );
  }
}

Template

<ng-container *ngIf="(person$ | async) as person">
  {{ person }}
  <some-comp [person]="person">...</some-comp>
</ng-container>

Update: Cannot read property

The error is thrown because the person variable is undefined until it’s assigned a value inside the subscription. The second option using async should mitigate the issue. In any case, you could use safe navigation operator ?. to check if a variable is defined before trying to access it’s properties.

<div>
  {{ person?.personId }}
  {{ person?.someProp }}
  {{ person?.someOtherProp }}
</div>

You could learn more about asynchronous data here.

CLICK HERE to find out more related problems solutions.

Leave a Comment

Your email address will not be published.

Scroll to Top