0

I am trying to get data from api , tested my api in post man everythinh works fine, I just want to display all movies returnen in get/movies end point. here is what i have done so far:

sevices component:

import { Injectable } from '@angular/core';
import { Headers, Http, Response } from '@angular/http';

@Injectable({
  providedIn: 'root'
})
export class MoviesService {

  private apiUrl = 'http://localhost:8000/movies';

  constructor(private http: Http) { }
getMovies(): Promise<any> {
      return this.http.get(this.apiUrl)
                 .toPromise()
                 .then(this.handleData)
                 .catch(this.handleError);
  }
private handleData(res: any) {
       const body = res.json();
       console.log(body); // for development purposes only
       return body || {};
   }
private handleError(error: any): Promise<any> {
     console.error('An error occurred', error); // for development purposes only
     return Promise.reject(error.message || error);
 }
}

in component here is what I have:

import { Component, OnInit } from '@angular/core';
import { Http } from '@angular/http';
import { Location } from '@angular/common';
import { MoviesService } from '../movies.service';

@Component({
  selector: 'app-movies',
  templateUrl: './movies.component.html',
  styleUrls: ['./movies.component.scss']
})
export class MoviesComponent implements OnInit {
  public movies: any;

  public constructor(private http: Http, private location: Location, private moviesService: MoviesService) {
      this.movies = [];
  }

  ngOnInit(): void {
    this.location.subscribe(() => {
      this.moviesService.getMovies();
  });
  this.moviesService.getMovies();
  }

}

when i run my app i get the following error:

movies.service.ts:24 An error occurred SyntaxError: Unexpected token J in JSON at position 0
    at JSON.parse (<anonymous>)
    at Response.push../node_modules/@angular/http/fesm5/http.js.Body.json (http.js:705)
    at push../src/app/movies.service.ts.MoviesService.handleData (movies.service.ts:19)
    at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invoke (zone.js:388)
    at Object.onInvoke (core.js:3671)
    at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invoke (zone.js:387)
    at Zone.push../node_modules/zone.js/dist/zone.js.Zone.run (zone.js:138)
    at zone.js:872
    at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:421)
    at Object.onInvokeTask (core.js:3662)
