I'm trying to use JSONP with Restangular. I'm using the Songkick API and when making a GET request I'm receiving no response data from a different domain but locally I receive data no problem.
I've created the following Factory for configuring Restangular and a controller. I'm a little unsure about how to use setDefaultRequestParams. Maybe the configuration is incorrect?
angular
.module('ModuleName')
.factory('RestFactory', Factory);
function Factory (Restangular) {
var factory = {
songkick: songkick
};
return factory;
function songkick () {
return Restangular.withConfig(function(RestangularConfigurer) {
RestangularConfigurer.setJsonp = true;
RestangularConfigurer.setDefaultRequestParams('jsonp', {
callback: 'JSON_CALLBACK'
});
RestangularConfigurer.setDefaultRequestParams('get', {
reason: 'attendance',
apikey: 'xxxxxxxxxx'
});
RestangularConfigurer.setBaseUrl('http://api.songkick.com/api/3.0/');
RestangularConfigurer.setRequestSuffix('.json');
RestangularConfigurer.setDefaultHttpFields({cache: true});
});
}
}
angular
.module('ModuleName')
.controller('UserController', Controller);
function Controller ($stateParams, RestFactory) {
var user = this;
activate();
function activate () {
RestFactory.songkick().one('users/'+$stateParams.username+'/calendar')
.get()
.catch(function(response){
console.log("Error with status code", response.status);
});
}
}
Did you miss the JSONP option settings for Restangular?
Something like the following:
//JSonp
RestangularProvider.setJsonp(true);
RestangularProvider.setDefaultRequestParams('jsonp', {callback: 'JSON_CALLBACK'});
Documented here
Related
As title, I want to catch Http response that sent by the browser.
Let say a redirect to "http://domain/api/something", actually, a GET request to "http://domain/api/something" which return a JSON data. How can I get that data on first load using AngularJs?
You should modify your code as below
app.service('feedbackService', function ($http) {
this.getFeedbackPaged = function () {
return $http.get('http://domain/api/something');
};
});
app.controller('feedbackController', function ($scope, feedbackService, $filter) {
// Constructor for this controller
init();
function init() {
feedbackService.getFeedbackPaged().then(function(data){
$scope.feedbackItems=data;
});
}
});
Use $http service as follows.
$http.get(
'http://domain/api/something'
).then(function successCallback(response) {
$scope.data = JSON.parse(response.data);
}, function errorCallback(response) {
// error handler
});
reference: https://docs.angularjs.org/api/ng/service/$http
I am trying to save $http response data in a variable inside angularJS factory. But I could not access the response outside the http method. It is showing undefined. I checked this link Injecting $scope into an angular service function() Please let me know how to handle this.
Below is the factory code:
angular.module('myapp')
.factory('CardNumberFactory',['$http', function ($http) {
// Service logic
var details={};
$http.get('scripts/services/mock.json')
.then(function(responce){
var resopnceData = responce.data;
details=resopnceData;
});
console.log(details);
return {details:details};
}]);
Because the $http service is asynchrony. You should do this like that:
angular.module('myapp')
.factory('CardNumberFactory',['$http', function ($http) {
var details={};
function getData() {
return $http.get('scripts/services/mock.json')
.then(function(response){
return {details: response.data}
});
}
return {
getData: getData
}
}]);
angular.module('myapp').controller('TestController, function($scope,CardNumberFactory) {
CardNumberFactory.getData().then(function(res) {
// res is the {details} object
})
})
I'm trying to call the getStuff function from my controller, but I get an error in the console saying that "undefined is not a function". I'm trying to return JSON from the GET and then store it in a $scope variable.
app.factory('UserInfo', function($http) {
var user = [];
return{
getStuff: function(){
user.push($http.get('api/users'));
return user;
},
testPost: function(){
return $http.post('api/users');
}
};
});
The factory is hooked up to the controller as follows
.controller('TwitterController', function($scope, $q, $interval, UserInfo) {
and here's the $scope function I'm using to call the factory function
$scope.datapls = function() {
UserInfo.getStuff().success(function(response){
console.log(response);
$scope.loaduser.push(response);
});
}
Thanks! I appreciate the help.
You're error refers to the .success() function - it doesn't exist.
It looks like you're trying to use promises. If that's the case, then you need to return the promise itself from your service.
Something like this (not tested, but an idea). You want to use the $q in your service, not your contorller.
The examples in the $q on AngularJS docs section are great.
So by doing this, your controller doesn't have to wait around for the data. As soon as it's resolved
app.service('UserInfo', function($http, $q) {
this.getStuff = function(){
var deferred = $q.defer();
$http.get('api/users').success(function(data, status) {
deferred.resolve(data);
}).error(function(data, status) {
deferred.reject(data);
});
return deferred.promise;
}
}
);
And in your controller you can do this:
UserInfo.getStuff().then(function(dataFromService){
// dataFromService is used in here..
$scope.loaduser.push(dataFromService);
}, function(error) {
// the error will come in via here
});
According to the docs, $http in itself returns a promise, you can change your factory function in order to achieve what you trying to do:
app.factory('UserInfo', function($http) {
return{
getStuff: function(){
return $http.get('api/users'));
},
testPost: function(){
return $http.post('api/users');
}
};
});
and in the controller:
$scope.datapls = function() {
UserInfo.getStuff().then(function(response){
console.log(response);
$scope.loaduser.push(response);
});
}
I am trying to create a Phonegap App. I use Angular as frontend.
I have a factory that gets data from an external ressource. In .config i added the access origin * attribute.
When I debug using http://debug.build.phonegap.com it seem to returning the data. The call to the API is returning 584 bytes.
So there seems to be an issue regaring the data from the factory to the frontend.
My Factory
.factory('ActivityService', ['$http', '$location', 'CookieService', function ($http, $location, CookieService) {
return {
getActivitiesService: function (data) {
$http.post('http://www.example.com/api/v1/Activity.php',
{
MethodName: "getActivitiesService",
SessionToken: CookieService.getCookie("ua_session_token")
})
.success(data)
},
postActivityService: function (activity) {
$http.post('http://www.example.com/api/v1/Activity.php',
{
MethodName: "postActivityService",
SessionToken: CookieService.getCookie("ua_session_token"),
ActivityName: activity.activityName,
ActivityDescription: activity.activityDescription
}).success(function () {
$location.path("/home");
});
}
}
}])
My controller
.controller('HomeCtrl', ['$scope', 'ActivityService', function($scope, ActivityService) {
//GET activities from server / DB
ActivityService.getActivitiesService(function (data) {
if (jQuery.isEmptyObject(data))
{
$scope.emptyJsonArray = "No activities.";
}
else
{
$scope.$apply(function () { $scope.activities = data; });
}
})
}])
In my app.js i do this:
//Manually bootstrapping Angular, after cordova.
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
angular.element(document).ready(function () {
angular.bootstrap(document, ['attenttoApp']);
});
};
Update:
Thanks both of you. I checked the content of the returned data, and it was an error that was returned.
Fixed it and now i works...
in the doc, they use return in factory
https://docs.angularjs.org/api/ng/service/$http
so try it like this
getActivitiesService: function (data) {
var toreturn = $http.post('http://www.example.com/api/v1/Activity.php',
{
MethodName: "getActivitiesService",
SessionToken: CookieService.getCookie("ua_session_token")
})
.success(function(data, status, headers, config) {
return data;
})
return toreturn;
},
and i think you should see in direction of promises, i wrote an answer about this, look at it
For which status codes promise resolving
I can't seem to get the $httpProvider.interceptors to actually intercept. I created a sample on JSFiddle that logs when the interceptor is run and when the $http response is successful. The request interceptor is run after the response is already returned as successful. This seems a bit backwards.
I can't use transformRequest because I need to alter the params in the config. That part isn't shown in the sample.
I'm using AngularJS 1.1.5
http://jsfiddle.net/skeemer/K7DCN/1/
Javascript
var myApp = angular.module('myApp', []);
myApp.factory('httpInterceptor', function ($q) {
return {
request: function (config) {
logIt('- Modify request');
return config || $q.when(config);
}
};
});
myApp.config(function ($httpProvider) {
$httpProvider.interceptors.push('httpInterceptor');
});
function MyCtrl($scope, $http) {
// Hit a server that allows cross domain XHR
$http.get('http://server.cors-api.appspot.com/server?id=8057313&enable=true&status=200&credentials=false')
.success(function (data) {
//logIt(data[0].request.url);
logIt('- GET Successful');
});
$scope.name = 'Superhero';
}
// Just the logging
var logs = document.getElementById('logs');
function logIt(msg) {
var e = document.createElement('div');
e.innerHTML = msg;
logs.insertBefore(e, logs.firstChild);
}
HTML
<div ng-controller="MyCtrl">Hello, {{name}}!</div>
<br/>
<div id="logs"></div>
If you want the option to accept/reject a request at interception time you should be using $httpProvider.responseInterceptors, see example below:
$httpProvider.responseInterceptors.push(function($q) {
return function(promise){
var deferred = $q.defer();
promise.then(
function(response){ deferred.reject("I suddenly decided I didn't like that response"); },
function(error){ deferred.reject(error); }
);
return deferred.promise;
};
});
EDIT Didn't read your comment, indeed responseInterceptors is now obsolete an that's how you do it instead:
$httpProvider.interceptors.push(function($q) {
return {
request: function(config){ return config; },
response: function(response) { return $q.reject(response); }
};
});
I learned something useful, thanks
The request interceptor isn't running after the data is returned. It's running before. Your logIt function inserts the newest message at the top. If you change your code to use the $log service, you'll see that the interceptor runs first.