Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Load the data before template render in Angular

I am using Angular 6 and using one way binding.

My code in component is given below.

ngOnInit() {
 this.profile.getUser(1).subscribe((data) => {
  this.userData = this.compiler.constructUserData(data);
 });
}

userData has one object and it has properties. I am trying to bind its data in HTML as shown below

<mat-list-item role="listitem">
          <span matLine>
            <span>First Name: </span>
            <span> {{userData?.first_name}}</span>
          </span>
        </mat-list-item>
        <mat-list-item role="listitem">
          <span matLine>
            <span>Last Name: </span>
            <span> {{userData?.last_name}} </span>
          </span>
        </mat-list-item>
        <mat-list-item role="listitem">
          <span matLine>
            <span>Email: </span>
            <span> {{userData?.email}} </span>
          </span>
        </mat-list-item>
        <mat-list-item role="listitem">
          <span matLine>
            <span>Mobile: </span>
            <span> {{userData.mobile_no}} </span>
          </span>
        </mat-list-item>

here I have used ? after userData variable. But when I write ? with last item as well

e.g. mobile_no it doesn't show any of the data (first_name, last_name, email or mobile_no) on the web. But if I remove ? from last item or any of the item. Data shows up but in console of web page.

Errors shows up as shown below.

Error description

like image 980
Umair Jameel Avatar asked Apr 11 '26 09:04

Umair Jameel


1 Answers

If you're subscribing to the Observable and not placing a ? in the template, make sure to initialize the this.userData with an empty Object initially.

Something like this:

userData = {};

I'd recommend you to rather use the async pipe in the template and not subscribe to the Observable. Assuming that you'll get the userData as an Object containing email, first_name, etc. in your userData Object, this would look something like this:

import { map } from 'rxjs/operators';

...

userData$;

...

ngOnInit() {
  this.userData$ = this.profile.getUser(1).pipe(
    map(data => {
      return this.compiler.constructUserData(data);
    })
  );
}

And in your template:

<div *ngIf="userData$ | async as userData">
  <mat-list-item role="listitem">
    <span matLine>
            <span>First Name: </span>
    <span> {{userData.first_name}}</span>
    </span>
  </mat-list-item>
  <mat-list-item role="listitem">
    <span matLine>
            <span>Last Name: </span>
    <span> {{userData.last_name}} </span>
    </span>
  </mat-list-item>
  <mat-list-item role="listitem">
    <span matLine>
            <span>Email: </span>
    <span> {{userData.email}} </span>
    </span>
  </mat-list-item>
  <mat-list-item role="listitem">
    <span matLine>
            <span>Mobile: </span>
    <span> {{userData.mobile_no}} </span>
    </span>
  </mat-list-item>
</div>

Here's a Working Sample StackBlitz for your ref.

like image 184
SiddAjmera Avatar answered Apr 13 '26 08:04

SiddAjmera