angularobservableangular-httpclient

Fetch array of 'data' from HTTPClient API call using Observables in Angular


I have a service from which I want to access data which are in this form from an HTTP GET request:

   "data": [
    {
        "id": "432",
        "Time": "06:25",
        "Place": "Atalanta"
    },
    {
        "id": "581",
        "Time": "18:21",
        "Place": "Georgia"
    }
   ]

I've created a service to call it which does this return method

return this.http.get<DataGroup>(url);

and two class models to access those data:

import { DataGroupValue } from './DataGroupValue';

export class DataGroup{
    value: DataGroupValue[] = [];
}

(don't know if it's doing the job right though)


export class DataGroupValue {
    id: string;
    Time: string;
    Place: string;
}

and a component that tries to call this method which doesn't work

export class TestPlannerComponent implements OnInit {

  DataGroupValues = new Array<DataGroup>();

  constructor(private dataService: DataService ) { }

  ngOnInit(): void {
    this.dataService.GetDataGroup.subscribe((res:DataGroup))=>{
        this.DataGroupValues=res; //errors here
      }
  }

}

How can we access those values?


Solution

  • Your types do not match at all, so Typescript corrently tells you that. If you are indeed receiving response as an object data that contains an array:

     {
       "data": [
        {
            "id": "432",
            "Time": "06:25",
            "Place": "Atalanta"
        },
        {
            "id": "581",
            "Time": "18:21",
            "Place": "Georgia"
        }
       ]
    }
    

    You need to create models that match these properties. I like to use interfaces:

    export interface DataGroupResponse {
      data: DataGroupValue[]; // use 'data' as that is what you are getting!
    }
    
    export interface DataGroupValue {
      id: string;
      Time: string;
      Place: string;
    }
    

    Then you need to correctly tell http what you are receiving, so what you are receiving as response is of type DataGroupPayload. Here I would already extract the array from data and send back the array as DataGroupValue:

    import { map } from 'rxjs/operators';
    
    // ...
    
    getDataGroup(): Observable<DataGroup[]> { // send back the array
      return this.http.get<DataGroupPayload>(url).pipe(  // what you are receiving is "DataGroupPayload"
        map((data: DataGroupPayload) => data.data as DataGroupValue[])
      )
    }
    

    Then in your component,

    dataGroupValues = <DataGroupValue[]>[]; // array
    
    ngOnInit(): void {
      this.dataService.getDataGroup().subscribe((res: DataGroupValue[]))=>{
         this.dataGroupValues = res;
      }
    }
    

    PS, notice I used camelCase, it's ususally how we name functions/variables.