Getting `Unexpected token :` in angularjs but cannot use callback - json

I'm trying to query the Spotify Metadata API with AngularJS but I keep running into the following error.
Uncaught SyntaxError: Unexpected token :
Now I know typically when querying you should add callback=JSON_CALLBACK as a query string but in this case it won't work. It returns:
Failed to load resource: the server responded with a status of 400 (Bad Request)
I am using $http.jsonp().
Example without callback | Example with callback
So, is there a way around this using pure Javascript or I'm best add a server-side wrapper (which I've got working but rather if it was pure Javascript)?

It doesn't seem like Spotify is providing jsonp support, but they do support CORS - so this should work:
function spotify_api($http) {
var url = "http://ws.spotify.com/lookup/1/.json?uri=spotify:track:5PJSqY8jbYzr4a6dl5Ory1";
//CORS support
delete $http.defaults.headers.common['X-Requested-With'];
$http.get(url).success(function(data) {
console.log(data);
});
}
See my update: http://jsfiddle.net/69kYH/
The bad news is that CORS doesn't seem to work properly in angular with older versions of IE - see AngularJS - Calling Flickr API fails with warning message

Related

SyntaxError: Unexpected token < in JSON at position 0

SyntaxError: Unexpected token < in JSON at position 0
while retrieving json data using ionic 2
here is the link http://areeef.unaux.com/php/platforms.php
here is the code i am using to get json data
constructor( public navCtrl: NavController, private http: Http) {
this.http.get('http://areeef.unaux.com/php/platforms.php').map(res => res.json()).subscribe(data => {
console.log(data);
}); }
when i run the same php code in local host then i can run the app without any error. but in online sever it is giving the error mentioned above
so is that a problem of the server or error in my code?
Nothing seems wrong with the code. The problem is because your server not returning valid JSON.
Check the API's behaviour using postman plugin. I have checked it and it returning invalid JSON-
This site requires Javascript to work, please enable Javascript in
your browser or use a browser with Javascript support
So, get your api working on postman first.
This error is normally caused by the server returning non JSON data. In this case, the PHP script could be returning an error message in form of HTML which will cause an error. The best approach for such errors is to debug the PHP script independently or accommodate the possibility of getting both html and JSON data on the client side.

unexpected token : from angular $http.jsonp request to Instagram API

