I have a service to for API call as following,
getValue: function(input) {
var deferred, url;
deferred = $q.defer();
url = "url";
$http.post(url, input).success(function(data, status, headers, config) {
return deferred.resolve({
success: true,
data: data,
status: status,
headers: headers,
config: config
});
}).error(function(data, status, headers, config) {
return deferred.resolve({
success: false,
data: data,
status: status,
headers: headers,
config: config
});
});
return deferred.promise;
}
But this is async. How can I convert it to sync(I want to make it wait till I get the result)?
No that is not possible with Angular.
See https://github.com/angular/angular.js/blob/master/src/ng/httpBackend.js#L51 where the XMLHttpRequest is opened with
xhr.open(method, url, true);
The third parameter in an xhr.open() can be set to false or true, where false is synchronous and true is asynchronous. In the Angular case, it is hardcoded to true, so that all outgoing calls will be asynchronous.
Use the .success() callback to wait until the async call returns, and then do whatever you want to do there.
As per the suggestion in the comments, you can of course also do the calls via raw javascript, jQuery or any other library that supports synchronous calls, but I would advise using callbacks/defers with the asynchronous angular call, because synchronous calls are blocking and blocking is bad.
Related
I've seen some websites where the ajax requests are hidden from the console/firebug. Reading more about this, I saw some answers saying we need to use JSONP requests instead of regular AJAX calls.
However, when doing JSONP requests, like this:
$scope.debugFunction = function() {
var url = '/request/jsonp.php?callback=JSON_CALLBACK'
$http.jsonp(url)
.success(function(data, status, headers, config) {
console.log('Success: ', data);
})
.error(function(data, status, headers, config) {
console.log('Error: ', status);
})
}
I'm still able to see the results on the console/firebug.
Is there a way to remove this from the console/firebug within the AngularJs enviroment?
I am getting a valid JSON request but only $http fail method is invoked. It shows OK 200 in firebug. Also the view is not getting updated. Newbie trying out AngularJS so something could be too wrong :)
$http.jsonp("http://localhost:51377/api/Books/1").success(function(data, status, headers, config) {
alert("Suc");
$scope.people = data;
}).error(function(data, status, headers, config) {
$scope.people = data;
alert("fail");
});
This is the response in firebug:
{"ID":1,"BookName":"ASP.Net"}
Also fails for:
[{"ID":1,"BookName":"ASP.Net"}]
getting 404 in status code in $http call. I am using jsonp which should take care CORS? as I read from somewhere. My angular is in file:// protocol
Update-1:
Tried with launching my angular in localhost from VS. Same results
Update-2:
I added configuration changes to remove CORS in my backend .net webapi and now it works with the following code but still the original above code using jsonp fails
$http({
method: 'get',
url: 'http://localhost:51377/api/Books/',
responseType: "json"
}).success(function (data, status, headers, config) {
alert(data);
console.log('Success: ' + data);
$scope.people = data;
}).error(function (data, status, headers, config) {
console.log('Error: ' + data);
});
I believe you need to add a callback parameter to your request:
$http.jsonp("http://localhost:51377/api/Books/1?callback=JSON_CALLBACK")
More info here:
https://docs.angularjs.org/api/ng/service/%24http#jsonp
Also, see this JSFiddle (not mine):
http://jsfiddle.net/saarmstrong/hYACX/8/light/
When you remove the callback parameter it fails...
try to use only "/api/Books/1" instead of "http://localhost:51377/api/Books/1"
In an angular service I am making a get request with $http.get('some/url/'). I need to check the content-disposition for what the filename should be on a success. I'm not sure if there's a way to access headers so for now I'm using then. Is there a way to get headers in the success function?
Is there a way to get headers in the success function?
As seen in AngularJs $http Documentation, second paragraph verbatim
$http.get('/someUrl').
success(function(data, status, headers, config) {
// this callback will be called asynchronously
// when the response is available
}).
error(function(data, status, headers, config) {
// called asynchronously if an error occurs
// or server returns response with an error status.
});
You can do
$http.get('/some/Url').then(function(successResponse){
console.log(successResponse); // this will print out the response object and you can access headers, config, data, etc.
}, function(failureResponse){
console.log(successResponse);
});
I'm having some problems when I try to make some $http calls after the user session has expired. Server side the methods are created in such a way that if a request comes and the user isn't authenticated it redirects to the login page. Making the call with JS doesn't help much because for some method it returns me the HTML mark-up for the login page and for other calls it doesn't work at all. I would like to know why some calls return something and some calls don't do a thing.
CODE - Call that works
$http({
url: url + $scope.ftValue,
method: 'GET'
})
.success(function (data, status, headers, config) {
//stuff on success
})
.error(function (data, status, headers, config) {
console.log("An error occured when applying the Free Text Search!");
});
Call that doesn't work
$http({
url: url + '¤tFacet=' + facetName,
method: 'GET'
})
.success(function (data, status, headers, config) {
//stuff on success
})
.error(function (data, status, headers, config) {
console.log("Error during facet values extraction. Status: " + status);
});
To note that the only thing that's different is the method that's getting called. And that's kind of irrelevant because the controller has an authorisation annotation and the call doesn't even reach the method (which is fine, because for the one that works it returns me the login page).
I would like to know what would cause the second call to not work. Both are triggered by an ng-click directive.
I need to do some cross site scripting. The block of code below contains the method of jsonp, the method returns as if it failed, but when I change it to be a get request I then have success. I need to be able to a successful response using the jsonp method. The following can be ruled out. The response is valid json and this param is in the url ?callback=JSON_CALLBACK. Here is the json I receive from doing the http request and the code block that executes this code.
http response status code 200
[{"cube":"1" ,"points":"160"},{"cube":"2","points":"690"},{"cube":"3","points":"331"}]
code block
var myApp = angular.module('test', []);
myApp.controller('UserCtrl', function($scope, users) {
$scope.usersPerCube = users.getUsers();
})
myApp.factory('users', function($http) {
return {
getUsers: function() {
var deferred = $q.defer();
var url = "http://localhost/api/api/index.php/analytics/UsersPerCube?callback=JSON_CALLBACK";
$http.get(url).success(function (data, status, headers, config) {
console.log(data);
deferred.resolve(data);
}).error(function (data, status, headers, config) {
//this always gets called
console.log(status);
deferred.reject(status);
});
return deferred.promise;
}
}
Note that I have edited my server side code and now receive
"angular.callbacks._1( {"cube":"1","points":"160"},{"cube":"2","points":"690"},{"cube":"3","points":"331"})"
UPDATE
The above is valid and now the success method is executing. I just need to figure out how to parse the objects. I will post again once I figure out the answer.
I have decided to give a detailed description of how to do a jsonp request so others will not run into the same troubles as I did.
myApp.factory('users', function($http) {
return {
getUsers: function() {
var deferred = $q.defer();
var url = "http://localhost/api/api/index.php/analytics/UsersPerCube?callback=JSON_CALLBACK";
$http.get(url).success(function (data, status, headers, config) {
console.log(data);
deferred.resolve(data);
}).error(function (data, status, headers, config) {
//this always gets called
console.log(status);
deferred.reject(status);
});
return deferred.promise;
}
Notice that the url contains ?callback=JSON_CALLBACK. Here is a nice stackoverflow on that. Once you get the response then you'll receive a json like the one below.
"angular.callbacks._1( {"cube":"1","points":"160"},{"cube":"2","points":"690"},{"cube":"3","points":"331"})"
Here is a nice stackoverflow on that subject
Now the one part that got me is that the server has to return the GET param, callback. Here is a good tutorial for that. http://niryariv.wordpress.com/2009/05/05/jsonp-quickly/ So the json looks like the one above.
Well, I hope this helps someone in the future.
If you want to make several JSONP requests through $http service, you should use a little hack. Agular change JSON_CALLBACK to internal value, and best way to use next solution: put this js code into your returned js-file:
var callbackId = '_' + (angular.callbacks.counter - 1).toString(36);
angular.callbacks[callbackId](/* YOUR JSON */);
To be sure that this code will work for you, please check createHttpBackend method in angular sources.