AngularJS - $scope outsite $http - ajax

I've create this piece of code:
app.controller('SiteDetailCtrl',function($scope, $routeParams, $http){
//remove ":" in SiteId
var SiteId = $routeParams.SiteId.replace(':','');
$scope.Site = $http.get('path-to-ajax/Site/'+SiteId);
.success(function(data){
$scope.Site = data;
console.log($scope.Site);
})
.error(function(){
$scope.Site = 'NULL';
alert('Ajax Fail');
});
console.log($scope.Site);
});
I don't understand why $scope.Site is available in Success function but outside ($http) $scope.Site is null.
Please explain for me what happen here.
I'm new to AngularJS.

the successhandler function you define in line 6 will run way later than the console.log statement from line 14. it is nothing angular specific but how asynchronous code works. i suggest you research a bit in that direction.

I haven't tested it yet but apparently the fact that your're returning a value from $http $scope.Site = $http.get(... //its worng and as Valerij said the nature of $http is ajax meaning asynchronous result, causes this bug.
you need to use it like this:
app.controller('SiteDetailCtrl',function($scope, $routeParams, $http){
//remove ":" in SiteId
var SiteId = $routeParams.SiteId.replace(':','');
$http.get('path-to-ajax/Site/'+SiteId);
.success(function(data){
$scope.Site = data;
console.log($scope.Site);
})
.error(function(){
$scope.Site = 'NULL';
alert('Ajax Fail');
});
// console.log($scope.Site);
});
html:
{{$scope.Site}} //this will work, asynchronously get results after Success function

Console.log you are using outside is executed immediately when the controller is initialized,
So the $scope.Site is not have a value
but Success function is called after the data is returned from the server, so value is present in the Success function

Related

$q.all() in angularJS

I have a set of ajax calls that should happen asynchronously and after all the ajax calls are made, some function should be executed. I am using $q.all().then() for this.
The problem with $q.all() is that even if one of the ajax calls fails the function won't get executed. My requirement is to execute the function regardless of the success or failure of the individual ajax calls. How can I go about it?
Using $q.allSettled instead of $q.all solves the problem.
Please refer to the following link for decorating the $q.all function
http://www.codeducky.org/q-allsettled/
You can resolve a promise with another promise, which makes it possible for you to do something like this:
var urls = [...];
var promises = urls.map(function (url) {
return $http.get(url).then(null,
// error callback returns a new promise
function (response) { return $q.resolve(response); });
});
$q.all(promises).then(...);
Fiddle: http://jsfiddle.net/j4b7pxmt/
you can use this code to implement this logic.
definition of GroupPromise plugin.
//create a group promise function.
var GroupPromise = function(){
this.allPromise = [];
this.successPromises = [];
this.failurePromises = [];
}
//use this function to add promises which you want to resolve on success or error.
GroupPromise.prototype.add = function(promiseToAdd){
var promise = $q.defer();
var self = this;
promiseToAdd.then(function(){
var args = angular.copy(arguments);
args.push({state: 'success'});
self.successPromises.push(promise);
promise.resolve.apply(this, args);
}, function(){
var args = angular.copy(arguments);
args.push({state = 'failure'});
self.failurePromises.push(promise);
promise.resolve.apply(this, args);
});
this.allPromise.push(promise);
}
//use this to resolve all promises.
GroupPromise.prototype.resolveAll = function(successCallback, errorCallback){
var self = this;
$q.all(this.allPromise).then(function(){
//all API calls processed.
if(self.failurePromises.length === 0){
//no API fails
successCallback.call(self);
}else{
//some API fails
errorCallback.call(self);
}
});
}
usage of GroupPromise plugin.
//create an object of GroupPromise.
var myGroupPromise = new GroupPromise();
//add API call promises to queue.
angular.forEach([1,2,3,4], function(){
myGroupPromise.add($http.get(url));
});
//call for resolve all promises and pass the success and error callback.
myGroupPromise.resolveAll(successCallback, errorCallback);
You have to use individual defers such as:
var myDefer = $q.defer();
myDefer.promise.then(function(result) {
}, function(rejected) {
});

parse.com background job triggering timeouts with cloud code function

I have written a cloud code function called approveDish that works within the timeout limits set by Parse.com when I call the function directly once from a client button.
However, I need to migrate some old database records to this and am wondering why when I run the background job with larger than say 3 results returned in the query I get timeouts in that cloud code function. Shouldn't this in a background job not timeout ever as we're calling things seriously?
Parse.Cloud.job("migrateDishesToChains", function(request, status){
Parse.Cloud.useMasterKey();
var Dishes = Parse.Object.extend("Dishes");
var query = new Parse.Query(Dishes);
query.notEqualTo("approved", true);
//dishes.equalTo("user", "JQd58QhOCO");
query.limit(1);
query.find().then(function(results) {
// Create a trivial resolved promise as a base case.
var promise = Parse.Promise.as();
_.each(results, function(result) {
// For each item, extend the promise with a function to delete it.
promise = promise.then(function() {
// Return a promise that will be resolved when the delete is finished.
return Parse.Cloud.run("approveDish", {dishID: result.id});
});
});
return promise;
}).then(function() {
status.success();
});
});

Angular $http returning new values only once

I am new to Angular, and set up a simple example with a REST Api config in Codeigniter that returns a json (default) thread list. No problems!
Until, I add an update to the Database. If I clear/then call getThreads again, I receive the same list of items. A page refresh solves this. I can see in firebug that its only calling the url:api/example/threadlist/id/'x' once per page load.
function ThreadsCtrl($scope, $http, $templateCache) {
$scope.getThreads = function(id) {
if (!id) { id = 'reset'; }
$http({method: 'GET', url: 'api/example/threadlist/id/' + id, cache: $templateCache}).
success(function(data) {
$scope.threadslist = data; //set view model
}).
error(function(data) {
$scope.threadslist = data || "Request failed";
});
};
How would I make it so that it always calls a new list of data rather than reuses the old.
Thanks!
If i understood your question correctly your ajax call is being cached so you have to remove cache:$templatecache from your code

How can I pass parameters with callback functions to search APIs like Yahoo BOSS and BING?

I am using Yahoo BOSS and Bing APIs to provide search functionality to my site. Specificaly, I use their JSON response formats where I would pass a callback function to the search provider that would later be called back with the search results. My callback function actually gets called, but the problem is, if I make more than one requests at a time, I can't tell which request a certain response is for. To this end, is there a way to pass additional parameters with the callback function to the search provider so that I can later use it to identify which response goes with which request?
Thank you
I have a same problem with you! I googled and find some solutions
and I has solve my problem. Now i show it to you, I hope it can help you :)
Previous code:
function MakeGeocodeRequest(credentials) {
var pins = checkLocation.d
$.each(pins, function (index, pin) {
var geocodeRequest = 'http://ecn.dev.virtualearth.net/REST/v1/Locations/' + pin.City + ',' + pin.Country + '?output=json&jsonp=GeocodeCallback&key=' + credentials;
CallRestService(geocodeRequest);
});
function CallRestService(request) {
var script = document.createElement("script");
script.setAttribute("type", "text/javascript");
script.setAttribute("src", request);
document.body.appendChild(script);
}
function GeocodeCallback(result) {.. to do with result callback, --> i want to add some pin infomation here}
Because each sccipt when add to document ( document.body.appendChild(script);) it will be run --> and callback, you cant add more params.
I solve it by request through ajax (doesnt add to document any more), when the ajax call success --> I call the GeocodeCallback(result, pin)
Here is the complete code.
function MakeGeocodeRequest(credentials) {
var pins = checkLocation.d;
$.each(pins, function (index, pin) {
$.ajax({
url:"http://ecn.dev.virtualearth.net/REST/v1/Locations/",
dataType: "jsonp",
data:{key:credentials,q:pin.City + ',' + pin.Country},
jsonp:"jsonp",
success: function(result){
GeocodeCallback(result,pin);
}
});
});
}
function GeocodeCallback(result,pin) { ... to do here}

XDomainRequest object caching/asynchronous call issue

I have an aspx page on which I am using XDomainRequest object to populate two div(s) with html returned from AJAX response.
I have used Jquery to get the divs and perform "each()" on the retrieved List
var divs = $("div");
divs.each(function(index) {
if (window.XDomainRequest) {
xdr = new XDomainRequest();
if (xdr) {
xdr.onload = function() {
alert("XDR Response - " + xdr.responseText);
var currentDivID = divs[index].attributes["id"].value;
var selectedDiv = $("div[id='" + currentDivID + "']");
if (xdr.responseText == '') selectedDiv.attr("style", "display:none;");
else selectedDiv.append(xdr.responseText);
};
xdr.open("GET", xdrUrl);
try {
xdr.send();
} catch (e) {
alert(e);
}
} else {
alert('Create XDR failed.');
}
} else {
alert('XDR not found on window object .');
}
}
Now, whats happening is , i have two Divs on a page that have different IDs and when this code runs on "$.ready(function(){})" , both requests are asynchronously sent to the server and processed
the result is
1. sometimes the onload get the response for the second div in both div results.
2. IE sents only one request to the server(I am using fiddler to see what requests are sent to server).
Can anybody guide me whats wrong with the code ? As far as I know XDR does not support synchronous calls, and asynchronous calls are giving me wrong results. Any workaround/tip for this problem.
Issue solved by myself when I pointed out a mistake in my code:(.
xdr = new XDomainRequest();
should be
var xdr = new XDomainRequest();
For Point 2 , I added "Cache-Control:no-cache" header in my response and it solved the matter.

Resources