Lucas S. Müller Lucas S. Müller - 1 month ago 14
TypeScript Question

Error: Unhandled Promise rejection in AngularJS 2

I'm building a Angular Provider that uses http to get data from The Movie DataBase Api.

But, although, i'm getting this errors in the page that i'm using that provider:
enter image description here

So, the source code of the provider and page is:

tmdb.ts

import { Injectable } from '@angular/core';
import { Http, Headers, RequestOptions, Response } from '@angular/http';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
import {Observable} from 'rxjs/Rx';

@Injectable()

export class TMDB {
apiUrl: string = "https://api.themoviedb.org/3";
apiKey: string = "xxx";
apiLang: string = "pt-BR";

posterLargePath: string = "https://image.tmdb.org/t/p/w500_and_h281_bestv2";
posterMiniPath: string = "https://image.tmdb.org/t/p/w116_and_h174_bestv2";

constructor(public http: Http) {
}

getSearchMovie(query: string){
let body = {"api_key":this.apiKey, "language":this.apiLang, "query":query, "include_adult": false};
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
return this.http.get(this.apiUrl + "/search/movie?" + JSON.stringify(body), options)
.map((res:Response) => res.json())
.catch((error:any) => Observable.throw(error.json().error || 'Server error'))
}

getDiscoverMovies(){
let body = {"api_key":this.apiKey, "language":this.apiLang, "page":1, "sort_by":"popularity.desc", "include_video": false, "include_adult": false};
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
return this.http.get(this.apiUrl + "/discover/movie?" + JSON.stringify(body), options)
.map((res:Response) => res.json())
.catch((error:any) => Observable.throw(error.json().error || 'Server error'))
}

getPosterLargeUrl(){
return this.posterLargePath;
}

getPosterMiniUrl(){
return this.posterMiniPath;
}

}


page.ts

import { Component } from '@angular/core';
//import{ Http } from '@angular/http';
import { NavController } from 'ionic-angular';
//import 'rxjs/add/operator/map'
import { TMDB } from '../../providers/tmdb.ts';

@Component({
selector: 'page-home',
templateUrl: 'home.html'
//,providers: [TMDB]
})
export class HomePage {
discoverMovies: any;
posterMiniPath: string;
posterLargePath: string;

constructor(public navCtrl: NavController) {
TMDB.getDiscoverMovies().subscribe(
movies => this.discoverMovies = movies, //Bind to view
err => {
// Log errors if any
console.log(err);
});
this.posterMiniPath = TMDB.getPosterMiniUrl();
this.posterLargePath = TMDB.getPosterLargeUrl();
}

}


I need to know that is the bug. Can someone help me? Remembering that i'm using Ionic Framework v. 2.

Edit 1:

import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';
import { TMDB } from '../../providers/tmdb.ts';

@Component({
selector: 'page-home',
templateUrl: 'home.html',
providers: [TMDB]
})
export class HomePage {
discoverMovies: any;
posterMiniPath: string;
posterLargePath: string;

constructor(public navCtrl: NavController, public tmdb: TMDB) {
tmdb.getDiscoverMovies().subscribe(
movies => this.discoverMovies = movies,
err => {
console.log(err);
});
this.posterMiniPath = tmdb.getPosterMiniUrl();
this.posterLargePath = tmdb.getPosterLargeUrl();
}

}


Edit 2:

app.module.ts:

import { NgModule } from '@angular/core';
import { IonicApp, IonicModule } from 'ionic-angular';
import { MyApp } from './app.component';
import { HomePage } from '../pages/home/home';
import { PageIntro } from '../pages/intro/page';
import { TMDB } from '../providers/tmdb.ts';

@NgModule({
declarations: [
MyApp,
HomePage,
PageIntro
],
imports: [
IonicModule.forRoot(MyApp)
],
bootstrap: [IonicApp],
entryComponents: [
MyApp,
HomePage,
PageIntro
],
providers: [ TMDB ]
})
export class AppModule {}


tmdb.ts:

import { Injectable } from '@angular/core';
import { Http, Headers, RequestOptions, Response } from '@angular/http';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
import {Observable} from 'rxjs/Rx';

/*
Generated class for the TMDB provider.

See https://angular.io/docs/ts/latest/guide/dependency-injection.html
for more info on providers and Angular 2 DI.
*/
@Injectable()

export class TMDB {
apiUrl: string = "https://api.themoviedb.org/3";
apiKey: string = "xxxx";
apiLang: string = "pt-BR";

posterLargePath: string = "https://image.tmdb.org/t/p/w500_and_h281_bestv2";
posterMiniPath: string = "https://image.tmdb.org/t/p/w116_and_h174_bestv2";

constructor(public http: Http) {
}

getSearchMovie(query: string){
let body = {"api_key":this.apiKey, "language":this.apiLang, "query":query, "include_adult": false};
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
return this.http.get(this.apiUrl + "/search/movie?" + JSON.stringify(body), options)
.map((res:Response) => res.json())
.catch((error:any) => Observable.throw(error.json().error || 'Server error'))
}

getDiscoverMovies(){
let body = {"api_key":this.apiKey, "language":this.apiLang, "page":1, "sort_by":"popularity.desc", "include_video": false, "include_adult": false};
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
return this.http.get(this.apiUrl + "/discover/movie?" + JSON.stringify(body), options)
.map((res:Response) => res.json())
.catch((error:any) => Observable.throw(error.json().error || 'Server error'))
}

getPosterLargeUrl(){
return this.posterLargePath;
}

getPosterMiniUrl(){
return this.posterMiniPath;
}

}

Answer

You're trying to call TMDB.getDiscoverMovies statically, when it is an instance method. What you should. What you should do, is add it to the @NgModule.providers, and then inject it into the HomePage

@NgModule({
  providers: [ TMDB ]
})
class AppModule {}

@Component({})
class HomePage {
  constructor(private tmdb: TMDB) {
    tmdb.getDiscoverMovies().subscribe(
        movies => this.discoverMovies = movies, //Bind to view
        err => console.log(err));
    this.posterMiniPath = tmdb.getPosterMiniUrl();
    this.posterLargePath = tmdb.getPosterLargeUrl();
  }
}

Notice we're using the TMDB as an instance now, and not statically.