javascript - Am I returning this promise correctly? -
i have function, getmonitors inside service. getmonitors returns list of monitor objects. if monitor object empty, grabs monitors via http , stores objects in monitor object array , returns it. function coded promise. know http returns promise, function may or may not use http - i've overlaid own promise (see below code)
controllers can call getmonitors(0) or getmonitors(1). 0 means if loaded in monitors array due previous call, don't load again. (1) means force reload array http
the service , associated getmonitors coded following way:
angular.module('zmapp.controllers').service('zmdatamodel', ['$http', '$q', function($http, $q) { // var deferred=''; var monitorsloaded = 0; var monitors = []; getmonitors: function(forcereload) { console.log("** inside zmdata getmonitors forcereload=" + forcereload); var d = $q.defer(); if ((monitorsloaded == 0) || (forcereload == 1)) // monitors empty or force reload { console.log("zmdatamodel: invoking http factory load monitors"); var apiurl = logindata.apiurl; var myurl = apiurl + "/monitors.json"; $http.get(myurl) .success(function(data) { // console.log ("http success got " + json.stringify(data)); monitors = data.monitors; console.log("promise resolved inside http success"); monitorsloaded = 1; return d.resolve(monitors); }) .error(function(err) { console.log("http error " + err); monitors = []; console.log("promise resolved inside http fail"); // know need reject here, not resolve. i'll it. lets assume need empty monitors list if there error return d.resolve(monitors); }); console.log("promise deferred inside http inside getmonitors"); return d.promise; } else // monitors loaded { console.log("returning pre-loaded list of " + monitors.length + " monitors"); return d.resolve(monitors); } },
i have route set getmonitors dependency so:
.state('app.montage', { data: { requirelogin: false }, resolve: { message: function(zmdatamodel) { console.log("inside app.montage resolve"); return zmdatamodel.getmonitors(0); } }, url: "/montage", views: { 'menucontent': { templateurl: "templates/montage.html", controller: 'zmapp.montagectrl', } } })
a sample controller uses coded so:
angular.module('zmapp.controllers').controller('zmapp.montagectrl', function($scope, $rootscope, zmdatamodel, message) { $scope.monitors = []; console.log("inside montagectrl waiting monitors load..."); $scope.monitors = message; // line returns undefined when getmonitors tries return preloaded monitor list console.log("i have received monitors inside montage , there " + $scope.monitors.length); // console.log("***calling factory"); //zmhttpfactory.getmonitors().then(function(data) //{ // $scope.monitors = data; // console.log("i got " + $scope.monitors); // }); $scope.dorefresh = function() { console.log("***pull refresh"); $scope.monitors = []; var refresh = zmdatamodel.getmonitors(1); refresh.then(function(data) { $scope.monitors = data; $scope.$broadcast('scroll.refreshcomplete'); }); }; });
the problem facing first time run, monitors list empty zmdata loads monitors http url , view shows perfectly. when switch view , view, see logs zmdata returning preloaded list of monitors (i know populated because printing out count in zmdata getmonitor else section). however, being returned controller undefined when "else" part of getmonitors hit.
this means not returning promise correctly in getmonitors "else" part.
any appreciated
ah, wrapped head around promises. can't return d.resolve(). sets state. need return d.promise , if resolved, return resolve. man. drove me mad.i think got basic hang of promises after 3 different questions. wish tutorials made clearer. returning d.promise , no 1 explained d.promise returns state of promise - changed resolve or reject.
the correct code is:
getmonitors: function (forcereload) { console.log ("** inside zmdata getmonitors forcereload="+forcereload); var d = $q.defer(); if ((monitorsloaded == 0) || (forcereload == 1)) // monitors empty or force reload { console.log ("zmdatamodel: invoking http factory load monitors"); var apiurl = logindata.apiurl; var myurl = apiurl+"/monitors.json"; $http.get(myurl) .success(function(data) { // console.log ("http success got " + json.stringify(data)); monitors = data.monitors; console.log ("promise resolved inside http success"); monitorsloaded = 1; d.resolve(monitors); }) .error (function (err) { console.log ("http error " + err); monitors = []; console.log ("promise resolved inside http fail"); d.resolve (monitors); }); return d.promise; } else // monitors loaded { console.log ("returning pre-loaded list of "+monitors.length+" monitors"); d.resolve(monitors); return d.promise; } }
Comments
Post a Comment