1

I will resolve an ID with a pipe.

I think it isn't the best way to call the service/api every time?

Is it better to store all countries before? How could I return the country name within pipe?

service:

getCountry(id:number) {
   return this._http.get(this.apiUrl + "/country/" + id).map(res => res.json());
}

pipe:

export class ResolvePipe implements PipeTransform {
  constructor(public _formDataService: FormDataService) {}
  transform(value: number, args: any[]): any {
    this._formDataService.getCountry(value).subscribe(
      data => console.log(data[0].name)
    )
  }
}

EDIT:

<tr (click)="showProfile(customer)" *ngFor="let customer of (customers | search:term)">
   <td>...</td><td>{{customer.country_id | resolve | async}}</td>
</tr>
robert
  • 797
  • 3
  • 9
  • 23

1 Answers1

1

First you need to return an Observable. When you call subscribe() a Subscription will be returned. Also you need to actually return something from transform() hence the added return

export class ResolvePipe implements PipeTransform {
  constructor(public _formDataService: FormDataService) {}
  transform(value: number, args: any[]): any {
    // added `return` and changed `subscribe` to `map`
    return this._formDataService.getCountry(value).map(
      data => {
        console.log(data[0].name);
        return data; // with `{ }` explicit `return` is required
      });
    )
  }
}

then you can use the pipe like

<div>{{someId | myIdPipe | async}}</div>

or

<some-comp [idProp]="someId | myIdPipe | async></some-comp>

The async pipe subscribes to the Observable returned from transform and uses the resulting value for the binding.

Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • thank you, works, but it's very slow. What can I do to speed up the performance? – robert Dec 22 '16 at 09:24
  • 1
    Hard to tell from here what is slow. Does the response from the server take such a long time? Is the pipe executed so often that it slows down you application. I can't tell from here. You might maintain a cache within `FormDataService` like discussed in http://stackoverflow.com/questions/36271899/what-is-the-correct-way-to-share-the-result-of-an-angular-2-http-network-call-in – Günter Zöchbauer Dec 22 '16 at 09:43
  • Yes, it's called some 1000 times. A cache should solve this problem. – robert Dec 22 '16 at 12:16
  • 1
    Would be insteresting why it's called that often. Do you use it on so many bindings or is the `value` changing so often? Angular doesn't by itself call a pipe more than once. Perhaps you have set `pure: false` which makes Angular to execute the pipe every time change detection runs - which is quite often. – Günter Zöchbauer Dec 22 '16 at 12:17
  • I have updated my post. I use the filter in a for loop. – robert Dec 22 '16 at 13:23
  • and there are 1000 customers or is `term` changing a lot? In this case I'd strongly suggest a cache. Perhaps you can do something that not a request per id is made but only one request for all ids. This would be a lot more efficient. – Günter Zöchbauer Dec 22 '16 at 13:29
  • and how you would handle the single request? cache the result in pipe? – robert Dec 22 '16 at 13:52
  • I would cache the results in the `FormDataService` because this way every pipe instance can benefit from the cache, otherwise each pipe has its own cache and when `*ngFor` recreates the rows when `term` changes, all pipes are destroyed and recreated and the cache won't have any effect. – Günter Zöchbauer Dec 22 '16 at 13:53