push../src/app/movies.service.ts.MoviesService.handleError @ movies.service.ts:24
push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invoke @ zone.js:388
onInvoke @ core.js:3671
push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invoke @ zone.js:387
push../node_modules/zone.js/dist/zone.js.Zone.run @ zone.js:138
(anonymous) @ zone.js:872
push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask @ zone.js:421
onInvokeTask @ core.js:3662
push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask @ zone.js:420
push../node_modules/zone.js/dist/zone.js.Zone.runTask @ zone.js:188
drainMicroTaskQueue @ zone.js:595
push../node_modules/zone.js/dist/zone.js.ZoneTask.invokeTask @ zone.js:500
invokeTask @ zone.js:1540
globalZoneAwareCallback @ zone.js:1566
error (async)
customScheduleGlobal @ zone.js:1666
push../node_modules/zone.js/dist/zone.js.ZoneDelegate.scheduleTask @ zone.js:407
push../node_modules/zone.js/dist/zone.js.Zone.scheduleTask @ zone.js:232
push../node_modules/zone.js/dist/zone.js.Zone.scheduleEventTask @ zone.js:258
(anonymous) @ zone.js:1831
desc.set @ zone.js:1244
WebSocketTransport @ sockjs.js:2974
SockJS._connect @ sockjs.js:828
SockJS._receiveInfo @ sockjs.js:802
g @ sockjs.js:66
EventEmitter.emit @ sockjs.js:86
(anonymous) @ sockjs.js:567
g @ sockjs.js:66
EventEmitter.emit @ sockjs.js:86
(anonymous) @ sockjs.js:374
g @ sockjs.js:66
EventEmitter.emit @ sockjs.js:86
xhr.onreadystatechange @ sockjs.js:1593
wrapFn @ zone.js:1188
push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask @ zone.js:421
push../node_modules/zone.js/dist/zone.js.Zone.runTask @ zone.js:188
push../node_modules/zone.js/dist/zone.js.ZoneTask.invokeTask @ zone.js:496
invokeTask @ zone.js:1540
globalZoneAwareCallback @ zone.js:1566
XMLHttpRequest.send (async)
scheduleTask @ zone.js:2969
push../node_modules/zone.js/dist/zone.js.ZoneDelegate.scheduleTask @ zone.js:407
push../node_modules/zone.js/dist/zone.js.Zone.scheduleTask @ zone.js:232
push../node_modules/zone.js/dist/zone.js.Zone.scheduleMacroTask @ zone.js:255
scheduleMacroTaskWithCurrentZone @ zone.js:1114
(anonymous) @ zone.js:3001
proto.(anonymous function) @ zone.js:1394
AbstractXHRObject._start @ sockjs.js:1601
(anonymous) @ sockjs.js:1490
push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask @ zone.js:421
push../node_modules/zone.js/dist/zone.js.Zone.runTask @ zone.js:188
push../node_modules/zone.js/dist/zone.js.ZoneTask.invokeTask @ zone.js:496
ZoneTask.invoke @ zone.js:485
timer @ zone.js:2054
setTimeout (async)
scheduleTask @ zone.js:2075
push../node_modules/zone.js/dist/zone.js.ZoneDelegate.scheduleTask @ zone.js:407
push../node_modules/zone.js/dist/zone.js.Zone.scheduleTask @ zone.js:232
push../node_modules/zone.js/dist/zone.js.Zone.scheduleMacroTask @ zone.js:255
scheduleMacroTaskWithCurrentZone @ zone.js:1114
(anonymous) @ zone.js:2090
proto.(anonymous function) @ zone.js:1394
AbstractXHRObject @ sockjs.js:1489
XHRLocalObject @ sockjs.js:2910
InfoAjax @ sockjs.js:356
InfoReceiver._getReceiver @ sockjs.js:536
InfoReceiver.doXhr @ sockjs.js:556
(anonymous) @ sockjs.js:525
push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask @ zone.js:421
push../node_modules/zone.js/dist/zone.js.Zone.runTask @ zone.js:188
push../node_modules/zone.js/dist/zone.js.ZoneTask.invokeTask @ zone.js:496
ZoneTask.invoke @ zone.js:485
timer @ zone.js:2054
setTimeout (async)
scheduleTask @ zone.js:2075
push../node_modules/zone.js/dist/zone.js.ZoneDelegate.scheduleTask @ zone.js:407
push../node_modules/zone.js/dist/zone.js.Zone.scheduleTask @ zone.js:232
push../node_modules/zone.js/dist/zone.js.Zone.scheduleMacroTask @ zone.js:255
scheduleMacroTaskWithCurrentZone @ zone.js:1114
(anonymous) @ zone.js:2090
proto.(anonymous function) @ zone.js:1394
InfoReceiver @ sockjs.js:524
SockJS @ sockjs.js:730
initSocket @ socket.js:9
(anonymous) @ client?719c:211
./node_modules/webpack-dev-server/client/index.js?http://0.0.0.0:0 @ vendor.js:84316
__webpack_require__ @ bootstrap:76
0 @ main.ts:12
__webpack_require__ @ bootstrap:76
checkDeferredModules @ bootstrap:43
webpackJsonpCallback @ bootstrap:30
(anonymous) @ main.js:1
core.js:1542 ERROR Error: Uncaught (in promise): Unexpected token J in JSON at position 0
    at resolvePromise (zone.js:814)
    at resolvePromise (zone.js:771)
    at zone.js:873
    at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:421)
    at Object.onInvokeTask (core.js:3662)
    at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:420)
    at Zone.push../node_modules/zone.js/dist/zone.js.Zone.runTask (zone.js:188)
    at drainMicroTaskQueue (zone.js:595)
    at ZoneTask.push../node_modules/zone.js/dist/zone.js.ZoneTask.invokeTask [as invoke] (zone.js:500)

rensponse:

