Сommon approach to process http response is like that:
return this._http.get(url)
.map((res: Response) => res.json());
which provides you with an Observable<Object[]>
where Object
is dynamically created type from json de-serialization.
Then you can use this result in *ngFor="let item of result | async"
etc...
I'd like to get a specific type instance (meaning using new
operator to call the type's constructor).
Tried different ways to achieve something like that:
.map((res: Response) => { let obj = res.json(); return new MyObject(obj.id, obj.name);})
but getting this error: Cannot find a differ supporting object '[object Object]' of type 'object'. NgFor only supports binding to Iterables such as Arrays.
This way seems to work but it's way too complicated and probably not effective:
.map((res: Response) => {
let results = <MyObject[]>[];
let obj = res.json();
obj.forEach(
function (o: any) {
results.push(new MyObject(o.id, o.name));
}
);
return results;
}
Thanks!
If you know what type of objects you want to deconstruct from the JSON (which you probably do) you can create a static method that returns an instance from Object.
class MyClass {
prop: number;
static fromObject(src: Object) {
var obj = new MyClass();
obj.prop = src.prop;
return obj;
}
}
Then convert the JSON response to instances of MyClass
:
Rx.Observable.of('[{"prop":1},{"prop":2},{"prop":3}]')
.map(val => JSON.parse(val))
.exhaustMap(val => new Rx.Observable.from(val))
.map(val => MyClass.fromObject(val))
.subscribe(
item => console.log('Next: ', item),
error => console.log('Error:', error),
_ => console.log('Completed')
);
How this works:
.map(val => JSON.parse(val))
Just converts the response to JSON which is an array of objects.
.exhaustMap(val => new Rx.Observable.from(val))
Converts each value to an Observable and exhaustMap
flattens them so each object from the JSON will be emitted separately.
.map(val => MyClass.fromObject(val))
Use map
again to convert each Object to an instance of MyClass
.
See live demo: http://jsfiddle.net/f5k9zdh1/1/