4

How can I use async pipe when calling service method from template?

This code works:

    <div *ngFor="let filename of filenames | async">
        <div>{{filename}}</div>
    </div>

    //code behind
    constructor(public importService: ImportService)
    {
        this.filenames = this.importService.list();  //returns Observable - from http.get
    }

but I would like to avoid assigning value to filenames (this.filenames = this.importService.list();) and call method directly from html:

<div *ngFor="let filename of importService.list() | async">
    <div>{{filename}}</div>
</div>

But this execute unlimited request to server. (As I would call importService.list().subscribe() in endless loop).

I also tried this (source for ideas):

<div *ngFor="let filename of (o = (importService.list() | async))">
    <div>{{filename}}</div>
</div>


<div *ngFor="let filename of (o = (importService.list()) | async)">
    <div>{{filename}}</div>
</div>


<div *ngIf="importService.list(); let o">
    <div *ngFor="let filename of o | async">
        <div>{{filename}}</div>
    </div>
</div>

But none works.
This Github issue described exactly the same thing. I hope something has changed in year and half and this could be done.

Edited:
Desired effect can be achieved with several approaches.
First:

<div *ngFor="let filename of filenames">
    <div>{{filename}}</div>
</div>

public filenames: string[];

constructor(public importService: ImportService)
{
    this.importService.list().subscribe(res => this.filenames = res);
}

Second, more effective (shorter):

<div *ngFor="let filename of filenames | async">
    <div>{{filename}}</div>
</div>

public filenames: Observable<string[]>;

constructor(public importService: ImportService)
{
    this.filenames = this.importService.list();
}

and third even shorter (what I want to achieve):

constructor(public importService: ImportService) { }

<div *ngFor="let filename of importService.list() | async">
    <div>{{filename}}</div>
</div>
Makla
  • 9,899
  • 16
  • 72
  • 142
  • 3
    what is the problem with assigning to the component ? This is the recommended way of doing... If you **really** want to do this (I still don't get why ?!), you just have to return the same observable from your service everytime. – n00dl3 Oct 17 '17 at 10:19
  • 1
    You could avoid writing at least 2 rows. Declaring observable variable and assigning. I really don't see a point why should I assign variable and then call async method on that variable. Would be a lot easier to just call | async on service method. – Makla Oct 17 '17 at 10:22
  • 1
    this execute unlimited request to server because each time Angular need to update the view so it must call `importService.list()` when an asynchronous action happen. just go with first approach as @n00dl3 said. – El houcine bougarfaoui Oct 17 '17 at 10:26
  • Thanks n00dl3 and Bougarfaoui El houcine, I understand why endless call to server. I edited my original post why I am looking for that, but apparently I can not go shorter then my second approach (n00dl3 answer). – Makla Oct 17 '17 at 10:34
  • 2
    There are scenarios where it can be done (note that I said "can", not "should"), but saving two lines of code is not part of these as it would require lot more work on the service side. – n00dl3 Oct 17 '17 at 10:39

0 Answers0