I've found a couple of similar posts to this, but the answers (which boil down to putting callback=JSONP_CALLBACK
into the get request) aren't working for me. Using that in the request generates an immediate 404 error, while using callback=angular.callbacks._0
at least lets the first request return a successful response. The problem is that using the very same request function with the very same params a second time to refresh the data or get the next 20 objects, returns a 404 error even though the actual get returns a 200 and the data can be seen in chrome tools.
I'm, new to using $q deferred promises, so I'm hoping that the issue has something to do with that not allowing enough time for a response before executing the reject. I'm attaching the code, which involves the Yelp API as did the other couple of posts I found on this issue. The most closely related is: (Subsequent JSONP requests give status 404 despite GET status 200), but there's another which uses the same callback string I'm using (Yelp API and AngularJS).
This particular project is for an ionic mobile app that gets coffee shops based on users geolocation.
Here's the code for the service (secret stuff removed):
var app = angular.module('caffeine.services', []);
app.service("YelpService", function ($q, $http, $cordovaGeolocation, $ionicPopup) {
function randomString(length, chars) {
var result = '';
for (var i = length; i > 0; --i) result += chars[Math.round(Math.random() * (chars.length - 1))];
return result;
};
var method = 'GET';
var url = 'http://api.yelp.com/v2/search';
var consumerSecret = ''; //Consumer Secret
var tokenSecret = ''; //Token Secret
var self = {
'page': 1,
'isLoading': false,
'hasMore': true,
'results': [],
'ranStr': randomString(32, '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'),
'timeStamp':new Date().getTime(),
'lat': 51.544440,
'lon': -0.022974,
'term': 'coffee',
'oauthConKey': '', //Consumer Key
'oauthToken': '', //Token
'oauthSigMeth': 'HMAC-SHA1',
'refresh': function () {
self.page = 1;
self.isLoading = false;
self.hasMore = true;
self.results = [];
return self.load();
},
'next': function () {
self.page += 1;
return self.load();
},
'load': function () {
self.isLoading = true;
var deferred = $q.defer();
ionic.Platform.ready(function() {
$cordovaGeolocation
.getCurrentPosition({timeout:10000, enableHighAccuracy:false})
.then(function(position){
self.lat = position.coords.latitude;
self.lon = position.coords.longitude;
console.log('latlong = '+self.lat+','+self.lon);
var params = {
callback: 'angular.callbacks._0',
page: self.page,
ll: self.lat+','+self.lon,
term: self.term,
oauth_consumer_key: self.oauthConKey, //Consumer Key
oauth_token: self.oauthToken, //Token
oauth_signature_method: self.oauthSigMeth,
oauth_timestamp: self.timeStamp,
//new Date().getTime(),
oauth_nonce: self.ranStr
};
var signature = oauthSignature.generate(method, url, params, consumerSecret, tokenSecret, { encodeSignature: false});
params['oauth_signature'] = signature;
console.log('url ='+url);
console.log('params.ll = '+params.ll);
$http.jsonp(url, {params: params}).success(function (callback) {
self.isLoading = false;
console.log(callback.businesses);
if (callback.businesses.length == 0) {
self.hasMore = false;
} else {
angular.forEach(callback.businesses, function (business) {
self.results.push(business);
});
}
self.isLoading = false;
deferred.resolve(callback.businesses);
})
.error( function (callback, status, headers, config) {
self.isLoading = false;
console.error('data not received');
console.error('data: '+callback);
console.error('status: '+status);
console.error('headers: '+headers);
console.error('congig: '+config);
deferred.reject(callback);
});
}, function(err) {
console.error('Error getting position');
console.error(err);
$ionicPopup.alert({
'title': 'Please turn on geolocation',
'template': 'It looks like you have geolocation turned off. Please turn on geolocation in your app settings to use this app.'
});
})
});
return deferred.promise;
}
};
self.load();
return self;
});