Search code examples
angulartypescriptangular13

Component ngOninit model bind issue


Component profile.component.ts is a child component and is trying to bind a dummy model which is shown below.

export class ProfileComponent implements OnInit {
constructor() {
}
objName: any;
ngOnInit() {
    this.getAsyncData().subscribe(j => {          
      this.objName = j.FirstName;
    });
}

getAsyncData() {
    // Fake Slow Async Data
    return of({
      FirstName: 'Luke',
      LastName: 'Skywalker'
    }).pipe(delay(2000));
  }

}

Here is my HTML page below.

<div class="col-12 col-form-label mb-5">
      {{objName | async}}
</div>

Now this this.objName = j.FirstName; gets data but does not bind on HTML page whether I use async or not on HTML page.

Update 1: Browser error without async.
browser error


Solution

  • If you want to use the | async pipe it will only work on an Observable.

    In your case this.objName is not an observable. this.objName is a value from property Firstname on object j which was emitted. You are trying to treat a single value as an observable - that's not how this works. Follow my example for better understanding on this.

    Also try to use camelCase instead of PascalCase when naming properties (e.g FirstName to firstName).

    <div>
      {{ objName$ | async }}
      <br />
      <br />
      <ng-container *ngIf="objName$ | async as obj">
        {{ obj.FirstName }}
      </ng-container>
    </div>
    
    @Component({
      selector: 'async-pipe',
      templateUrl: './async-pipe.component.html',
      styleUrls: ['./async-pipe.component.css'],
    })
    export class AsyncPipeComponent implements OnDestroy, OnInit {
    
      objName$: Observable<any>;
      unsubscribe$: Subject<void> = new Subject<void>();
    
      ngOnDestroy() {
        this.unsubscribe$.next();
        this.unsubscribe$.complete();
      }
    
      ngOnInit() {
        this.objName$ = this.getAsyncData().pipe(takeUntil(this.unsubscribe$));
      }
    
      getAsyncData() {
        // Fake Slow Async Data
        return of({
          FirstName: 'Luke',
          LastName: 'Skywalker',
        }).pipe(delay(2000));
      }
    }
    

    Working example: https://stackblitz.com/edit/async-pipe-8c2brn?file=app%2Fasync-pipe%2Fasync-pipe.component.ts