Request loop in AngularJS 2

3

I'm new to using AngularJs and decided to study based on a work project.

My problem is this:

I'm building a base project using AngularJs 2 to consume Wordpress ( WP ) data via WP REST API .

In this API I look for a WP post (custom post called news ) and I need to get the highlighted image in this post, but JSON does not return the URL of the image , it returns the link to json with the media information (information that contains the image data) and the media identifier.

Following the AngularJS 2 tutorial, I created a news service to get the data in the WP API ) and also a service for medium. In the detail of news 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 json of news, here comes my problem .

The solution I imagined was the most obvious in my view, to do a method in the detail of news that through the media identifier I took these data, this works, but in doing so, calling this method in the view, it it enters a request loop. I imagined then doing this in the component detail of news, but there the object news is undefined, therefore I do not have this identifier to make the request.

I imagine it is a very simple solution, but I have no idea how to solve it, I have been locked in for several days.

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")
    }

}

news-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));
    }

}

news-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>

noticia.json

{
  "id": 116,
  "date": "2016-06-01T10:55:27",
  "date_gmt": "2016-06-01T13:55:27",
  "guid": {
    "rendered": "http://localhost/gerenciadorWP/?post_type=noticias&#038;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"
      }
    ]
  }
}
    
asked by anonymous 16.06.2016 / 20:37

2 answers

1

With the help of Nicolas Takashi , which instructed me to study LifeCycle Hooks in AngularJS 2, I discovered the problem of multiple requests. So I was able to find out where in the Component's LifeCycle the news object was set and there I made the media service call to get the data from the image. After the image is set I canceled the subscription of the service so as not to have problems with Memory Leak besides using the ngOnDestroy hook to release all services.

    
22.06.2016 / 16:08
1

Have you ever used a debug method to see which values are coming up in the image variable? Use the batarang to debug the js so you already check if the json is being correctly loaded. I believe it must be something, probably some detail. Or some internal error of angular, at last without debugging has no way, in terms of code I saw nothing wrong.

Try to run straight to see if it will loop:

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) { }

 public getImagemDestaque(id: number) {
        this._mediaService.getMedia(id).subscribe(data => this.imagemDestaque = data, error => console.log(error));
    }

    ngOnInit() {
        let id = <number><any>this._routeParams.get("id");
        this._noticiaService.getNoticia(id).subscribe(data => this.noticia = data, error => console.log(error));

        this.getImagemDestaque(noticia.featured_media);
    }



}
    
16.06.2016 / 21:52