Liem
Liem

Reputation: 456

How to map http response to client model type in Angular

I have model MyObejct like this in client:

class MyObject{
 id: number;
 name: string;
 active: boolean;
}

And the http response json data like this:

[
 {
  id: "1",
  name: "object1",
  active: "true",
 }
]

The http response is key-value pair, and all the value type is string. So how can I map the http response to 'MyObject' type. The http get function is like this:

getMyObejct(name: string): Observable<MyObject> {
 const url = this.url + 'name/' + name;
 return this.http.get<MyObject>(url);  // This is part I'm confused
}

getAllObjects(): Observable<MyObject[]> {
 return this.http.get<MyObject>(this.url); // How to map this reponse to MyObject
}

The http response values are all string type, but MyObject has types number and boolean. How can I do that?

Upvotes: 1

Views: 1951

Answers (3)

Hemendra
Hemendra

Reputation: 388

To specify the response object type, first define an interface with the required properties. (Use an interface rather than a class; a response cannot be automatically converted to an instance of a class.)

interface MyObject{
 id: number;
 name: string;
 active: boolean;
}

getAllObjects(): Observable<MyObject[]> {
 return this.http.get<MyObject>(this.url); // now returns an Observable of MyObject[]
}

Read more about it here - https://angular.io/guide/http#typechecking-the-response

Upvotes: 0

raychz
raychz

Reputation: 1175

You may want to look into class-transformer. The plainToClass method transforms a plain javascript object to an instance of a specific class.

import {plainToClass} from "class-transformer";

fetch(url).then((objects: MyObject[]) => {
    const realMyObjects = plainToClass(MyObject, objects);
    // now each object in realMyObjects is an instance of MyObject class
});

In your case, you'll need to enable implicit type conversion:

class MyPayload {
  prop: string
}

const result1 = plainToClass(MyPayload, { prop: 1234 }, { enableImplicitConversion: true });

/**
 *  result1 will be `{ prop: "1234" }` - notice how the prop value has been 
 *  converted to string.
 */

Upvotes: 0

GreyBeardedGeek
GreyBeardedGeek

Reputation: 30088

It depends on whether you truly need an instance of MyObject, or just something with the same properties.

If you just need an object with the same properties, you can do:

return this.http.get<MyObject>(url).map( (obj) => {
  id: Number(obj.id), 
  name: obj.name,
  active: obj.active === 'true'
});

If you need an actual MyObject instance (e.g. if MyObject has methods), you can do:

return this.http.get<MyObject>(url).map( (obj) => Object.assign(new MyObject(), {
  id: Number(obj.id), 
  name: obj.name,
  active: obj.active === 'true'
}));

Upvotes: 1

Related Questions