10

I might be missing something here but I can't make this JSONP request work, here is the code:

var url =  'http://' + server + '?callback=JSON_CALLBACK';
$http.jsonp(url)
    .success(function(data){
       console.log('success');
    })
    .error(function () {
      console.log('error')
    });

The request fires ok and I am getting the response (with header Content-Type:application/json) in this format:

    [{"id": "1", "name": "John Doe"},
     {"id": "2", "name": "Lorem ipsum"},
     {"id": "3", "name": "Lorem ipsum"}]

Can you see anything wrong? Maybe the format I should return from the server is not right? Angular fires the error callback without any error message besides the one I set ('error').

Bertrand
  • 13,340
  • 5
  • 37
  • 48

3 Answers3

30

@TheHippo is correct the data should not just be a plain json response. Here is a working example of a JSONP request against a youtube endpoint in AngularJS.

A couple of things to note in this example:

  • Angular's $http.jsonp converts the request querystring parameter from callback=JSON_CALLBACK to callback=angular.callbacks._0.
  • When calling the youtube endpoint I needed to specify to the service that this is a JSONP request by using alt=json-in-script instead of alt=json in the querystring. This was found in their documentation.
  • Compare the results of this url to this one to see the difference between JSON and JSONP response in your browser.
  • Take a look at the Chrome Network Panel in Developer Tools to help compare and troubleshoot with your request/response.

I know this example is very specific but hopefully it helps!

Gloopy
  • 37,557
  • 15
  • 101
  • 71
  • Thanks TheHippo! Very useful comments. – Bertrand May 03 '13 at 10:17
  • @Gloopy - Useful info and example jsfiddle very helpful for debugging my code, thanks very much. – Nick Jun 27 '13 at 21:11
  • Finally a solution that works! Was running into this problem using smartthings just to drop the keyword here. – Karoh Feb 08 '15 at 05:00
  • Unfortunately the Youtube service utilized for this example no longer works. http://stackoverflow.com/a/30685729/1014710 shows that it can be done with an Google Developers API key. – Johnathan Elmore Nov 29 '15 at 15:48
16

JSONP requires you do wrap your data into a JavaScript function call. So technically you return a JavaScript file and not a Json file.

The data returned from server should similar to this:

// the name should match the one you add to the url
JSON_CALLBACK([
    {"id": "1", "name": "John Doe"},
    {"id": "2", "name": "Lorem ipsum"},
    {"id": "3", "name": "Lorem ipsum"}
]);

Edit: If some one else stumbles across problems with angular's JSONP please also read this answer to this question, it contains usefull informations about how angular handles the actual callback function.

Community
  • 1
  • 1
TheHippo
  • 54,987
  • 13
  • 72
  • 98
  • 3
    Solved! Thanks. TheHippo if you could edit your answer to include what @Gloopy commented: "Angular's $http.jsonp converts the request querystring parameter from callback=JSON_CALLBACK to callback=angular.callbacks._0", so the response is not exactly JSON_CALLBACK() but angular.callbacks._0([ {"id":"1", "name":"John Doe"}, {"id":"2", "name":"Lorem ipsum"}]); If there is more than one request the second jsonp convert the request querystring callback=JSON_CALLBACK to angular.callbacks._1 and so forth, so in my case (PHP server) I am using $_GET['callback']to get the right callback name. – Bertrand May 03 '13 at 10:16
-3

If the response data is "pure" JSON, we can just handle it with angular's $http.get.

$http.get(url).
  then(function(response) {
    // this callback will be called asynchronously
    // when the response is available
    $scope.responseArray = response.data;
 }, function(response) {
    // called asynchronously if an error occurs
    // or server returns response with an error status.
 });

Refer to the example on w3schools

bjc
  • 103
  • 2