Reputation: 3922
I am having trouble with what I have to believe is a fairly common situation in Angular / Typescript / JavaScript in general. I have a simple class with some fields and some methods.
class Rectangle {
width: number;
height: number;
area(): number {
return this.width * this.height;
}
}
I then have a service with the following method that retrieves these things from my server:
class RectangleService {
... // blah blah blah
getRectangle (id: number): Observable<Rectangle> {
// no error handling needed - nothing ever goes wrong with web services... :)
return this.http.get<Rectangle> ('http://myserver.com:8080/rectangle/' + id);
}
}
And of course, my web service returns something like
{width: 10, height:15}
But then once I get the thing back, I can't call area() on it because (I am guessing) we have a bare JavaScript associative array masquerading as a Rectangle. Which makes sense to some degree I suppose - this isn't Java where object creation is locked down by constructors. But what is the accepted way to get that data from JSON returned by the web service into a proper Rectangle that has the methods available?
Do I have to manually build a constructor to do this? This obviously wouldn't be tedious in this case, but in the case where there are several nested objects, it seems like it could get out of hand quickly.
I have seen some "roll-your-own" solutions (and some are very good), but this would seem to be a very common scenario in Angular, so I find it strange that there is no commonly accepted practice or library to do this. Am I doing something wrong here?
Upvotes: 3
Views: 693
Reputation: 60548
The server just returns data formed with properties from the defined object. It doesn't actually create an instance of the object.
Try something like this:
return this.http.get<Rectangle> ('http://myserver.com:8080/rectangle/' + id)
.map(res => Object.assign(new Rectangle(), res));
This should create the object and then copy any of the retrieved properties into it.
Here is some sample code I used on the TypeScript playground (https://www.typescriptlang.org/play/):
class Hospital {
hospital: string;
doctors: Doctors[];
}
class Doctors {
id: number;
ward: string;
}
class Test {
hospitals: Hospital[] = [];
hospitals2: Hospital[];
constructor() {
this.hospitals[7] = {
hospital: "New York Hospital",
doctors: [{
id: 1269,
ward: "test"
}]
};
this.hospitals2 = Object.assign(new Hospital(), this.hospitals);
}
data() {
return JSON.stringify(this.hospitals) + '<br>' +
JSON.stringify(this.hospitals2);
}
}
let tester = new Test();
let button = document.createElement('button');
button.textContent = "Say Hello";
button.onclick = function() {
alert(tester.data());
}
document.body.appendChild(button);
Upvotes: 2