Search code examples
angularhttpionic-frameworkgetionic3

ionic 3 HTTP get REST API "'Items' does not exist ont type 'object'"


I'm trying to build this app that fetches API data from https://developers.themoviedb.org/3/lists/get-list-details. Which actually works when I "ionic serve --lab". but when i'm trying to "ionic cordova run android" it gives me the error of:

Property 'items' does not exist on type 'Object'.

  L48:  .subscribe(data => {
  L49:    this.data = data.items;
  L50:    resolve(this.data);

Here is my provider 'movie-service.ts':

import { HttpClient } from '@angular/common/http';
import { HTTP } from '@ionic-native/http';
import { Injectable } from '@angular/core';
import 'rxjs/add/operator/map';
/*
  Generated class for the MovieServiceProvider provider.

  See https://angular.io/guide/dependency-injection for more info on providers
  and Angular DI.
*/
@Injectable()
export class MovieServiceProvider {
  data: Object = {};
  items: Array<any>;  

  apiUrl = 'https://api.themoviedb.org/3/list'
  apiKey = '?api_key=9e493b8e1d5cda98bb97c77029b786a0'

  constructor(private http: HttpClient) {
    console.log('Hello MovieServiceProvider Provider');
  }

  getMoviesPhase1() {
    return new Promise(resolve => {
      this.http.get(this.apiUrl+'/51602?api_key=9e493b8e1d5cda98bb97c77029b786a0&language=en-US&append_to_response=images&include_image_language=en,null')
        .subscribe(data => {
          this.data = data.items;
          resolve(this.data);
          console.log(data);
      });
    });
  }

  getMoviesPhase2() {
    return new Promise(resolve => {
      this.http.get(this.apiUrl+'/51605?api_key=9e493b8e1d5cda98bb97c77029b786a0&language=en-US&append_to_response=images&include_image_language=en,null')
        .subscribe(data => {
          this.data = data.items;
          resolve(this.data);
          console.log(data);
      });
    });
  }

  getMoviesPhase3() {
    return new Promise(resolve => {
      this.http.get(this.apiUrl+'/51781?api_key=9e493b8e1d5cda98bb97c77029b786a0&language=en-US&append_to_response=images&include_image_language=en,null')
        .subscribe(data => {
          this.data = data.items;
          resolve(this.data);
          console.log(data);
      });
    });
  }
}

Here is my home.ts

import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';
import { ViewChild } from '@angular/core';
import { Slides } from 'ionic-angular';
import { ItemDetailPage } from '../item-detail/item-detail';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/toPromise';

import { MovieServiceProvider } from '../../providers/movie-service/movie-service';

@Component({
  selector: 'page-home',
  templateUrl: 'home.html',
  providers: [MovieServiceProvider]
})

export class HomePage {
  @ViewChild(Slides) slides: Slides;

  public moviesPhase1: any;
  public moviesPhase2: any;
  public moviesPhase3: any;  

  constructor(public navCtrl: NavController, public MovieServiceProvider: MovieServiceProvider) {
    this.getMoviesPhase1();
    this.getMoviesPhase2();
    this.getMoviesPhase3();
  }


  getMoviesPhase1() {
    this.MovieServiceProvider.getMoviesPhase1()
    .then(data => {
      this.moviesPhase1 = data;
    });
  }

  getMoviesPhase2() {
    this.MovieServiceProvider.getMoviesPhase2()
    .then(data => {
      this.moviesPhase2 = data;
    });
  }

  getMoviesPhase3() {
    this.MovieServiceProvider.getMoviesPhase3()
    .then(data => {
      this.moviesPhase3 = data;
    });
  }

  viewItemPhase1(movie){
    this.navCtrl.push(ItemDetailPage, {
      movie:movie
    });
  }

  viewItemPhase2(movie){
    this.navCtrl.push(ItemDetailPage, {
      movie:movie
    });
  }

  viewItemPhase3(movie){
    this.navCtrl.push(ItemDetailPage, {
      movie:movie
    });
  }

  ionViewDidLoad() {

  }

}

And ofcourse my home.html

<ion-content padding>

  <h2>Phase 1</h2>
  <ion-slides slidesPerView="2">
    <ion-slide *ngFor="let movie of moviesPhase1">
      <ion-card (click)="viewItemPhase1(movie)">
        <img src="https://image.tmdb.org/t/p/w500{{movie.poster_path}}"/>
        <ion-card-content>
          <ion-card-title>
            <span>{{movie.original_title}}</span>
            </ion-card-title>

        </ion-card-content>
      </ion-card>
    </ion-slide>
    </ion-slides>

    <h2>Phase 2</h2>
    <ion-slides slidesPerView="2">
      <ion-slide *ngFor="let movie of moviesPhase2">
        <ion-card (click)="viewItemPhase2(movie)">
          <img src="https://image.tmdb.org/t/p/w500{{movie.poster_path}}"/>
          <ion-card-content>
            <ion-card-title>
              <span>{{movie.original_title}}</span>
            </ion-card-title>
          </ion-card-content>
        </ion-card>
      </ion-slide>
      </ion-slides>

      <h2>Phase 3</h2>
      <ion-slides slidesPerView="2">
        <ion-slide *ngFor="let movie of moviesPhase3">
          <ion-card (click)="viewItemPhase2(movie)">
            <img src="https://image.tmdb.org/t/p/w500{{movie.poster_path}}"/>
            <ion-card-content>
              <ion-card-title>
                <span>{{movie.original_title}}</span>
              </ion-card-title>
            </ion-card-content>
          </ion-card>
        </ion-slide>
        </ion-slides>  
</ion-content>

I get the feeling that I need to declare the items variable in an other way. But again i'm very new to this so excuse me for any rookie mistakes. I really hope you could help me out, it would be much appreciated!


Solution

  • If you don't provide a type to your requests, the compiler must assume that it is an Object that is returned.

    Try using this for your requests :

    this.http.get<any>(URL)
    

    Or this

    this.http.get(URL).subscribe((data: any) => {...})
    

    Or even both :

    this.http.get<any>(URL).subscribe((data: any) => {...})
    

    This way, you type your response, and the compiler doesn't try to find the item property on the Object type.