3
I am new to the use of Angularjs and decided to study based on a work project.
My problem is this:
I am building a base project using Angularjs 2 to consume data from Wordpress (WP) through the REST API of WP.
In this API I seek a post from WP (custom post called news) and I need to get the image highlighted in this post, only JSON does not return the image URL, it returns the link to the json with the media information (information that contains the image data) and the identifier of that media.
Following the tutorial of Angularjs 2, I created a news service to get the data on API of WP (below the codes) and also a service for media. In the news Detail I consume the data generated by the news service and expose them in the view, but to get the image I have to consume the data generated by the media service, through the identifier that is in the json news, then my problem arises.
The solution I imagined was the most obvious in my point of view, to make a method in news Detail that through the media identifier I took this data, it works, but in doing so, calling this method in the view, it goes into request loop. I then imagined doing this in the Detail component itself of news, but there the news object is undefined, so I do not have this identifier to make the request.
I imagine it’s a very simple solution, but I have no idea how to solve, it’s been several days that I’m stuck in it.
What would be the best solution?
Codes
noticia.service.ts
import {Noticia} from "./noticia";
import {Injectable} from "@angular/core";
import {Http, Response, Headers, RequestOptions} from "@angular/http";
import {Observable} from "rxjs/Observable";
import {AppConstants} from ".././app-constants";
import "rxjs/Rx";
@Injectable()
export class NoticiaService {
constructor(private _http: Http) { }
private _apiUrl: string = AppConstants.API_URL;
getNoticias() {
return this._http.get(this._apiUrl + "noticias")
.map(res => res.json())
.catch(this.throwError);
}
getNoticia(id: number) {
return this._http.get(this._apiUrl + "noticias/:id".replace(":id", id.toString()))
.map(res => res.json())
.catch(this.throwError);
}
private throwError(response) {
return Observable.throw(response.json().error || "Server error")
}
}
media.service.ts
import {Media} from "./media";
import {Injectable} from "@angular/core";
import {Http, Response, Headers, RequestOptions} from "@angular/http";
import {Observable} from "rxjs/Observable";
import {AppConstants} from ".././app-constants";
import "rxjs/Rx";
@Injectable()
export class MediaService {
public medias: Array<Media>;
constructor(private _http: Http) { }
private _apiUrl: string = AppConstants.API_URL;
getMedias() {
return this._http.get(this._apiUrl + "media")
.map(res => res.json())
.catch(this.throwError);
}
getMedia(id: number) {
return this._http.get(this._apiUrl + "media/:id".replace(":id", id.toString()))
.map(res => res.json())
.catch(this.throwError);
}
private throwError(response) {
return Observable.throw(response.json().error || "Server error")
}
}
noticia-Detail.component.ts
import {Component, OnInit} from "@angular/core";
import {NoticiaService} from "./noticia-service";
import {MediaService} from "../medias/media-service";
import {RouteParams} from '@angular/router-deprecated';
import {Noticia} from "./noticia";
import {Media} from "../medias/media";
import {AppConstants} from ".././app-constants";
@Component({
templateUrl: "app/view/noticias/noticia-detail.html",
})
export class NoticiaDetailComponent implements OnInit {
public noticia: Noticia;
public imagemDestaque: Media;
public constantes: AppConstants = AppConstants;
constructor(private _routeParams: RouteParams, private _noticiaService: NoticiaService, private _mediaService: MediaService) { }
ngOnInit() {
let id = <number><any>this._routeParams.get("id");
this._noticiaService.getNoticia(id).subscribe(data => this.noticia = data, error => console.log(error));
}
public getImagemDestaque(id: number) {
this._mediaService.getMedia(id).subscribe(data => this.imagemDestaque = data, error => console.log(error));
}
}
noticia-Detail.html
<div *ngIf="noticia" class="col-md-12">
<article>
<section>
<header>
<h3>{{noticia.title.rendered}}</h3>
<span class="text-muted">Publicado em {{constantes.formatarDataWP(noticia.modified)}}</span>
</header>
{{getImagemDestaque(noticia.featured_media)}}
<p *ngIf="imagemDestaque">
<img src="{{imagemDestaque.media_details.sizes.full.source_url}}" alt="{{imagemDestaque.title.rendered}}" title="{{imagemDestaque.title.rendered}}"/>
</p>
</section>
</article>
</div>
news.json
{
"id": 116,
"date": "2016-06-01T10:55:27",
"date_gmt": "2016-06-01T13:55:27",
"guid": {
"rendered": "http://localhost/gerenciadorWP/?post_type=noticias&p=116"
},
"modified": "2016-06-02T16:51:28",
"modified_gmt": "2016-06-02T19:51:28",
"slug": "mais-uma-noticia",
"type": "noticias",
"link": "http://localhost/gerenciadorWP/en/blog/noticias/mais-uma-noticia/",
"title": {
"rendered": "(Português do Brasil) Mais uma noticia"
},
"content": {
"rendered": ""
},
"excerpt": {
"rendered": ""
},
"featured_media": 127,
"comment_status": "open",
"ping_status": "closed",
"tags": [],
"acf": {
"corpo": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.",
"resumo": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut a",
"chapeu": "Chapéu (ante-título)",
"subtitulo": "Subtítulo",
"origem": "",
"autor": "Jeffersson",
"documentos": [
123
],
"fotos": [
105
]
},
"_links": {
"self": [
{
"href": "http://localhost/gerenciadorWP/en/wp-json/wp/v2/noticias/116"
}
],
"collection": [
{
"href": "http://localhost/gerenciadorWP/en/wp-json/wp/v2/noticias"
}
],
"about": [
{
"href": "http://localhost/gerenciadorWP/en/wp-json/wp/v2/types/noticias"
}
],
"replies": [
{
"embeddable": true,
"href": "http://localhost/gerenciadorWP/en/wp-json/wp/v2/comments?post=116"
}
],
"version-history": [
{
"href": "http://localhost/gerenciadorWP/en/wp-json/wp/v2/noticias/116/revisions"
}
],
"wp:featuredmedia": [
{
"embeddable": true,
"href": "http://localhost/gerenciadorWP/en/wp-json/wp/v2/media/127"
}
],
"wp:attachment": [
{
"href": "http://localhost/gerenciadorWP/en/wp-json/wp/v2/media?parent=116"
}
],
"wp:term": [
{
"taxonomy": "post_tag",
"embeddable": true,
"href": "http://localhost/gerenciadorWP/en/wp-json/wp/v2/tags?post=116"
}
],
"curies": [
{
"name": "wp",
"href": "https://api.w.org/{rel}",
"templated": true
}
]
}
}
media.json
{
"id": 127,
"date": "2016-06-02T16:51:16",
"date_gmt": "2016-06-02T19:51:16",
"guid": {
"rendered": "http://localhost/gerenciadorWP/wp-content/uploads/2016/06/2014_batman_arkham_knight-wide-batman-arkham-knight-has-shadow-of-mordor-s-combat-affected-it.jpeg"
},
"modified": "2016-06-02T16:51:16",
"modified_gmt": "2016-06-02T19:51:16",
"slug": "2014_batman_arkham_knight-wide-batman-arkham-knight-has-shadow-of-mordor-s-combat-affected-it",
"type": "attachment",
"link": "http://localhost/gerenciadorWP/en/blog/noticias/mais-uma-noticia/2014_batman_arkham_knight-wide-batman-arkham-knight-has-shadow-of-mordor-s-combat-affected-it/",
"title": {
"rendered": "2014_batman_arkham_knight-wide-batman-arkham-knight-has-shadow-of-mordor-s-combat-affected-it"
},
"author": 1,
"comment_status": "open",
"ping_status": "closed",
"alt_text": "",
"caption": "",
"description": "",
"media_type": "image",
"mime_type": "image/jpeg",
"media_details": {
"width": 2560,
"height": 1600,
"file": "2016/06/2014_batman_arkham_knight-wide-batman-arkham-knight-has-shadow-of-mordor-s-combat-affected-it.jpeg",
"sizes": {
"thumbnail": {
"file": "2014_batman_arkham_knight-wide-batman-arkham-knight-has-shadow-of-mordor-s-combat-affected-it-150x150.jpeg",
"width": 150,
"height": 150,
"mime_type": "image/jpeg",
"source_url": "http://localhost/gerenciadorWP/wp-content/uploads/2016/06/2014_batman_arkham_knight-wide-batman-arkham-knight-has-shadow-of-mordor-s-combat-affected-it-150x150.jpeg"
},
"medium": {
"file": "2014_batman_arkham_knight-wide-batman-arkham-knight-has-shadow-of-mordor-s-combat-affected-it-300x188.jpeg",
"width": 300,
"height": 188,
"mime_type": "image/jpeg",
"source_url": "http://localhost/gerenciadorWP/wp-content/uploads/2016/06/2014_batman_arkham_knight-wide-batman-arkham-knight-has-shadow-of-mordor-s-combat-affected-it-300x188.jpeg"
},
"medium_large": {
"file": "2014_batman_arkham_knight-wide-batman-arkham-knight-has-shadow-of-mordor-s-combat-affected-it-768x480.jpeg",
"width": 768,
"height": 480,
"mime_type": "image/jpeg",
"source_url": "http://localhost/gerenciadorWP/wp-content/uploads/2016/06/2014_batman_arkham_knight-wide-batman-arkham-knight-has-shadow-of-mordor-s-combat-affected-it-768x480.jpeg"
},
"large": {
"file": "2014_batman_arkham_knight-wide-batman-arkham-knight-has-shadow-of-mordor-s-combat-affected-it-1024x640.jpeg",
"width": 1024,
"height": 640,
"mime_type": "image/jpeg",
"source_url": "http://localhost/gerenciadorWP/wp-content/uploads/2016/06/2014_batman_arkham_knight-wide-batman-arkham-knight-has-shadow-of-mordor-s-combat-affected-it-1024x640.jpeg"
},
"post-thumbnail": {
"file": "2014_batman_arkham_knight-wide-batman-arkham-knight-has-shadow-of-mordor-s-combat-affected-it-1200x750.jpeg",
"width": 1200,
"height": 750,
"mime_type": "image/jpeg",
"source_url": "http://localhost/gerenciadorWP/wp-content/uploads/2016/06/2014_batman_arkham_knight-wide-batman-arkham-knight-has-shadow-of-mordor-s-combat-affected-it-1200x750.jpeg"
},
"full": {
"file": "2014_batman_arkham_knight-wide-batman-arkham-knight-has-shadow-of-mordor-s-combat-affected-it.jpeg",
"width": 2560,
"height": 1600,
"mime_type": "image/jpeg",
"source_url": "http://localhost/gerenciadorWP/wp-content/uploads/2016/06/2014_batman_arkham_knight-wide-batman-arkham-knight-has-shadow-of-mordor-s-combat-affected-it.jpeg"
}
},
"image_meta": {
"aperture": "0",
"credit": "",
"camera": "",
"caption": "",
"created_timestamp": "0",
"copyright": "",
"focal_length": "0",
"iso": "0",
"shutter_speed": "0",
"title": "",
"orientation": "1",
"keywords": []
}
},
"post": 116,
"source_url": "http://localhost/gerenciadorWP/wp-content/uploads/2016/06/2014_batman_arkham_knight-wide-batman-arkham-knight-has-shadow-of-mordor-s-combat-affected-it.jpeg",
"_links": {
"self": [
{
"href": "http://localhost/gerenciadorWP/en/wp-json/wp/v2/media/127"
}
],
"collection": [
{
"href": "http://localhost/gerenciadorWP/en/wp-json/wp/v2/media"
}
],
"about": [
{
"href": "http://localhost/gerenciadorWP/en/wp-json/wp/v2/types/attachment"
}
],
"author": [
{
"embeddable": true,
"href": "http://localhost/gerenciadorWP/en/wp-json/wp/v2/users/1"
}
],
"replies": [
{
"embeddable": true,
"href": "http://localhost/gerenciadorWP/en/wp-json/wp/v2/comments?post=127"
}
]
}
}
The values arrive normal in the variable imageDestaque, but the thing is that the view keeps calling in loop the getImagemDestaque method, what I’m not getting.
– Jeffersson Galvão
I do not understand much of angular 2, but already tried to run direct by js , I will put in question
– luizluan
It does not work, because in ngOnInit the object news is not defined yet.
– Jeffersson Galvão