I'm making a request to an authorized Instagram account to display images on a site. Originally, I was running into No 'Access-Control-Allow-Origin' when using Angular's $http.get(....
From Matt's answer in this question, It seems that I can use getJSON, or Angular $http.jsonp, to bypass this issue. That Guy's answer also says "JSONP is really a simply trick to overcome XMLHttpRequest same domain policy".
So, I'm no longer getting that problem, and am getting a json payload:
{"pagination":{"next_url":"https:\/\/api.instagram.com... etc
But am getting a very ambiguous error:
Uncaught SyntaxError: Unexpected token :
This is a response from the Instagram API, so I'm not sure why there'd be a syntax error on the inbound json. Also, It's hard to locate the error since the jsonp response is all on a single line... where the error is reported.
The preview shows that I'm getting a full payload:
I found the issue. Unfortunately there are no JavaScript libraries to help with this, but in the Instagram API docs, for JSONP you can wrap the response with a callback so that the json payload will be wrapped in <script> tags (more info on jsonp here), therefore not blocked by Access Control Allow Origin.
https://api.instagram.com/v1/tags/coffee/media/recent?access_token=ACCESS-TOKEN&callback=callbackFunction
Response:
callbackFunction({
...
});
So, in your http request URI, you add in a callback parameter. Since I am using Angular, their docs for $http.jsonp() requests specify the callback string as "JSON_CALLBACK".
So, my request URL for Angular would be:
$http.jsonp(
'https://api.instagram.com/v1/tags/coffee/media/recent?
access_token=ACCESS-TOKEN&callback=JSON_CALLBACK')
.success(function(data) {...

Not able to fetch the json response through angularjs

Need to fetch the build values from apache.org. So i am using their api
https://builds.apache.org/api/json
I tried angularjs $http.jsonp but not able to fetch the data.
In chrome console under network json api is getting loaded but the data is not getting returned instead it is throwing the response as error.
app.controller("jsoncontroller",function($scope,$http){
var url='https://builds.apache.org/api/json';
$http.jsonp(url).success(function(data){
console.log('success');
})
.error(function () {
console.log('error')
});
});
Getting the error as
Uncaught SyntaxError: Unexpected token :
error
As per the jsonp angular docs, you must append JSON_CALLBACK to the URL: https://builds.apache.org/api/json?jsonp=JSON_CALLBACK
However, that URL doesn't work because even when the callback parameter is specified, the server still sends back a content-type of application/json, instead of the expected application/javascript. This causes it to be parsed (evidently) by the json parser instead of the javascript callback needed for JSONP to work. I'm not versed enough in JSONP or Angular to know who is it fault here.
I've made a fiddle with this working with another URL.
[Update]: The apache build server appears to use Jenkins, which has disable JSONP from the remote API. You can verify this yourself by trying to hit their jsonp endpoint, which returns a 403. You'll have to use another endpoint, no way I can see around this.

Detect malformed/invalid JSON in an AngularJS $http.post() call

As can be seen in AngularJS's source, any $http.post request that returns an HTTP code in the 200-299 range will trigger the success() callback even if the response contains invalid data (like for example invalid JSON).
I'm specifically setting my call's responseType: 'json' and even then the success callback is fired when something else comes back. This is especially annoying in the development server where PHP's display_errors setting is turned on. When something goes wrong server-side and PHP outputs an error message the AngularJS app doesn't detect this and continues happily.
Is there a way to prevent this? I mean, to make the AngularJS app fire the error() callback when the response data is invalid JSON?
Thanks
so your PHP server responds with a 200 error code even on an error? Not knowing PHP, this feels like a server configuration problem to me. I'd expect a 500 error with a payload. That being said, there are two things that I can think of offhand.
$http includes transformResponse handlers you can set up to inspect the response for problems.
$http also includes the concept of "interceptors" which allow you to pick up the response payload and do something with it. You could use an interceptor to "reject" the response.
More information on transformResponse and "interceptors" in the $http documentation:
http://docs.angularjs.org/api/ng.$http

HTTP Status 0 from AngularJS Get for JSON

I'm running a $http.get for a JSON and am getting a status of 0. I've downloaded the same JSON and the get works locally, and in Python using the requests library I can get the JSON no problem, but in AngularJS it's not working. What I don't understand is why angular isn't getting it but everything else is. Code snippet below.
function AgentListCtrl($scope, $http) {
$http.get('http://foo.bar/api/objects').success(function(data) {
$scope.objects = data;
}).error(function(data, status) {
$scope.status1 = status;
});
This provides the JSON and parses it when using a local file, but otherwise it fails and sets status1 to 0.
Just to make this clear since is not directly stated in the above answer (but in its comments) and, like me, some Angular newbies may be spending some time on this:
Angular's $resource will be able to execute a REST verb on another server, which in turn will respond correctly (with a status 200). Angular will nevertheless fail with a cryptical message, identifyiable by the status 0. It is further misleading since, in a browser's debugger, you may actually see the server's answer.
Angular will do an OPTIONS request on a cross-domain request (at least for the default query() method) unless specified on the contrary. Usually the server will not answer with the desired content (i.e. your representation). One simple way of doing this per request is specifying the method to be 'GET'.
$resource('http://yourserver/yourentity/:id', {}, {query: {method: 'GET'});
The server answering your REST requests MUST include the headers specified by CORS [1] in order to allow Angular to consume properly the response. Essentially this means including the Access-Control-Allow-Origin header in your response, specifying the servers from where the request comes from, that are allowed. This value may be *.
Complementing this answer for anyone integrating AngularJS with spring-data-rest-webmvc:
the HATEOAS json formatted response will not be properly consumed by Angular, producing instead the error Expected response to contain an array but got an object. This is solved by adding the isArray: false parameter to the $resouce's configuration;
a very to-the-point example of configuring CORS for the spring-data-rest-webmvc scenario is presented at [2] (see the SimpleCORSFilter)
[1] https://developer.mozilla.org/en/docs/HTTP/Access_control_CORS
[2] https://spring.io/guides/gs/rest-service-cors/
In your code, the status assignment only occurs when the error happens. You should be able to get the status when the call was made successfully like this:
success(function(data, status, headers, config) {
$scope.objects = data;
$scope.status1 = status;
}).error(function(data, status) {
$scope.status1 = status;
});
I was having a similar problem myself. A third party API that returns JSON just fine through every other means was failing with status 0 when called through Angular's $http.get() method.
In my case there wasn't any CORS problem. Instead, the URL I was using for the API was not quite right and the server was issuing a 301 response. Angular wasn't respecting the redirect.
Word to the wise.