Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 2 async pipe on a function

I'm trying to get a base64 from an api. The following code works fine.

private test = null;

ngOnInit() {
   this.loadCustomers();
   this.test = this.getSiteImage();
}

getSiteImage() {
   return this.CustomerService.getCustomerSiteImage('test.com').share();
}

<img class="avatar avatar-xl" src="{{ (test | async)?.image }}" alt="">

But I would rather like to use a function. When I change the code to the following:

getSiteImage(url) {
    return this.CustomerService.getCustomerSiteImage(url).share();
}


<img class="avatar avatar-xl" src="{{ (getSiteImage('test.com') | async)?.image }}" alt="">

I like to know why this isn't working and how I can properly achieve this.

---------EDIT:

To help people with the same problem in the future. Just as @thinkinkingmedia suggested. I put the observables in an object with the url as key.

I changed the getSiteImage(url) methode to:

getSiteImage(url) {
    if (url in this.imageObservables) {
      return this.imageObservables[url];
    } else {
      this.imageObservables[url] = this.CustomerService.getCustomerSiteImage(url).share();
      return this.imageObservables[url];
    }
}
like image 681
KBeckers Avatar asked Jul 07 '17 14:07

KBeckers


People also ask

Can I use async pipe in component?

The async pipe in angular will subscribe 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.

Should I use async pipe in angular?

Any Angular developer worth his salt has gotta admit that the AsyncPipe is quite terrific. If you subscribe() to an Observable or Promise you'll need to unsubscribe() at the end of your component's life cycle to avoid memory leaks. Change detection works splendidly with the async pipe.

What does AsyncPipe do in angular?

Angular's async pipe is a tool to resolve the value of a subscribable in the template. A subscribable can be an Observable , an EventEmitter , or a Promise . The pipe listens for promises to resolve and observables and event emitters to emit values.

Should I use async pipe?

Async pipe it`s better in most of the cases because it is in charge to handle the subscription and unsuscription and notify which reactive part of the code is going to be rendered. Also you prevent possible memory leaks.


1 Answers

The reason it's not working is because async is getting a new observable every time Angular checks the expression for a change.

In your first example:

{{ (test | async)?.image }}

Angular checks the expression which passes the value of the property test to async. Asycn then subscribes to the observable and waits for a value. In the next cycle of checking Angular passes the same observable to Async, and Async makes no changes as it's already subscribed.

In your second example:

{{ (getSiteImage('test.com') | async)?.image }}

Angular checks the expression which calls a function that creates an observable. This is passed to async which waits for a response. In the next cycle this gets repeated. Each change detection creates a new observable and the async never gets a chance to yield a result. For every new observable passed to async it unsubscribes to the previous.

like image 68
Reactgular Avatar answered Oct 01 '22 01:10

Reactgular