0

I'm getting an error with a reactive extension (rx) Observable subscribe operator and not seeing why. It seems that the same code in tutorials I've done works fine, but for some reason I'm getting an error working with an actual API.

getChannelVideos(channelId: string): Observable<any>{
  var url = `${this._baseUrl}/channels/${channelId}/videos`;

  return this._jsonp.get(url).map(response => response.json());
}

// url https://api.twitch.tv/kraken/channels/khaldor/videos

In my component, I call that service function in ngOnInit.

ngOnInit(){
  this._twitchService.getChannelVideos('khaldor')
    .subscribe(response => console.log(response));
}

In the network tab, I get a 200 response with a JSON object

{"_total":2,
  "_links":{...}, 
  "videos": {...} 
}

In the console, I get an error videos:1 Uncaught SyntaxError: Unexpected token : which references the first semi-colon in the returned JSON response.

I've tried removing the .map in the service, but I get the same error when applying .subscribe() to the Observable object in the component.

awwester
  • 9,623
  • 13
  • 45
  • 72

1 Answers1

1

I think that your address isn't JSONP-compliant. If it's the case, you need to provide the JSONP_CALLBACK value to the callback query parameter. Something like that:

getChannelVideos(channelId: string): Observable<any>{
  var url = `${this._baseUrl}/channels/${channelId}/videos?callback=JSONP_CALLBACK`;

  return this._jsonp.get(url).map(response => response.json());
}

The callback is a sample and depends on the service.

If your service supports CORS, you could leverage the Http class instead:

constructor(private http:Http) {}

getChannelVideos(channelId: string): Observable<any>{
  var url = `${this._baseUrl}/channels/${channelId}/videos`;

  return this.http.get(url).map(response => response.json());
}
Thierry Templier
  • 198,364
  • 44
  • 396
  • 360
  • if it wasn't JSONP compliant would it be returning data? When I used the Http service it gave me the typical error when making CORS requests without CORS enabled. I switched to JSONP (they say it's compliant), and I get data back from the request, in the Network tab. – awwester Jun 13 '16 at 17:04
  • If the service is JSONP, that's fine. The problem is that you don't specify a callback name, so the response is simple JSON but not wrapped in a function call. Something like that: `callback([ { name: 'test' }, ... ]);`. Because JSONP relies on a dynamic script element added to execute the request, the response must follow this... – Thierry Templier Jun 13 '16 at 17:38
  • Here are two samples: http://stackoverflow.com/questions/36289495/how-to-make-a-simple-jsonp-asynchronous-request-in-angular-2/36289568#36289568 and http://stackoverflow.com/questions/35180562/i-need-to-do-a-http-request-to-a-mail-chimp-subscription-list-via-a-component-po/35181085#35181085. – Thierry Templier Jun 13 '16 at 17:39
  • You need to find out which query parameter to use to provide the callback name... – Thierry Templier Jun 13 '16 at 17:40
  • thanks, first time working with JSONP and that confused me. Now I see it in the docs. – awwester Jun 13 '16 at 19:00
  • No problem! It's actually not so obvious! – Thierry Templier Jun 13 '16 at 19:04