0

How can I cast or convert an HttpClient response to array of custom class objects in Angular?

I have a provider like:

import { Client } from '../../models/client.model';

@Injectable()
export class ClientProvider {

  clients: Client[] = [];
  url = "link/to/api/clients" //Should return an array of clients

  constructor(public http: HttpClient){ }

  getClient() {
     this.http.get(this.url)
  .subscribe(
      (response) => {
        this.clients = response as Client[];
        console.log(this.clients[0]) // this works and shows the client info
        console.log(this.clients[0].getName()); //this gives error (1)
       });
  }

Error:

ERROR TypeError: _this.clients[0].getName is not a function

I even tried

(response: Client[]) => {
   this.clients = response ...}}

But it gives me the same error.

my model definition is like:

export class Client{
    id: number;
    name: string;

    getName() {
    return this.name;
    }
}
1
  • Please add the logs you're getting in the console on the screen. Commented Oct 22, 2018 at 8:05

5 Answers 5

3

This wont work. When you get the JSON response,all that framework do for you is parsing that JSON into plain object. Every type declaration or casting are meaningless and are valid only on compile time (as a type hint for IDE and brief type control for transpiler).

There is no instance of Client class there to call method on.

If you want it to be instance of class, you must map the whole response first like this:

  getClient() {
     this.http.get(this.url)
     .pipe(
        map(plainJson=> create new Client here from json)// HER Eyou must create CLIENT yourself from plain javascript object
     )
  .subscribe(
      (response) => {
        this.clients = response as Client[];
        console.log(this.clients[0]) // this works and shows the client info
        console.log(this.clients[0].getName()); //this gives error (1)
       });
Sign up to request clarification or add additional context in comments.

Comments

2

Issue

The issue with your approach is, you are trying to assign the response to Client[] array. However it just the assignment of response data to client variable.

Fix

If you want to convert response to respective models class then you need to handle it from the model class itself.

ex :

Create the constructor in the model class

export class Client{

constructor(obj?: any) {
   Object.assign(this, obj);
}

id: number;
name: string;

getName() {
return this.name;
}

}

getClient() {
     this.http.get(this.url)
  .subscribe(
      (response) => {
        let clients = this.response.map(item=>new Client(item)); //Create new instance of client and set the properties.
       });

Note : Check the type of response. The above implementation when the response contains the multiple client.

Comments

1

try this console.log(this.clients[0].name);

There is no need to of using function here.

1 Comment

yes, i know, but it's just an example, because i 'll need some some other functions later; i think i'll map ther response as above answers say
1

Type hinting is not the same as casting. You cannot do as Client and expect the object to become a Client class and have all the methods in there. You need to map it:

this.http.get(this.url).pipe(
    map((clients) => clients.map((client) => ({ ...new Client(), ...client})) 
  )
  .subscribe(
      (clients) => {
        console.log(clients[0]) // this works and shows the client info
        console.log(clients[0].getName());
});

Comments

0

You can directly cast your response and do like this

getClient() {
     this.http.get<Array<Client>>(this.url)
  .subscribe(
      (response) => {
        /*here you can directly iterate response and get Client objects*/
        for(let client in response){
         console.log(client.name);
         }

       });
  }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.