javascript - AngularJS : calling a factory method within the loop -
i have factory method looks below:
angular.module('gridsamplesapp') .factory('registerpostfactory', function($resource, $q, webrequest) { var getmessage = function(upddata, token, dataurl) { var deferred = $q.defer(); var settings = { data: upddata, headers: { 'content-type': 'application/json', 'x-csrf-token' : token }, method: 'post', url: dataurl, withcredentials: true }; webrequest.requestraw(settings).then( function(response) { // data app sec var msg = response; deferred.resolve(msg); }, function(error) { console.log('error retrieving message', error); deferred.reject('error retrieving message', error); }); return deferred.promise; }; return { getmessage: getmessage }; });
i have controller looks like
$scope.getlogs = function() { $.each($scope.modifiedsn, function(i, e) { if ($.inarray(e, result) == -1) result.push(e); }); $scope.inputs.push({sn:'', key:'', status:'', log:''}); for(var i=0; i<result.length; i++) { var j = result[i]; if ($scope.data[j].serialnumber !== "") { var upddata = {}; upddata['iconvruleflg'] = ''; upddata['srnum'] = $scope.data[j].serialnumber; upddata['lvemailid'] = 'abc@xyz.com'; upddata['wkey'] = $scope.data[j].wtykey; registerpostfactory.getmessage(upddata, $scope.token, dataurl).then( function(response) { $scope.msg = response.headers["custommessage"]; $scope.data[j].autolinkerrorlog = $scope.msg; $scope.inputs.push({sn: $scope.data[j].serialnumber, key: $scope.data[j].wtykey, status: response.headers["msgtype"], log: $scope.msg}); }, function(error) { console.log('error reading msg: ', error); } ); } } };
the issue takes last element in array since asynchronous call , loop not wait response, tried using $q.all()
not figure out how implement this, can please help?
from understand, factory works ok, , @ravimone said, usage of async callback code within loop, ll surprised how beginners fall trap. also, see $scope.msg
, not sure comes , how works, due async , parallel nature of calls, might display wrong values various calls, if changes per call, should think serializing call.
a cleaner way write $scope.getlogs
might be( have reduced usage of jquery, used es5 stuff, if have support legacy systems, can use this ):
$scope.getlogs = function(){ var result = [] // again not sure result comes from, initizing here, else can append filtered array previous set $scope.modifiedsn.foreach(function(value) { if (result.indexof(value) < 0) result.push(e); }); $scope.inputs.push({sn:'', key:'', status:'', log:''}); var promises = result.map(function(val){ return $scope.data[val]; }).filter(function(val){ return val && val.serialnumber !== ""; // first check if $scope.data[j] exists }).map(function(val){ return registerpostfactory.getmessage({ iconvruleflg: '', lvemailid: '', wkey: val.wtykey, srnum: val.serialnumber }).then(function(response){ $scope.msg = response.headers["custommessage"]; val.autolinkerrorlog = $scope.msg; $scope.inputs.push({sn: val.serialnumber, key: val.wtykey, status: response.headers["msgtype"], log: $scope.msg}); }).catch(function(e){ console.log('error reading msg: ', e); }); }); $q.all(promises) .then(function(resarray){ console.log('get logs...'); }).catch(function(e){ console.log('some error: ', e); }); };
edit:
if want them done in sequence:
$scope.getlogs = function(){ var result = [] // again not sure result comes from, initizing here, else can append filtered array previous set , serialpromise = $q.when(1); // initializing promise. $scope.modifiedsn.foreach(function(value) { if (result.indexof(value) < 0) result.push(e); }); $scope.inputs.push({sn:'', key:'', status:'', log:''}); result.map(function(val){ return $scope.data[val]; }).filter(function(val){ return val && val.serialnumber !== ""; // first check if $scope.data[j] exists }).foreach(function(val){ var datum = { iconvruleflg: '', lvemailid: '', wkey: val.wtykey, srnum: val.serialnumber }; serialpromise = serialpromise.then(function(){ // adding new promise chain. return registerpostfactory.getmessage(datum); }).then(function(response){ $scope.msg = response.headers["custommessage"]; val.autolinkerrorlog = $scope.msg; $scope.inputs.push({sn: val.serialnumber, key: val.wtykey, status: response.headers["msgtype"], log: $scope.msg}); }).catch(function(e){ console.log('error reading msg: ', e); }); }); serialpromise.then(function(){ console.log('got logs...'); }).catch(function(e){ console.log('some error: ', e); }); };
Comments
Post a Comment