I am willing to track the progress of the querying from Facebook's graph api. I have this promise in an angular service
getPosts: function() {
var deferred = $q.defer();
FB.api(
"/me/home", {since:'yesterday','limit': limit},
function ( response ) {
if ( response && !response.error ) {
deferred.resolve(response);
}
}
);
return deferred.promise;
},
and in my controller I use FBS.getPosts().then(function (data) {...}); . I am willing to be able to keep track of the progress of this promise and be able to display it on my page. Any ideas if this is even possible? I tried adding function (progress) , after the error function of the promise in my controller, had no luck though. Somewhere I read you can use .progress(function (progress){...}) like the .then one but it didn't work.
I don't like leaving questions in the promise tag open as I've made is a personal goal to keep it clean :) so here goes:
Facebook does not expose that functionality, if you want you can track the progress of multiple requests (that is, how many out of N requests are done) but that's not the same thing.
What you are asking for is simply put - impossible. There is no way to know how far the query has progressed without Facebook telling you, and they're not telling you.
Happy coding.
Related
I have created a service that is to run any http requests that have been requested. This runs in the ui-router onSuccess hook and looks like this:
$transitions.onSuccess({}, function() {
document.body.scrollTop = document.documentElement.scrollTop = 0;
console.log('%cwe have completed a transition', 'color: green;');
httpQueueService.process();
});
The problem with this is that the controller is initialized after this hook, so I can't capture the http requests without adding a timeout:
function process() {
$timeout(() => {
let t = angular.copy(queue);
console.log('processing', t, t.length);
queue.forEach((task) => invoke(task));
}, 500);
}
I know the timeout is only half a second and I could probably reduce that even futher, but it doesn't seem right.
It would be better if I could get the controller that has been initialized directly from the success hook.
Is there a way of doing this?
I did try by looking at the transition object in the success hook:
$transitions.onSuccess({}, function(transition) {
console.log(transition);
});
But that doesn't appear to have the controller there
What you are looking for is the 'resolve' option of the ui-router's states. You are trying to asynchronously load data (from your httpQueueService) to the new state's controller if I understood your description correctly. I suggest you take a look at the official ui-router documentation, especially the tutorials. Obviously you can skip most of it, so starting from the second: https://ui-router.github.io/ng1/tutorial/hellosolarsystem seems feasible for you.
Basically it handles the asynchronous nature of what you are doing - without adding any exact, hard-coded timeout.
Here is another great article which I found helpful when dealt with async queries on transitions: https://medium.com/opinionated-angularjs/advanced-routing-and-resolves-a2fcbf874a1c
I hope this helps, however, if you have any more specific issue then let us know!
I need to post same url with multiple parameters simultaneously .
how to achieve in angular 1
You do it with $http service with $http.post() request. If you want to do multiple requests, you can do it a loop. E.g. return $http.post(url,data).then((response)=>{return response.data;})
This is where you need to clarify what do you mean by saying "simultaneously", because if you want to receive the response from all of these requests at the same time, then you need something more advanced like deferred objects. This is what $q service is for, it helps you to resolve such Promises.
Firstly you need to collect all of the asynchronous callbacks in an array:
var promises = [];
angular.forEach(array, function(element) {
promises.push( $http.post(url,element).then((res)=>{return res.data}) );
}
(Pass different parameters/data however you like)
Then you need to resolve all of them at the same time with $q.all():
$q.all(promises).then((res)=>{
/* do what you need with them, e.g:
$q.defer().resolve(res)
*/
})
It should resolve an array with your data from previous requests in synch now.
I need to invoke a Restful service endpoint to get an Id and once I got the result I should invoke a second Restful service endpoint through a angularjs service.
First call returns a customer ID, with this customer ID I need to search for additional info about that customer.
As I should call and and wait for promises I don't think nesting calls to promises is a good pratice. What I mean is that something like the below code isn't supposed to be a neat solution. Am I right or wrong? What should be a good way to achieve this task.
someService.someAction().then( function(data){
var id = data.data;
antoherCallToAnotherService.someOtherAction(id).then(function(data2){
//do some stuff
);
);
Thank you
This is quite typical approach. However, you can optimise it by chaining multiple promises:
someService.someAction().then(function(response) {
var id = response.data;
return antoherCallToAnotherService.someOtherAction(id);
})
.then(function(data2) {
// data is available
});
This is not that bad at all, however can be improved even more if you want. You should probably not make the first promise resolve with entire response object, underlying service should resolve with actual (maybe processed data). Then your code could become:
someService.someAction()
.then(antoherCallToAnotherService.someOtherAction)
.then(function(data) {
// data is available
});
For above to work, someService.someAction should resolve with response.data (which is an id in your case).
We have an endpoint on our API that includes a set of settings (like default text, other endpoints, etc.). Our frontend is written in AngularJS and we're trying to figure out the best way to get them back to the client, and make them available throughout all directives in the application. Right now our best solution is to include settings as a directive:
angular.module('ourapp')
.factory('settings', function ($http) {
var url = 'http://localhost:8080/settings';
return function (callback){
$http.get(url).success(callback);
};
});
But then all the other calls are wrapped asynchronously.
Is there a better way to do this?
Since the settings come asynchronously from the server, their availability will inherently be asynchronous. If your logic depends on the settings being available, then there is probably no better solution than using promises.
angular.module('ourapp').factory('settings', function($http) {
var url = 'http://localhost:8080/settings';
return $http.get(url); // returns a promise
});
You could use $route to resolve the promise before instantiating controllers. The settings would then be synchronously available in the controllers.
You can also simulate promise unwrapping, i.e. immediately (synchronously) returning an object, which later will be filled with real data. This is great for scopes and templates, and was previously a feature of Angular itself. Be aware that the simulated promise unwrapping may cause bugs if not used cautiously, because the settings data may or may not be there.
Example:
angular.module('ourapp').factory('settings', function($http) {
var url = 'http://localhost:8080/settings';
var settings = {};
$http.get(url).success(function(data) {
angular.extend(settings, data); // fills in data from server
});
return settings; // immediately (synchronously) returned
});
I'm using $q of AngularJS, when I create a single promise and that promise is already resolved, can it be resolved again? I don't know if this is possible but if not is there a way that I can resolve the same promise again and again. I was thinking of using the notify way but I don't know if there are other ways to do this.
From Mastering Web Application Development with Angularjs, by Kozlowski and Bacon, Chapter 3 "Communicating with a Back-end Server", section "The Promise API with $q":
A promise that was resolved or rejected once can't change its state.
There is only one chance of providing promised results. In other words it is not possible to:
Resolve a rejected promise
Resolve an already resolved promise with a different result
Reject a resolved promise
Reject a rejected promise with a different rejection reason
Those rules are rather intuitive.
For example, it wouldn't make much sense if we could be called back with the information that there are problems with a pizza order delivery after a pizza was successfully delivered (and probably eaten!).
If you provide more code and we can understand better what you are trying to do we might be able to help you.
what I simply did was reinitialize promise again like so:
var appReadyDeferred = $q.defer();
this.prepareAppReadyDeffered = function() {
appReadyDeferred = $q.defer();
};
this.appReady = function() {
return appReadyDeferred.promise;
};
this.appResolve = function() {
appReadyDeferred.resolve();
};
this.appDeferr = function() {
appReadyDeferred.reject();
};
So I can use
someService.appReady().then(function() {
// some code
});
And reinit it using
someService.prepareAppReadyDeffered();
I'm not sure this is the best possible resolution but it seems to work.