Reputation: 182
I'm having trouble returning data from an Angular promise in a factory back to the controller. In this example,
update: function (staffList) {
// get local last updated timestamp
var lastUpdatedLocal = "";
var lastUpdatedRemote = "";
for (i=0; i < staffList.length; i++) {
// get largest (most recent) timestamp
if(staffList[i].entry_date > lastUpdatedLocal) {
lastUpdatedLocal = staffList[i].entry_date;
}
}
// get remote last updated timestamp
var promise = $http.get('REMOTE_API_CALL')
.success(function(data, status, header, config) {
return lastUpdatedRemote = data[0].entry_date;
}).then(function(response) {
return response.data[0].entry_date;
});
console.log(promise);
}
I want to filter local data to get a local timestamp, compare it against a remote timestamp and instruct the controller to re-download all data if the local timestamp is less than the remote timestamp.
I'm filtering the local data okay and getting the expected result. Where I seem to get stuck is with promises. I can log out the filtered remote data within the .success or .then methods but haven't had much luck returning the values out of the promises. I know there's probably an issue with variable scope here.
Also, am I best to return a boolean from my factory to my controller (should I update? true/false) or perhaps a small obj with the local & remote timestamped data and leave the controller decide what to do from there?
Thanks in advance.
Upvotes: 0
Views: 1125
Reputation: 3469
Here is the best example I have of how to implement this. I assumed some stuff about your controller and factory. Note that you need to inject $q into your factory to use deferreds. This is how I do it in my app.
http://jsfiddle.net/JimTheDev/2zLEp/
/*
NOTE: make sure to inject $q into your factory before
this. For the purposes of my example, let's assume your
factory looks like this:
*/
app.factory('mySweetFactory', ['$q', function($q) {
return {
// You probably have a bunch of other methods like
// this one in your factory.
myothermethod: function(argument1, argument2) {
/* some code here */
},
update: function (staffList) {
// Create a new deferred object
var deferred = $q.defer();
// get local last updated timestamp
var lastUpdatedLocal = "";
for (i=0; i < staffList.length; i++) {
// get largest (most recent) timestamp
if(staffList[i].entry_date > lastUpdatedLocal) {
lastUpdatedLocal = staffList[i].entry_date;
}
}
// Make a call to the remote api
$http.get('REMOTE_API_CALL').then(function(response) {
// Get the remote last updated
// time from the response
var lastUpdatedRemote = response.data[0].entry_date;
// Check if local or remote is larger
// You probably need to modify this
// depending on your datetime formatting.
// I am assuming an epoch string.
if(lastUpdatedRemote > lastUpdatedLocal)
{
// Resolve the deferred and return
// the data so that the controller can
// use it to update the view
deferred.resolve(response.data);
} else {
// Since we don't need to do anything,
// reject the deferred
deferred.reject();
});
// Return the promise from the deferred object
// immediately. We will eventually either
// resolve or reject it, but at the start, it
// will be in a pending state.
return deferred.promise;
}
};
}]);
app.controller('mySweetController', ['mySweetFactory', function(mySweetFactory){
$scope.doUpdate = function() {
mySweetFactory.update($scope.staffList).then(function(newStaffList) {
// Promise was resolved. List needs updating!
$scope.staffList = newStaffList;
}, function(){
// Promise was rejected. No update needed!
});
};
}]);
Upvotes: 2