rossco
rossco

Reputation: 625

How to iterate over JSON returned by HttpClient

I have a simple Angular HttpClient, which is correctly returning JSON. I am attempting to cast the results to enforce type safety (not sure if this is correct).

But how do I actually access the returned JSON to copy it into an array?

The httpClient get() request is (and seems to be working fine):

public sendGetRequest(): Observable<Symbols[]> {
    return this.httpClient.get<Symbols[]>(this.REST_API_SERVER);
  }

The Symbols interface is

export interface Symbols {
  code: string
  desc: string
}

I have a component which calls the data service and is getting a response. However the code below returns an error when attempting to map the JSON into a string array

ERROR TypeError: syms.map is not a function
listOfOption: Array<{ value: string; label: string }> = []

this.dataService.sendGetRequest().subscribe((syms: Symbols[]) => {
  console.log('return value ' + JSON.stringify(syms))
  // console output shows the returned JSON and it looks correct

  //this does not work, how do I copy the results to a string array??
  this.listOfOption = syms.map(results => {
     return {
        value: results.code,
        label: results.code,
     }
  })
})

The JSON data structure is:

{
  "results": [
    {
      "code": "code1",
      "desc": "Long description of code 1"
    },
    {
      "code": "code2",
      "desc": "Long description of code 2"
    },
    {
      "code": "code3",
      "desc": "Long description of code 3"
    },
    {
      "code": "code4",
      "desc": "Long description of code 4"
    }
  ]
}

This is driving me crazy

Upvotes: 0

Views: 614

Answers (2)

Pallavi
Pallavi

Reputation: 506

Model a new interface called responseData to support response type.

export interface responseData{
  results: Symbols[]
}


export interface Symbols {
   code: string
   desc: string
}

Update the same in service

public sendGetRequest(): Observable<responseData> {
  return this.httpClient.get<responseData>(this.REST_API_SERVER);
}

You can now retrieve the results using array.map()

listOfOption: Array<{ value: string; label: string }> = []

this.dataService.sendGetRequest().subscribe((syms: responseData) => {
  console.log('return value ' + syms)

  
  this.listOfOption = syms.results.map(result => {
     return {
        value: result.code,
        label: result.code,
     }
  })
})

Upvotes: 1

Jon G St&#248;dle
Jon G St&#248;dle

Reputation: 3904

The response data has an object root, but you're trying to parse it as an array root. I think the simplest solution would be something like this:

public sendGetRequest(): Observable<Symbols[]> {
  return this.httpClient.get<{results: Symbols[]}>(this.REST_API_SERVER)
    .pipe(pluck('results'));
}

Which specifies that the response data is an object with a field named results which holds an array of Symbols.

Alternatively you could also extract the response type to a separate definition:

interface ApiResponse {
  results: Symbols[]
}

public sendGetRequest(): Observable<Symbols[]> {
  return this.httpClient.get<ApiResponse>(this.REST_API_SERVER)
    .pipe(pluck('results'));
}

Upvotes: 1

Related Questions