Angular 2 observable does not โ€œrenderโ€ the model

When I learn Angular 2, I used observable to get some data through the API. Like this:

getPosts() { return this.http.get(this._postsUrl) .map(res => <Post[]>res.json()) .catch(this.handleError); } 

My model is as follows:

 export class Post { constructor( public title: string, public content: string, public img: string = 'test') { } 

The problem I am facing is that the map operator is not doing anything with the Post model. For example, I tried to set a default value for the img value, but nothing is displayed in the post.img view. I even changed Post [] with another model (Message []), and the behavior did not change. Can anyone explain this behavior?

+6
source share
2 answers

I had a similar problem when I wanted to use a computed property in a template.

I found a good solution in this article:

http://chariotsolutions.com/blog/post/angular-2-beta-0-somnambulant-inauguration-lands-small-app-rxjs-typescript/

You create a static method in your model that takes an array of objects and then calls this method from the map function. In the static method, you can either call the constructor that you already defined, or use the copy constructor:

Matching method

 getPosts() { return this.http.get(this._postsUrl) .map(res => Post.fromJSONArray(res.json())) .catch(this.handleError); } 

Existing constructor

 export class Post { // Existing constructor. constructor(public title:string, public content:string, public img:string = 'test') {} // New static method. static fromJSONArray(array: Array<Object>): Post[] { return array.map(obj => new Post(obj['title'], obj['content'], obj['img'])); } } 

Copy constructor

 export class Post { title:string; content:string; img:string; // Copy constructor. constructor(obj: Object) { this.title = obj['title']; this.content = obj['content']; this.img = obj['img'] || 'test'; } // New static method. static fromJSONArray(array: Array<Object>): Post[] { return array.map(obj => new Post(obj); } } 

If you use an editor that supports code completion, you can change the type of the obj and array parameters to Post :

 export class Post { title:string; content:string; img:string; // Copy constructor. constructor(obj: Post) { this.title = obj.title; this.content = obj.content; this.img = obj.img || 'test'; } // New static method. static fromJSONArray(array: Array<Post>): Post[] { return array.map(obj => new Post(obj); } } 
+12
source

You can use the as keyword to de-serialize JSON for your object.

There is a tutorial in Angular2 docs that you understand this about. However, in short ...

Model:

 export class Hero { id: number; name: string; } 

Services:

 ... import { Hero } from './hero'; ... get(): Observable<Hero> { return this.http .get('/myhero.json') .map((r: Response) => r.json() as Hero); } 

component:

 get(id: string) { this.myService.get() .subscribe( hero => { console.log(hero); }, error => console.log(error) ); } 
0
source

All Articles