Reputation: 11649
I receive a json from the backend which contains an array of client
object:
Here is the client class:
export class Client {
private id:number;
private firstname: String;
private lastname: String;
private phone:String;
private address:String;
private country:String;
private Security_No:String;
}
I am looking for easiest way to cast the received json
to a Clients[]
.
currently i store the json in an attribute, and later i go throw it and extract data fram it. but it seems that, there should be an easier way?
populateClientData() {
this._httpClientService.getAllClients().subscribe((res)=>this.data=res.json()))
}
Upvotes: 3
Views: 21818
Reputation: 164177
You can not cast json data (that is, js objects) into classes.
Well, you can, but then you don't really have instances of the class but objects that satisfy the class interface.
Simple example:
class Point {
x: number;
y: number;
constructor(x: number, y: number) {
this.x = x;
this.y = y;
}
}
let a = {
x: 5,
y: 5
} as Point;
console.log(a); // Object {x: 5, y: 5}
let b = new Point(5, 5);
console.log(b); // Point {x: 5, y: 5}
The compiler won't complain about a
not being an instance of Point
because it satisfies the Point
interface, so these are valid:
function log(point: Point) {
console.log(`(${ point.x }, ${ point.y })`);
}
log(a); // fine
log(b); // fine
It works this way because:
One of TypeScript’s core principles is that type-checking focuses on the shape that values have. This is sometimes called “duck typing” or “structural subtyping”. In TypeScript, interfaces fill the role of naming these types, and are a powerful way of defining contracts within your code as well as contracts with code outside of your project.
As for you specific problem, you can use your class as an interface or just make it into an interface:
interface Client {
id:number;
firstname: String;
lastname: String;
phone:String;
address:String;
country:String;
Security_No:String;
}
And then (in both cases):
this._httpClientService.getAllClients().subscribe((res) => {
this.data = res.json() as Client[]
}));
But if you'll use your class (and not the interface) then the properties must be public and not private.
If you wish to use your class as a class and not interface then casting won't do, you'll need to:
this._httpClientService.getAllClients().subscribe((res) => {
this.data = res.json().map(item => new Client(data));
}));
And you'll need to have a constructor for Client
which accepts the interface and assigns the values to its members.
Upvotes: 6
Reputation: 2676
In my app, I have a user object that has many fields and a number of arrays to store data so it's a complex object. In the map operator, I can cast the response.json()
to that value like this:
return this.http.get(this.constants.userUrl + userId, { headers: headers })
.map((response: Response) => <User>response.json())
.catch(this.handleError);
}
The subscribe is handled the same way:
Upvotes: 4