Holly
Holly

Reputation: 7752

HTTP JSONP request issue with $http in AngularJS

I get the bellow error when I try to use the JSONP method in angularJS.

Uncaught SyntaxError: Unexpected token : http://example.com/getSomeJson?format=jsonp&json_callback=angular.callbacks._0

What am I doing wrong here, this is my AngularJs controller with the http request:

UPDATED QUESTION DETAILS

See below with code snipit which reproduces my problem, I've commented some of the .js to illustrate what I've tried so far.

var app = angular.module('app', []); 

app.controller('mainController', ['$http', 'mainService', function($http, mainService){

	mainCtrl = this;

	mainCtrl.test = "If you can see this the mainController works"

	var promise = mainService.getJson();
	promise.then(function (data)
	{
		mainCtrl.json = data;
	});
}]);

app.service("mainService", function ($http, $q)
{
		var deferred = $q.defer();
 
    /* 	
    // Method to Grab JSON that has CORs enabled:
    // JSON resource with CORs enabled
	var url = 'https://jsonplaceholder.typicode.com/posts/1';
	$http({
	    method: 'GET',
	    cache: true,
	    url: url,
           headers: {  
           'Content-Type': 'application/json;charset=UTF-8'  
      	}
	}).
	success(function(response) {
	    //your code when success
	    deferred.resolve(response);
	    console.log('HTTP CORS SUCCESS!');
	}).
	error(function(response) {
	    //your code when fails
	    console.log('HTTP CORS ERROR!');
	});
*/	


	/* */
    // Method to Grab JSON that has CORs enabled:
	// JSON resources without CORs enabled
	var url = 'http://run.plnkr.co/plunks/v8xyYN64V4nqCshgjKms/data-1.json' // does not work?
    // var url = 'http://samcroft.co.uk/json-data/sample'  // this one works

	$http({
        method: 'jsonp',
        url: url + '?callback=JSON_CALLBACK',
    }).
	success(function(response) {
	    //your code when success
	    deferred.resolve(response);
	    console.log('JSONP SUCCESS!');
	}).
	error(function(response) {
	    //your code when fails
	    console.log('JSONP ERROR!');
	});


	
	this.getJson = function ()
	{
		return deferred.promise;
	};


});
<!DOCTYPE html>
<html lang="en" ng-app="app">
<head>
	<meta charset="UTF-8">
	<title>Document</title>
	<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.9/angular.min.js"></script>
	<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.9/angular-route.js"></script>
	<script src="app.js"></script>
</head>
<body ng-controller="mainController as mainCtrl">
	<p>{{mainCtrl.test}}</p>
	<hr />
	<p>You should also see the JSON obeject below:</p>
	{{mainCtrl.json}}
</body>
</html>

ORIGIONAL QUESTION DETAILS

app.controller('testController', ['$scope', '$http', function($scope, $http){

    var url = 'http://example.com/getSomeJson';

    $http({
        method: 'JSONP',
        url: url,
        params: {
            format: 'jsonp',
            json_callback: 'JSON_CALLBACK'
        }
    }).
    success(function(data) {
        //your code when success
        $scope.data = data;
        console.log('SUCCESS!');
    }).
    error(function(status) {
        //your code when fails
        console.log('ERROR!');
    });
}]);

When I look at the json in the chromes sources panel I see where the error is highlighted. enter image description here

Any idea what I'm doing wrong? Or could it be an issue with how the API service is configured?

Upvotes: 0

Views: 4961

Answers (2)

Aruna
Aruna

Reputation: 12022

Here you go :-)

The code you tried with the jsonp request looks good but the url you used is not supporting the jsonp request, that's why you got an error.

If you try the same url with $http.get, it will work fine.

To support the jsonp call, the response should be wrapped with the JSON_CALLBACK () as below

JSON_CALLBACK ({ /* JSON */ })

Hence, I changed this to valid jsonp url and it worked!

https://angularjs.org/greet.php?callback=JSON_CALLBACK

You can try this url in the browser and see the response, how it is wrapped with JSON_CALLBACK ().

But if you try the below url, you can just see the json without any wrapping.

http://run.plnkr.co/plunks/v8xyYN64V4nqCshgjKms/data-1.json?callback=JSON_CALLBACK

That's the difference to find whether the api supports jsonp.

Also, I have changed the service below with the same syntax as in another SO question answer,

https://stackoverflow.com/a/41030976/7055233

Working snippet:

var app = angular.module('app', []); 

app.controller('mainController', ['$http', 'mainService', function($http, mainService){

	mainCtrl = this;

	mainCtrl.test = "If you can see this the mainController works"

	var promise = mainService.getJson();
	promise.then(function (data)
	{
		mainCtrl.json = data;
	});
}]);

app.service("mainService", function ($http, $q)
{
    var deferred = $q.defer();
	var url = 'https://angularjs.org/greet.php';
	//var url = 'http://run.plnkr.co/plunks/v8xyYN64V4nqCshgjKms/data-1.json';
 
    /* 	
    // Method to Grab JSON that has CORs enabled:
    // JSON resource with CORs enabled
	var url = 'https://jsonplaceholder.typicode.com/posts/1';
	$http({
	    method: 'GET',
	    cache: true,
	    url: url,
           headers: {  
           'Content-Type': 'application/json;charset=UTF-8'  
      	}
	}).
	success(function(response) {
	    //your code when success
	    deferred.resolve(response);
	    console.log('HTTP CORS SUCCESS!');
	}).
	error(function(response) {
	    //your code when fails
	    console.log('HTTP CORS ERROR!');
	});
*/	


	/* */
    // Method to Grab JSON that has CORs enabled:
	// JSON resource without CORs enabled
  function getJson() {

	// $http.jsonp(url + "?callback=JSON_CALLBACK").  // this does not work either
	$http.jsonp(url + '?callback=JSON_CALLBACK').
	then(function(response) {
	    //your code when success
	    deferred.resolve(response);
	    console.log('JSONP SUCCESS!');
	}, function(response) {
	    //your code when fails
	    console.log('JSONP ERROR!');
        deferred.reject(response);
	});
	
    return deferred.promise;

  }
	
	this.getJson = getJson;


});
<!DOCTYPE html>
<html lang="en" ng-app="app">
<head>
	<meta charset="UTF-8">
	<title>Document</title>
	<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.9/angular.min.js"></script>
	<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.9/angular-route.js"></script>
	<!--<script src="app.js"></script>-->
</head>
<body ng-controller="mainController as mainCtrl">
	<p>{{mainCtrl.test}}</p>
	<hr />
	<p>You should also see the JSON obeject below:</p>
	{{mainCtrl.json}}
</body>
</html>

Upvotes: 1

georgeawg
georgeawg

Reputation: 48968

JSONP callback must be specified by jsonpCallbackParam

BREAKING CHANGE

You can no longer use the JSON_CALLBACK placeholder in your JSONP requests. Instead you must provide the name of the query parameter that will pass the callback via the jsonpCallbackParam property of the config object, or app-wide via the $http.defaults.jsonpCallbackParam property, which is "callback" by default.

-- Added to AngularJS v1.6.0-rc.2


UPDATE

The OPs example code does not work because the http://run.plnkr.co API does not support JSONP.

JSONP is available only on some sites with an API that pre-date ACCESS-CONTROL headers.

For more information, see JSONP Demystified

Upvotes: 0

Related Questions