0

I'm trying to implement a decoupled wordpress solution and I'm having a bit of confusion displaying the JSON object properties in my template. I'm able to return JSON objects for the WP API but not sure how to handle them. The only way I can get a property to display it's value in a template is if I add a [0] to the interpolated property, which won't work in an ngFor loop. I've read the solution by @Thierry here access key and value of object using *ngFor but this doesn't seem to be how Google handles the Tour of Heroes app http://plnkr.co/edit/WkY2YE54ShYZfzJLSkMX?p=preview

Google uses this data set:

    {
  "data": [
    { "id": "1", "name": "Windstorm" },
    { "id": "2", "name": "Bombasto" },
    { "id": "3", "name": "Magneta" },
    { "id": "4", "name": "Tornado" }
  ]
}

which looks like a JSON object to me, so how is the app able to handle something like this:

 <ul>
  <li *ngFor="let hero of heroes">
    {{hero.name}}
  </li>
</ul>

I'm just unclear if there's been a change in RC5 that allows iteration over an object, or do I still need to transform this somehow. I'm very new to Angular and could use a little guidance on this matter. Thanks!!

An update based on the comments, if I want to transform an api request like http://localhost:8888/wp-json/wp/v2/posts, what's the best method for that? My return code would look something like:

[
  {
    "id": 4,
    "date": "2016-08-09T00:09:55",
    "date_gmt": "2016-08-09T00:09:55",
    "guid": {
      "rendered": “http://localhost:8888/?p=4"
    },
    "modified": "2016-08-09T00:11:05",
    "modified_gmt": "2016-08-09T00:11:05",
    "slug": “wp-api-test”,
    "type": "post",
    "link": "http://localhost:8888/2016/08/wp-api-test”,
    "title": {
      "rendered": "testing the wp api"
    },
    "content": {
      "rendered": "<p>loreum ipsum</p>\n"
    },
    "excerpt": {
      "rendered": "<p>loreum ipsum</p>\n"
    },
    "author": 1,
    "featured_media": 0,
    "comment_status": "open",
    "ping_status": "open",
    "sticky": false,
    "format": "standard",
    "categories": [
      1
    ],
  }
]
Community
  • 1
  • 1
Amanda K
  • 75
  • 9

4 Answers4

0

Without writing all the code for you, there is no short answer to what you are asking, but here are some tips:

Ben Richards
  • 3,437
  • 1
  • 14
  • 18
0

How are you defining your services?

Here's an example:

export interface IPost {
  id: number;
  date: Date;
  date_gmt: Date;
  ... // rest of your defintion
}

@Injectable()
export class BlogPostService {
    private http: Http;

    constructor(http: Http) {
        this.http = http;
    }

    private apiUrl: string = 'api/blog/posts.json';

    getPosts(): Observable<IPost[]> {
        return (this.http.get(this.apiUrl)
            .map((response: Response) => <IPost[]>response.json())
            .do(data => console.log('All: ' + JSON.stringify(data)))
            .catch(this.handleError)) as any;
    }

    private handleError(error: Response) {
        console.error(error);
        return Observable.throw(error.json().error || "Server error");
    }
}

This line should transform your json object to array[] of IPosts

.map((response: Response) => <IPost[]>response.json())

Hope that helps.

penleychan
  • 5,370
  • 1
  • 17
  • 28
0

Thanks so much for the answers. They helped lead me to the solution. I was able to solve this rather simply by creating a posts array and making it equal to the Observable return. The component looks like this:

posts: {};

constructor (private _wpService: WpApiService) {}

ngOnInit() { this.getPosts() }

getPosts() {

    this._wpService.getPosts()
        .subscribe(
          data => {
            this.posts = data;
        });
  } 

The template looks like:

<li *ngFor="let post of posts">
     <h3>{{post.title.rendered}}</h3>
</li>
Amanda K
  • 75
  • 9
0

Just replace {{hero.name}} by {{hero.data.name}}

The best way to handle the JSON object by creating an interface class to access the data easily

Catarina Ferreira
  • 1,824
  • 5
  • 17
  • 26
Safwan Mh
  • 66
  • 8