Angular - HttpClient: Map Get method object result to array property

后端 未结 5 607
忘了有多久
忘了有多久 2021-02-04 06:19

I am calling an API that returns a JSON Object. I need just the value of the array to map to a Observable . If I call api that just returns the array my service call works.

相关标签:
5条回答
  • 2021-02-04 06:24

    .map(res=> res['shows'] ) does the trick

    0 讨论(0)
  • 2021-02-04 06:28

    You can simply .map() your http call, which is an Observable, to return the data type that you want.

    findAllShows(): Observable<Show[]> {
        return this.http
            .get(`${someURL}/shows`)
            .map(result=>result.shows)
    }
    

    Your httpClient.get() should return an Observable, which you have explicitly stated it thought Observable<Show[]>. You .map() is an operator that transform the observable into a new one.

    More on .map() operator: http://reactivex.io/documentation/operators/map.html

    Update:

    For RXJS version 6 and above, simply use .pipe() to pipe the .map() operator:

    findAllShows(): Observable<Show[]> {
        return this.http
            .get(`${someURL}/shows`)
            .pipe(map(result=>result.shows))
    }
    
    0 讨论(0)
  • 2021-02-04 06:46

    Latest HttpClient which should be used instead of http has no map method. You should first import it by import { map } from 'rxjs/operators'; Then you should use it this way:

    this.http.get(`${someURL}/shows`).pipe(
            map(res => res['shows'])
        )
    
    0 讨论(0)
  • 2021-02-04 06:47

    There are 2 approaches of doing this. You can use .map operator form the observable to map one type of observable into another and second approach includes just with the help of interface.

    1st Approaches (with the help of .map)

    import { Injectable } from '@angular/core';
    import { HttpClient } from '@angular/common/http';
    
    import { Observable } from 'rxjs/Observable';
    
    import 'rxjs/add/operator/map';
    
    interface ItemsResponseObj {
        id: string,
        modified: string,
        name: string
    }
    
    interface ItemsResponse {
        shows: Array<ItemsResponseObj>;
    }
    
    @Injectable()
    export class AppService {
    
        constructor(private http: HttpClient) { }
    
        getData(): Observable<ItemsResponseObj[]> {
            return this.http.get<ItemsResponse>('api/api-data.json')
                .map(res => res.shows);
        }
    
    }
    

    and in the 2nd approach with the help of wrapping interfaces

    import { Injectable } from '@angular/core';
    import { HttpClient } from '@angular/common/http';
    
    import { Observable } from 'rxjs/Observable';
    
    interface ItemsResponseObj {
        id: string,
        modified: string,
        name: string
    }
    
    interface ItemsResponse {
        shows: Array<ItemsResponseObj>;
    }
    
    @Injectable()
    export class AppService {
    
        constructor(private http: HttpClient) { }
    
        getData(): Observable<ItemsResponse> {
            return this.http.get<ItemsResponse>('api/api-data.json')
        }
    
    }
    
    0 讨论(0)
  • 2021-02-04 06:51

    Thanks All, I was able to find solution by combining responses from @ Arun Redhu by providing a transfer object interface that the server sends back. Then solution provided by @CozyAzure by using the .map() to transform one Observable to the correct Observable Show[].

    Full Solution below for those interested.

    import {Observable} from 'rxjs/Observable';
    import {Contact} from '../models/show';
    import {environment} from '../../../environments/environment';
    // Use the new improved HttpClient over the Http
    // import {Http, Response} from '@angular/http'; 
    import {HttpClient} from '@angular/common/http';
    
    // Create a new transfer object to get data from server
    interface ServerData {
      shows: Show[];
    }
    
    @Injectable()
    export class ShowsService {
    
      constructor(private http: HttpClient ) { }
    
    // want Observable of Show[]
      findAllShows(): Observable<Show[]> {  
        // Request as transfer object <ServerData>
        return this.http
          .get<ServerData>(`${apiURL}/shows`)
         // Map to the proper Observable I need 
          .map(res => <Show[]>res.shows); 
    
      }
    }
    

    All great now!!! Thanks . So depending on data returned I can either use directly or map to proper Observable I need.

    0 讨论(0)
提交回复
热议问题