Angular Async Pipe and the 'delay' operator

Vern Halen

I'm attempting to simulate latency with my observables.

I want to unwrap the observable using the async pipe, and add a bit of delay with the 'delay' operator.

app.component.html

<ul *ngIf="items$ | async as items">
   <li *ngFor=let item of items">{{ item }}<li>
</ul>

app.component.ts

get items$(): Observable<string[]> {
    return of(['alpha', 'bravo', 'charlie', 'delta']).pipe(delay(3000));
}

However, doing it in this fashion returns no HTML markup. Removing the pipe(delay(3000)) allows it to work.

If I implement 'OnInit' and just check on the observable:

ngOnInit(): void {
   this.items$.subscribe(val => console.log(val));
}

In three seconds the console will output:

(4) ["alpha", "bravo", "charlie", "delta"]

So the observable is behaving like I want it to, but it seems I am not utilizing the async pipe correctly.

What am I missing about about how the async pipe works? How do I simulate this delay in a simple fashion?

Igor

You need a single Observable instance. Your code currently will create and return a new Observable every time your property items$ is accessed. Create it one time instead. You could still use a getter if you wanted to as long as it is the same Observable instance being returned with each call.

items$: Observable<string[]>;
constructor() {
  this.items$ =  of(['alpha', 'bravo', 'charlie', 'delta']).pipe(delay(3000));
}

or

private _items$?: Observable<string[]>;
get items$(): Observable<string[]> {
  if (!this._items$) {
    this._items$ =  of(['alpha', 'bravo', 'charlie', 'delta']).pipe(delay(3000));
  }
  return this._items$;
}

If you want to see how/why your original code is failing you could add a counter in the getter and then you can see the number of Observable being created and returned.

  numberOfCalls = 0;
  get items$(): Observable<string[]> {
    this.numberOfCalls++;
    return of(['alpha', 'bravo', 'charlie', 'delta']).pipe(delay(3000));
  }

and then add this to your template

calls to items$ which create and return a new observable = {{numberOfCalls}}

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

Angular 2 + rxjs: async pipe with .share() operator

Angular Rxjs: emit all merged observables with delay continuously with async pipe

Rxjs share() operator with Behavior subject and async pipe - Angular

Safe navigation operator on an async observable and pipe in Angular 2

Angular async pipe with mergeMap

Angular Async Pipe on a getter

Angular replace pipe operator is not working

rxjs take operator - to limit results with async pipe

Angular - RxJS : afterViewInit and Async pipe

How to async pipe an observable in Angular

spyOn not working with async pipe in Angular

Angular async pipe and object property

angular async pipe not updating the view

Angular async pipe hangs on a promise

Angular 2 async pipe on a function

Angular async pipe not working with fromEvent

Angular Observables Unsubscribe async pipe

Angular async pipe with offset pagination

Pipe operator not working when combining with async pipe in template for valuechanges observable

async pipe as not working within an input in Angular

angular: bind method + param with async pipe in template

Angular extend component with BehaviorSubject async pipe not working

Angular template binding with Observable async pipe issue

Angular getting cartSize with async pipe not working

Angular *ngIf variable with async pipe multiple conditions

Correct syntax for Angular async pipe with as keyword

Using Angular Async Pipe to Subscribe to Observable

Angular 2 using ngFor with the async pipe and index

How to handle boolean observables with the async pipe in Angular