AngularJS promises and timing with custom filters -


i'm having massive headache right regarding custom filters timing. have demo (learning angular) gallery app in using custom filter checkboxes select different categories of photos.

the simptoms: when using custom filter on ng-repeat directive noticed http://screencast.com/t/xpgx1lytu9yp ... after few hours of debugging got conclusion problem data json not there when filter runs, though without filter seems load ok.

here plnkr http://plnkr.co/edit/kbbg67 (i copy pasted code, modified bit, not working yet, fix in morning, code)

i started using deferring , promises in services fetches json data controllers , else wait data load, [services]

angular.module('services', []).factory('getallposts', ['$http', '$q', '$timeout', function($http, $q, $timeout) {   //defining promised based api   var deffered = $q.defer();   //the getdata function   var getdata = function() {     //defining empty data array     var thedata = {};     //using $http dat     $http.get('/wordpress/api/get_recent_posts/').success(function(data) {       // prepare data here       //assigning our data thedata array.       // // new stuff here, pushing data 1 one populate array faster isn't emtpy .. ?!       thedata.length = 0;       (var = 0; < data.length; i++) {         thedata.push(data[i]);       }       thedata = data;     });     //setting timeout data , waiting if necesarry.     $timeout(function() {       deffered.resolve(thedata);     }, 1000);     //when s done, return promise... think so. ?!     return deffered.promise;   }   return {     //creating getdata handler use in controllers.     getdata: getdata   }; }]) 

my controller [controller]

.controller('listcontroller', ['$scope', 'getallposts', 'getcategories', '$location',     function($scope, getallposts, getcategories) {         $scope.name = 'list';         getallposts.getdata().then(function(data) {             return $scope.posts = data.posts;         });         getcategories.get(function(data){             return $scope.categories = data.categories;         })     } ]) 

i'm using getdata().then() fetch while it's loaded.

i realize not telling same thing filter [filter]

angular.module('filters', []) .filter('checkboxfilter', function($filter) {     return function(post, prefs) {         var i, j, k, n, out, matchingpost = [];         // loop through post         (i = 0; < post.length; i++) {             console.log('i passed length ... wtf?')             out = false;             n = 0;              if (prefs) {                 // each item, loop through checkboxes categories                 (j = 0; j < prefs.length; j++) {                      // each category, loop through checkboxes categories of current category                     (k = 0; k < prefs[j].categories.length; k++) {                          // test if current item property name same filter name                         if (post[i][prefs[j].slug] === prefs[j].categories[k].slug) {                              // test if checkbox checked property                              (prefs[j].categories[k].value) ? n++ : out = true;                             break;                         }                     }                     if (out) break;                     // if 1 filter in each categories true, add item matchingpost                     if (n === prefs.length) {                         matchingpost.push(post[i]);                     }                 }             }         }         return matchingpost;     } }) 

the thing started reading angular book , didn't understood many things went hands on experience, every bit falls place 1 ... i've been spending time on it. think if take on again make more sense.


question: how rid of errors , make filter read data after it's been loaded?


side-question: through different service outputting existing categories in backbone (wordpress) , ng-repeat them in checkboxes, how link checkboxes results of filters? (it isn't obvious me yet, though have seen examples....)


side-question 2: why requests multiply, in first screenshot posted, no wait, part talking http://screencast.com/t/lcrwnliol3u ... have 44 posts far, after data there, filter calls again.

this behaviour hapenned on other things ... wondering doing wrong.


annotation: using angular 1.2.0rc1 of tonight, behaviors appeared other versions used: 1.0.7.0, 1.1.5.

i think real way override default $interpolateprovider enable filters return promises. way, defer rendering of filtered expressions until resolved.

remember, though, cannot chained filters trivially. forced rewrite $parse enable support chaining of promises.

i faced same problem @ moment, , such, might go ahead , it. if so, make sure post link answer on github repository project (http://github.com/agileapes/bootstrapui).

edit

another (mostly) easy way pass arbitrary argument filter updated via http call (or other means):

.controller("mycontroller", function ($scope, $q, $timeout) {     $scope.result = null;     var deferred = $q.defer();     $timeout(function () {         $scope.result = [1, 2, 3, 4];     }, 2000); }); 

here have updated result via timeout, don't have way. demonstration. update $scope.result in way choose.

here sample filter, include even numbers in result:

.filter('even', function () {     return function (input) {         if (!angular.isarray(input)) {             return input;         }         var result = [];         angular.foreach(input, function (x) {             if (x % 2 == 0) {                 result.push(x);             }         });         return result;     } }); 

now, in view, can use them together, way:

<div ng-controller="mycontroller">     <ul ng-if="result.length"> <!-- nice not pollute dom empty lists -->         <li ng-repeat="item in result | even">{{item}}</li>     </ul> </div> 

after couple of seconds or so, list should populated , ngrepeat directive should receive filtered result.

the trick, here, have made digest cycle happen particular result variable, means filter being fed variable re-executed, in turns means happen smoothly , expected.


Comments

Popular posts from this blog

c# - Send Image in Json : 400 Bad request -

jquery - Fancybox - apply a function to several elements -

An easy way to program an Android keyboard layout app -