How to dynamically map json response object to object?
I am implementing ng2 where my user.service.ts calls the REST service and returns json like this:
getUser(id: number): Promise<User> {
return this.http.get('http://localhost:4000/users/1')
.toPromise()
.then(response => response.json())
}
The returned object looks like this:
{
"Id":"1"
"FirstName":"John"
"LastName":"Smith"
}
I need to convert this to a custom ng2 object that looks like this:
export class User
{
Id: number;
FirstName: string;
LastName: string;
}
I would like to do this in the most general way so that I can use the template. For example, something like:
var user = userResponse.map(User);
I would like this to use reflection or a similar dynamic technique, so the rendering happens automatically without any further explicit requirement. What would be a good way to do this in ng2?
source to share
Based on the comments, it seems like you want to avoid creating a constructor in your class. Well, the "simplest" solution here is to use Object.assign()
:
getUser(id: number): Promise<User> {
return this.http.get('http://localhost:4000/users/1')
.map(res => Object.assign(new User(), res.json()))
.toPromise()
}
Your data is now instances User
.
Demo: http://plnkr.co/edit/Gzi6tjZzTizDhlMCD1y9?p=preview (check console)
source to share
When you declare your class, you can add a constructor that builds the class correctly:
export class User
{
Id: number;
FirstName: string;
LastName: string;
constructor(obj: any) {
this.Id = +obj['Id'];
this.FirstName = obj['FirstName'];
this.LastName = obj['LastName'];
}
}
Check out this plunker to see it in action.
For setting and resetting dynamically, you can create a method:
let user = setUser(this.userResponse); // <-- Assuming this.userResponse is the returned object
setUser(res) {
return {
Id: +res['Id'],
FirstName: res['FirstName'],
LastName: res['LastName']
};
}
source to share
Get property keys from json object, then loop through them and assign them to object properties by name.
.then(json => {
Object.keys(json).forEach(key => user[key] = json[key]);
});
Or as a reusable function as you requested:
export class User {
// properties
mapResponse(response) {
Object.keys(response).forEach(key => this[key] = json[key]);
}
}
getUser(id: number): Promise<User> {
var user = new User();
this.http.get('http://localhost:4000/users/1')
.toPromise()
.then(response => response.json())
.then(newUser.mapResponse);
return user;
}
I've never written TypeScript, so I gave it my best guess. Hope this is enough to get you started.
source to share
In my project I am using Observable instead of Promise and my code is like
getUser(id: number): Observable<User> {
return this.http.get('http://localhost:4000/users/1')
.map(resp=>resp.json());
}
If a promise is required
getUser(id: number): Promise<User> {
return this.http.get('http://localhost:4000/users/1')
.map(resp=>resp.json())
.toPromise()
}
source to share