admin管理员组

文章数量:1391974

I have a method on my service that gets all Templates, and returns an Observable array of Template objects. I am attempting to add a new method to my service that gets the array of Templates, but filters it to get a specific template by name, in an array.

Is there a way to get this to just return a single Template Observable, rather than an Observable Template array with one item? I am still so new to rxjs syntax that I don't understand how to use things like reduce.

Here's my working method to get all templates.

 getAllTemplates(): Observable<Template[]>{
    const uri = this.baseService.rootTemplatesUri;
    return this.http.get<Template[]>(uri)
      .pipe(
        catchError((error: HttpErrorResponse) => { return throwError(error); })
      );
  }

Here's my attempt that is filtering by name, which returns an array with one element if there's a matching name:

getTemplateByName(name:string):Observable<Template[]>{
    const uri = this.baseService.rootTemplatesUri;
    return this.http.get<Template[]>(uri)
      .pipe(
        map(templates => {
          return templates.filter(template => {
            return template.Name === name;
          })
        }),
       catchError((error: HttpErrorResponse) => { return throwError(error); })
     );

  }

Is there a way to get a single Observable returned by filtering this?

I have a method on my service that gets all Templates, and returns an Observable array of Template objects. I am attempting to add a new method to my service that gets the array of Templates, but filters it to get a specific template by name, in an array.

Is there a way to get this to just return a single Template Observable, rather than an Observable Template array with one item? I am still so new to rxjs syntax that I don't understand how to use things like reduce.

Here's my working method to get all templates.

 getAllTemplates(): Observable<Template[]>{
    const uri = this.baseService.rootTemplatesUri;
    return this.http.get<Template[]>(uri)
      .pipe(
        catchError((error: HttpErrorResponse) => { return throwError(error); })
      );
  }

Here's my attempt that is filtering by name, which returns an array with one element if there's a matching name:

getTemplateByName(name:string):Observable<Template[]>{
    const uri = this.baseService.rootTemplatesUri;
    return this.http.get<Template[]>(uri)
      .pipe(
        map(templates => {
          return templates.filter(template => {
            return template.Name === name;
          })
        }),
       catchError((error: HttpErrorResponse) => { return throwError(error); })
     );

  }

Is there a way to get a single Observable returned by filtering this?

Share Improve this question edited May 24, 2019 at 18:09 Jennifer S asked May 24, 2019 at 17:37 Jennifer SJennifer S 1,4492 gold badges26 silver badges44 bronze badges 4
  • one option could be using reduce operator in rxjs, to receive an array and return single object – Reza Commented May 24, 2019 at 17:41
  • Where would I put the reduce? – Jennifer S Commented May 24, 2019 at 17:53
  • 1 Use find instead of filter. developer.mozilla/en-US/docs/Web/JavaScript/Reference/… – Gosha_Fighten Commented May 24, 2019 at 18:15
  • @JenniferS in pipe – Reza Commented May 24, 2019 at 18:27
Add a ment  | 

1 Answer 1

Reset to default 6

When the map RxJS operator is used, the returned observable has the type returned inside the map operator. The JavaScript filter method returns a new array as stated in its documentation. That's why your getTemplateByName method returns an observable of Template[] elements.

If you need to make the getTemplateByName method return an observable of Template elements, you need to return a single Template element inside your map operator. The JavaScript find method does this as stated in Array​.prototype​.find(). Just use it to achieve the desired behavior.

getTemplateByName(name:string):Observable<Template>{
    const uri = this.baseService.rootTemplatesUri;
    return this.http.get<Template[]>(uri)
      .pipe(
        map(templates => {
          return templates.find(template => {
            return template.Name === name;
          })
        }),
       catchError((error: HttpErrorResponse) => { return throwError(error); })
     );

  }

本文标签: javascriptRxjs map and filter array Return single object instead of array of oneStack Overflow