Angular 2 async pipe on a function
Asked Answered
P

1

6

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];
    }
}
Pegeen answered 7/7, 2017 at 14:17 Comment(2)
Actually you are not passing any URL when calling to your methodHaihaida
You mean in (getSiteImage('test.com') ?Pegeen
D
12

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.

Demarcation answered 7/7, 2017 at 14:52 Comment(3)
Any idea how I can fix this? I like to use de URL as a parameter.Pegeen
@Pegeen change the function so that it stores the observable in a object map using the URL as the key, then the next time it's called use the value from the map.Demarcation
This was really useful, thx. My CPU was at 100% all the time due to thisIntermit

© 2022 - 2024 — McMap. All rights reserved.