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>
5
  • 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. Commented Oct 17, 2017 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. Commented Oct 17, 2017 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. Commented Oct 17, 2017 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). Commented Oct 17, 2017 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. Commented Oct 17, 2017 at 10:39

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.