AsyncPipe not working when interval is returned by a function

angular async pipe not working
angular async observable
angular async pipe as
async pipe vs subscribe
angular async pipe as variable
angular async pipe ngfor
invalidpipeargument: '' for pipe 'asyncpipe'
angular async pipe object

So I'm messing up a little bit with Observers and I can't understand why methods that returns interval can't display the observers data using the AsyncPipe

component.ts

import {interval} from "rxjs";

export class CalendarComponent implements OnInit {
  interval: any;

  ngOnInit() {
    this.interval = interval(1000);
  }

  myInterval() {
    return interval(1000);
  }
}

component.html

INTERVAL : {{interval | async}} //Displays the interval incrementing each second
FUNCTION : {{myInterval() | async}} //Not working

Every time angular refreshes page by change detector, it checks values/references of bound objects and if there is new one, algorithm puts new values into view. myInterval() method gives reference for new object on every change detection tick. Probable angular has trouble in loading your view. this.interval is all the time same object, so its loaded only once to session cache.

Similar situation is when you would put a PromiseLike type into view like this:

getPromisValue() {
    return Promise.resolve("anything");
}

<p>{{getPromiseValue() | async}}</p>

its all the time the same value but new promise reference so view will have a trouble to load it.

To track such situations, good practise is to inject ngZone in app.component.ts and log onStable observable.

constructor(
    private zone: NgZone
  ) {
    this.zone.onStable.asObservable().subscribe(() => console.log("onStable"));
  }

As angular doc says https://angular.io/api/core/NgZone#onStable it:

Notifies when the last onMicrotaskEmpty has run and there are no more microtasks, which implies we are about to relinquish VM turn. This event gets called just once.

So if you will do something wrong, you will see in console that log occurs too many times. Disable this on production.

Async Pipe: How to use it properly in Angular, The angular async pipe allows the subscription to observables inside of the angular template syntax. let value = 0 const interval = setInterval(() => { observer.next(value) a REST-Endpoint, as the angular HttpClient returns an observable. Also, the methods showed above do not work with the onPush� AsyncPipe is a convenience function which makes rendering data from observables and promises much easier. For promises it automatically adds a then callback and renders the response. For Observables it automatically subscribes to the observable, renders the output and then also unsubscribes when t…

If you try

myInterval() {
    console.log('here');
    return interval(1000);
}

you will notice that this function is getting called each 1s. That will give you new object every time (return interval(1000)), hence using just reference is working.

Why this is happening ? (With inputs from @C_Ogoo)

As you are returning interval of 1s, after that the change detection cycle kicks in as you have used interpolation here. Due to this the function gets called again and resulting in new interval every time.

Three things you didn't know about the AsyncPipe, Turns out the AsyncPipe is full of little wonders that may not be That's the typical scenario when working with http and it's basically the only scenario when working with Promises. toString(16).slice(-6); Observable.interval(1000) .scan(( acc, 0, {num, color}); if (acc.length > 5) { acc.pop() } return acc; }, []). Promise: It is a proxy for a value not necessarily known when the promise is created. It does not return immediately a final value. It returns a promise to supply the value at some point in the future. toPromise(): This is a RxJS operator that converts Observable into Promise. setInterval(): Sets a time interval after which it re-executes.

It is invoked and works exactly as you would expect.

the problem is, since its a function, it will constantly get evaluated, and return a new interval reference on each change detection cycle.

change your function's:return value to

return interval(1).pipe(tap(n => console.log(n)))

it will make things much clearer

Async Pipe • Angular, AsyncPipe is a convenience function which makes rendering data from Your browser does Duration: 11:04 Posted: 6 Oct 2016 interval is not an filter, it's function that returns and Observable. Maybe you want delay instead? – martin Mar 25 '18 at 10:02 Yes but when I want to filter persons which age is > 26 it says that it can’t read property age – Jan Testowy Mar 25 '18 at 10:04

Subscribing to Multiple Observables in Angular Components , Below are some functions that return the Observables that we will use in our components. import { Observable, of, interval } from 'rxjs'; import { delay } from When first working with Angular and RxJS subscribing directly to the The Async pipe will allow us to let angular know what properties on our� 1 AsyncPipe not working when interval is returned by a function Jan 3. 0 Angular return httpclient response that object with 0 Observable result is not

3 Common Angular Rxjs Pitfalls, If you have used RxJs before, then try to guess the problem in each scenario, Creating an observable is somewhat similar to declaring a function, the are returned by the HTTP service, either directly or via the async pipe. interval function generates incrementing numbers with some delay. switchMap callback checks if the emitted number is odd, if yes — it makes request wrapped in Observable and subscriber gets a

AsyncPipe, The async pipe subscribes to an Observable or Promise and returns the latest resolve: Function|null = null; constructor() { this.reset(); } reset() { this.arrived� The async pipe subscribes to an Observable or Promise and returns the latest value it has emitted. When a new value is emitted, the async pipe marks the component to be checked for changes. When the component gets destroyed, the async pipe unsubscribes automatically to avoid potential memory leaks. Usage noteslink Exampleslink

Comments
  • It's because you didn't call the myInterval function. Unless it's a getter or a variable, you need the necessary parenthesis after the function name to call the function.
  • Woops, forgot to add them in the question.
  • This is technically incorrect. Angular does not track the return values from functions. The problem here is that Angular has no clue if a function has any side effects. So when the compiler converts a template expression to JavaScript and it sees a function it marks the expression as impure. So it will evaluate the expression every render pass. Pipes are the only functions you can use in a template that can be marked as pure. This is why we have pipes.
  • I think this is also to do with the change detection cycle. So everytime change detection is ran, the function myInterval will be called and thus returning a new interval
  • Exactly. I was just going through the documentation. I ll update the answer.
  • @C_Ogoo myInterval() | async the async pipe calls markForCheck() when a value is emitted. So the pipe itself is triggering the change detection on the view, and then a new observable is created and async starts over.