kevingoos
kevingoos

Reputation: 4313

Angular2 apply filter inside service

I am building an app with Angular 2. I have a service, and I am trying to filter the data before getting it from the service. I want a function where I can just ask one project element instead of the whole array.

This is the code I tried, but this approach doesn't work:

getProject(id: number): Observable<Project> {
        return this.http.get(this.url).map(this.extractData).filter(project => (<Project>project).id == id).catch(this.handleError2);

    // return this.getProjects().filter(project => project.id === id);
    //return this.http.get(this.url).toPromise().then(x => x.json().data.filter(project => project.id === id)[0]).catch(this.handleError);
}

private extractData(res: Response) {
    let body = res.json();
    return body.data || { };
}

private handleError2 (error: any) {
    // In a real world app, we might use a remote logging infrastructure
    // We'd also dig deeper into the error to get a better message
    let errMsg = (error.message) ? error.message :
    error.status ? `${error.status} - ${error.statusText}` : 'Server error';
    console.error(errMsg); // log to console instead
    return Observable.throw(errMsg);
}

Upvotes: 2

Views: 3602

Answers (3)

neaumusic
neaumusic

Reputation: 10474

To me, it looks like you're mixing sync and async code, and return doesn't work like that. You can return an object (function) who's properties change later (aka a Promise)

I doubt that http.get() provides an array for you to map


.toPromise() seems like a hack, but you should return a Promise chain


return this.http.get(this.url).then(data => data.map(this.extractData).filter(project => (<Project>project).id == id).catch(this.handleError2));

If this.http.get() does not return a Promise, but takes a callback, you can construct one:

return new Promise (resolve => this.http.get(this.url, resolve)).then(data => data.map(this.extractData).filter(project => (<Project>project).id == id).catch(this.handleError2));

And whatever is calling getProject() can chain with getProject().then()

Upvotes: 1

Alexis Le Gal
Alexis Le Gal

Reputation: 337

If this part of code works :

getProjects() {
        return this.http.get(this.url).map(this.extractData).catch(this.handleError2);
     }

Then you can call a single project with :

getProject(id: number) {
        return this.getProjects()
            .then(projects => projects.filter(project => (<Project>project).id == id);
    }

Upvotes: 0

ranakrunal9
ranakrunal9

Reputation: 13558

Its better to filter data in component from where you have called the service.

So your service is like :

getProject(id: number): Observable<Project> {
  return this.http.get(this.url).map(this.extractData);
}
private extractData(res: Response) {
  let body = res.json();
  return body.data || []; // return value must be array to use filter function in component
}

in your component you can do as below :

service.getProject(projectId).subscribe((res) => {
  let filtered = [];
  if(res.length){
    filtered = res.filter((item) => {
      return item.id === projectId;
    });
  }
});

Upvotes: 1

Related Questions