У меня есть сервис, обертывающий сторонний API, который я использую для извлечения данных в контроллер. Я хотел бы сделать некоторую обработку для поворота данных перед ее отображением, но я не могу работать, как это сделать после обещание завершено. До тех пор нет данных для обработки!Дождитесь завершения обещания перед обработкой результата
Я попробовал несколько различных способов, но ни один не кажется, работает:
angular.module('myApp').controller('myController', function ($scope, MyService) {
$scope.getData = function() {
MyService.getData(myParams)
.then(function (results) {
$scope.queryResults = results;
// Can't do processing here, data hasn't been retrieved yet
}, function (err) {
$scope.alerts.push({ msg: 'Unable to get data', type: 'danger' });
});
}
$scope.$watch('queryResults', function(newVals) {
// Can't do processing here either, this only fires at
// "$scope.queryResults = results;"
// above where "results" is still an empty array
});
};
И обслуживание:
angular.module('myApp').service('MyService', ['$q', function($q) {
return {
getData: function (params) {
var operation = $q.defer();
ThirdPartyLibrary.getData(params, { callback: function(err, results) {
if (err == null) {
operation.resolve(results);
} else {
operation.reject(err, results);
}
}});
return operation.promise;
}
}
}]);
Это должно быть довольно обычным делом хочу сделать, но Я не могу найти много на Google - хотя я, вероятно, искал неправильные вещи!
EDIT
ОК, так что я реструктурировать много вещей, и основная проблема по-прежнему кажется, что мое обещание цепи прогрессируют до возврата данных из ранее в цепочке. Вот новый код:
angular.module('myApp').service('MyService', ['MyWrapperService', function(MyWrapperService) {
var getDataForFilter = function(myApi, filter) {
var processedResults = {};
// This is the chain I'm having problems with
return MyWrapperService.getRelevantKeys(myApi, filter).then(MyWrapperService.getDetailsForKeys).then(function(results){
//do some processing here
return processedResults;
}, function(errors) {
return errors;
});
};
return {getDataForFilter: getDataForFilter};
}]);
angular.module('myApp').service('MyWrapperService', ['$q', function($q) {
var getRelevantKeys = function(myApi, filter) {
var operation = $q.defer();
myApi.getKeys({'filter': filter, 'callback': function (err, results) {
if (err == null) {
// This does get called correctly, but not until after the rest of the chain has been called.
operation.resolve(myApi, results, filter);
} else {
operation.reject(err, results);
}
}
};
var getDetailsForKeys = function(myApi, keys, filter) {
var operation = $q.defer();
var promises = [];
var details = [];
var errors = [];
angular.forEach(keys, function (val) {
// Get the data for each key. ***When this is called, 'keys' is still undefined.***
promises.push(getDataForKey(myApi, val, filter).then(function(result){
details.push(result);
}, function(err, result) {
errors.push(err);
}));
});
$q.all(promises).then(function() {operation.resolve(details);}, function() {operation.reject(errors)});
return operation.promise;
};
var getDataForKey = function(myApi, key, filter) {
var operation = $q.defer();
myApi.getDetail(key, {
'filter': filter,
'callback': function(err, results) {
if (err == null) {
operation.resolve(myApi, results, activity);
} else {
operation.reject(err, results);
}
}
});
return operation.promise;
};
return {
getRelevantKeys: getRelevantKeys,
getDetailsForKeys: getDetailsForKeys,
getDataForKey: getDataForKey,
};
}]);
К сожалению, API делает, что я пытаюсь сделать немного многословно, но я получаю все ключи базы данных, относящиеся к фильтру, а затем получить все значения для тех, затем переверните данные (комментарий в getDataForFilter
), прежде чем передавать их обратно на контроллер для отображения. Я рад добавить больше комментариев, если что-то неясно.
(Кроме того, любая общая обратная связь по архитектуре это была бы оценена!)
"* Это только срабатывает в' $ scope.queryResults = results; '*" именно то, что вы хотели, не так ли? Если 'results' - пустой массив, то это означает, что' getData' привел к пусту массива. – Bergi
Я предполагаю, что это ваша служба, которая делает что-то странное, или вы просто не получаете никаких данных для вашего запроса. –
Он возвращает данные, но требуется несколько секунд. 'then (function (results) {$ scope.queryResults = results;}' вызывается мгновенно с пустым массивом, который затем заполняется после завершения основного вызова API. – Mourndark