SONP_CALLBACK({page: 1, total_results: 364974, total_pages: 18249, results: [,…]})
page
:
1
results
:
[,…]
0
:
{vote_count: 595, id: 351286, video: false, vote_average: 6.7, title: "Jurassic World: Fallen Kingdom",…}
1
:
{vote_count: 2250, id: 383498, video: false, vote_average: 7.7, title: "Deadpool 2",…}
2
:
{vote_count: 6772, id: 284053, video: false, vote_average: 7.4, title: "Thor: Ragnarok",…}
3
:
{vote_count: 4857, id: 299536, video: false, vote_average: 8.4, title: "Avengers: Infinity War",…}
4
:
{vote_count: 1628, id: 338970, video: false, vote_average: 6.2, title: "Tomb Raider",…}
5
:
{vote_count: 11073, id: 135397, video: false, vote_average: 6.5, title: "Jurassic World",…}
6
:
{vote_count: 24, id: 525102, video: false, vote_average: 3.7, title: "Girl Lost",…}
7
:
{vote_count: 9056, id: 297762, video: false, vote_average: 7.2, title: "Wonder Woman",…}
8
:
{vote_count: 6114, id: 284054, video: false, vote_average: 7.3, title: "Black Panther",…}
9
:
{vote_count: 917, id: 348350, video: false, vote_average: 6.8, title: "Solo: A Star Wars Story",…}
10
:
{vote_count: 157, id: 402900, video: false, vote_average: 6.8, title: "Ocean's 8",…}
11
:
{vote_count: 13447, id: 118340, video: false, vote_average: 7.9, title: "Guardians of the Galaxy",…}
12
:
{vote_count: 2070, id: 337167, video: false, vote_average: 6, title: "Fifty Shades Freed",…}
13
:
{vote_count: 39, id: 260513, video: false, vote_average: 6.9, title: "Incredibles 2",…}
14
:
{vote_count: 641, id: 449176, video: false, vote_average: 8.3, title: "Love, Simon",…}
15
:
{vote_count: 9272, id: 10195, video: false, vote_average: 6.7, title: "Thor", popularity: 68.281475,…}
16
:
{vote_count: 0, id: 482560, video: false, vote_average: 0, title: "Covet: The Island of Desire",…}
17
:
{vote_count: 7119, id: 76338, video: false, vote_average: 6.7, title: "Thor: The Dark World",…}
18
:
{vote_count: 849, id: 268896, video: false, vote_average: 5.9, title: "Pacific Rim: Uprising",…}
19
:
{vote_count: 4733, id: 141052, video: false, vote_average: 6.3, title: "Justice League",…}
total_pages
:
18249
total_results
:
364974

what am I doing wrong here? any help will be apreciated

Hot Zellah
  • 1,061
  • 3
  • 11
  • 21
  • Well what does the JSON look like? – Pointy Jun 15 '18 at 21:40
  • ```handleData``` and ```handleError``` have one argument you are passing none . – Fateme Fazli Jun 15 '18 at 21:40
  • Does your API return JSON, or something else? – R. Richards Jun 15 '18 at 21:41
  • @Pointy here u can check it its just for learning purpose https://api.themoviedb.org/3/movie/401478/reviews?api_key=4d9c9de3bdf0d3b6837c49c086e3b190'; – Hot Zellah Jun 15 '18 at 21:42
  • No I mean the *actual* JSON in the *actual* response when you get that error. That's where the problem is. – Pointy Jun 15 '18 at 21:43
  • @R.Richards json check above link the api – Hot Zellah Jun 15 '18 at 21:44
  • 2
    @HotZellah Can you check in the browsers network tab in the developer tools, and paste exactly what is being returned from your service please? – user184994 Jun 15 '18 at 21:47
  • @Pointy if I udnerstood your question here is more from that error movies.service.ts:24 An error occurred SyntaxError: Unexpected token J in `JSON at position 0 at JSON.parse () at Response.push../node_modules/@angular/http/fesm5/http.js.Body.json (http.js:705)` – Hot Zellah Jun 15 '18 at 21:47
  • 2
    No that's not the question. That error is telling you that some JSON content your code expects is not valid. Thus without actually seeing that response text, it's impossible to say more than that. – Pointy Jun 15 '18 at 21:49
  • @user184994 check the update in my question posted the whole error – Hot Zellah Jun 15 '18 at 21:51
  • Click on the row/request in the network tab, on the right side you'll see detail tabs, click the response tab and show us what is in the response. – shaunhusain Jun 15 '18 at 21:52
  • @HotZellah Still not what we're looking for...It's not the error we want to see, we want to see the JSON that it's trying to parse. Please check in the browsers developer tools otherwise no one can help – user184994 Jun 15 '18 at 21:53
  • Unfortunately you're still not understanding what I and others are asking for. Your browser has a "Network" tab in the developer tools. That will show you exactly what response content is returned from your HTTP request. That's where you'll have to look to find what's causing the error. The error message itself is not enough (other than to indicate what you need to look for). – Pointy Jun 15 '18 at 21:53
  • Have you tried deleting the line "const body = res.json();" This looks familiar, but I can't find the documentation. If I remember right, the default data type for a Promise is now json, so calling the .json() on it, actually causes an error. – Marco Rosas Jun 15 '18 at 21:58
  • @MarcoRosas The default response type for `HttpClient` is now JSON, but this is still using the older `Http`, so it is necessary. – user184994 Jun 15 '18 at 22:00
  • 1
    @Pointy check now the question update : i posted the rensponse from browser as u asked – Hot Zellah Jun 15 '18 at 22:03

