ufk
ufk

Reputation: 32104

using Observable in Angular 10 properly, value never changes

I'm trying to understand how to use Observables In Angular 10 for loading indicators and for data change in some graphql functions that I have.. and I'm missing basic implementation that I don't understand.

lets take a boolean value for loading indicator as an example.

so in my component class I have this:

private readonly loading = new Subject<boolean>();
get loading$(): Observable<boolean> {
 return this.loading;
}

in the template html file I have this:

{{(this.loading$ | async) ? 'true' : 'false'}}

the problem is that it's alway prints false

in ngOnInit() function I added this.loading.next(true); but the html template still prints false.

what am I missing ?

thanks

Upvotes: 0

Views: 315

Answers (2)

mbojko
mbojko

Reputation: 14679

It's not about observables, it's about Angular component life cycle.

in ngOnInit() function I added this.loading.next(true); but the html template still prints false.

That's too early - the observable emits once, before the template is rendered, effectively before anyone's listening to the stream. But the same code will work if put in ngAfterViewInit instead of ngOnInit.

https://stackblitz.com/edit/angular-xefd3z?file=src%2Fapp%2Fapp.component.ts

Upvotes: 1

user3791775
user3791775

Reputation: 471

Ok, I would not use a setter. I would just do something like:

loading$ = new BehaviorSubject(false);

ngOnInit() {
   this.loading$.next(true)
   // setTimeout should be cleared but this is just to show toggling works
   setTimeout(() => {this.loading$.next(false)}, 2000)
}

Explanation: A behaviorSubject has an initial value (false). The behaviorSubject is an Observable so you can print it with the async pipe in your template. In ngOnInit the behaviorSubject gets a next of true, and after the timeout a next of false, just to showcase stream value changes

Upvotes: 1

Related Questions