keeroll
keeroll

Reputation: 33

uncaught typeerror cannot read property 'touppercase' of undefined Observable._subscribe

I have an issue. I develop mobile app with ionic framework. It's movie app. I found one example on github and tried to implement some functions and design into my project.

I have the page 'Store'. When I start the project I get the error

Uncaught (in promise): TypeError: Cannot read property 'toUpperCase' of undefined TypeError: Cannot read property 'toUpperCase' of undefined at Observable._subscribe

It come from ngOnInit function, but I can't see what is wrong. I just recently started to learn mobile development with ionic framework, ts and angular. I will be glad for any help.

import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';
import { MovieService } from '../../services/movie-service';
import { MovieDetailsPage } from '../movie-details/movie-details';

@Component({
  selector: 'page-store',
  templateUrl: 'store.html'
})
 export class StorePage {

  movies: Array<any>;

     constructor(public navCtrl: NavController, private movieService: 
 MovieService) {

     }

     ngOnInit(){
        this.movieService.send('getMovies').subscribe(a => {
            console.log(a);
            this.movies = a.results.map(b => {
                return {
                    id: b.id,
                    title: b.title,
                    image: b.poster_path,
                    overview: b.overview,
                    rating: b.vote_average
                }
            })
        });
     }

     searchMovieDB(event, key) {
         if(event.target.value.length > 2) {
             this.movieService.searchMovies(event.target.value).subscribe(
                 data => {
                     this.movies = data.results; 
                     console.log(data);
                 },
                 err => {
                     console.log(err);
                 },
                 () => console.log('Movie Search Complete')
              );
         }
     } 

     itemTapped(event, movie) {
         //console.log(movie);
         this.movieService.send('getSingleMovie', movie.id).subscribe(data 
  => console.log(data));  
         this.navCtrl.push(MovieDetailsPage, {
             movie: movie
         });
     }

 }

Here is 'MovieService' which I use to create api requests:

import { Injectable } from '@angular/core';
import {Http, Headers, RequestMethod, Request} from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';

@Injectable()
export class MovieService {

    constructor(private http:Http) {

    }

    searchMovies(movieName) {
        var url = 'http://api.themoviedb.org/3/search/movie?query=&query=' + 
encodeURI(movieName) + '&api_key=xxxxxxxxxxxxxxxxxx';

        var response = this.http.get(url).map(res => res.json());
        return response;
    }

    send(name, id?, item?) {

                let url: string,
                    body: any,
                    api_key: string = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxx';

                if(name == 'getMovies')
                    url = 'http://api.themoviedb.org/3/movie/'+id+'?
api_key=' + api_key;
                else if (name == 'getMoviesByPage')
                    url = 'http://api.themoviedb.org/3/movie/popular?
api_key='+api_key+'&page=' + id;
                else if (name == 'getSingleMovie')
                    url = 'https://api.themoviedb.org/3/movie/'+id+'?
api_key=' + api_key;
                else if (name == 'getVideo')
                    url = 'https://api.themoviedb.org/3/movie/'+id+'/videos?
api_key=' + api_key;
                else if (name == 'getImages')
                    url = 'https://api.themoviedb.org/3/movie/'+id+'/images?
api_key=' + api_key;


                let options = {
                    url: url,
                    body: null
                };

                if (item) {
                    body = typeof item === 'string' ? item : 
 JSON.stringify(item);
                    options.body = body;
                }


                return this.http.request(new Request(options))
                    .map(res => res.json())

            }
}

Upvotes: 1

Views: 731

Answers (1)

AVJT82
AVJT82

Reputation: 73367

The problem is when you are using Request (which is deprecated along with Http by the way). You would want to just make get request, nothing else needed really. I see some problems in your code, for example when getting a single movie based on id, your app would throw an error at the mapping inside subscribe, since the data you would get back from fetching one movie would just return an object, not an array. So you need to rethink that!

But here's a sample with getting one movie based on id:

send(name, id?, item?) {
  let url: string,
  api_key: string = 'xxxxxxxxxxxxxxxxxxxxxxx';

  if (name == 'getMovies') 
    url = 'https://api.themoviedb.org/3/movie/' + id + '?api_key=' + api_key

  return this.http.get(url)
    .map(res => res.json())
}

Component:

ngOnInit() {
  this.movieService.send('getMovies').subscribe(a => {
    this.movies = a // will not be an array in this case, just an object! 
  });
}

Upvotes: 0

Related Questions