1 Answers1

4

The response is not JSON, it's JSONP. That means it is not valid JSON, hence the parsing error.

You are calling the software in a way that returns JSONP. If that is the default return type you need to change it to be normal JSON, so that you can parse it as you have coded. If that's not possible, perhaps because you don't control the backend and can't add CORS headers, you need to either change your logic to actively work with JSONP (meaning you create a global function with the name JSONP_CALLBACK - usually configurable through a parameter to allow multiple simultaneous calls) or work around it. If JSONP is used because the API server is on another domain and doesn't set CORS, then there's not much you can do. But if CORS headers are set or the API endpoint is on the same domain you can simply replace the function call bit using a regex and just be left with a regular JSON object you can parse normally.

If you don't know wtf JSONP is you should read this article. It's basically a hack from 2010-ish that's no longer needed with modern browsers and CORS.

Angular has built-in support for JSONP through the $http.jsonp() method. If you need explicit help on how to do this using Angular then see this answer.

oligofren
  • 20,744
  • 16
  • 93
  • 180
  • your right in backend its using JSONP_CALLBACK , I will change now if it works I will accept your answer just a minute – Hot Zellah Jun 15 '18 at 22:15
  • Remember the function needs to be global - not local (hidden from the global scope). Btw, jQuery has support for JSONP built-in. If not, you need to `eval` the response. – oligofren Jun 15 '18 at 22:20
  • Here's an answer on how to do this using Angular: https://stackoverflow.com/a/13400409/200987 – oligofren Jun 15 '18 at 22:22
  • here iw hat i have changed `private apiUrl = 'http://localhost:8000/movies'; constructor(private http: Http, private _jsonp: Jsonp) { } getMovies(): Promise { return this._jsonp.get(this.apiUrl) .toPromise() .then(this.handleData) .catch(this.handleError); } private handleData(res: any) { const body = res.json(); console.log(body); // for development purposes only return body || {}; }` stil get error: Error: StaticInjectorError(AppModule)[MoviesService -> Jsonp]: – Hot Zellah Jun 15 '18 at 22:32
  • I don't see how that should work. You need to specify what the callback parameter is called. Check that first. You need it. It defaults to `callback`. As in `$http.jsonp('some/trusted/url', {jsonpCallbackParam: 'callback'})`. Please read the two links if you are not sure what I mean. – oligofren Jun 15 '18 at 22:38
  • am using angular 6 all those provided answer does not work, I dont know what to do next am newbie to this stuff if you can help i will apreciate – Hot Zellah Jun 15 '18 at 22:53
  • 1
    Thanks , works now , just changed callback in backend with or without callback works, thanks again – Hot Zellah Jun 16 '18 at 00:29