0

Following snippet:

<h1>
    {{pid.pname}}
    <span style="font-size: 0.75em; text-shadow: none;">({{pid.pos}})</span>
    <span style="font-size: 0.5em; text-shadow: none;"><a ng-href="#/team/{{pid.team | the_link}}/">{{pid.group}}</a></span>
</h1>

Filter the_link defined like so...

myApp.filter('the_link', function() {
    return function(longname) {
        alert(longname);
        var parts = longname.split(' ');
        return parts[parts.length - 1].toLowerCase();
    }
});

The alert() call is fired several times on loading the page-- seemingly every time a {{...}} is parsed (4 times in the snippet), and it's undefined except for the one time where the ngHref is finally handled. Additionally, an $interpolate:interr is fired three of the four times...

Why is this? I think I'm misunderstanding a lifecycle of some kind. Any clarity appreciated.

PSL
  • 123,204
  • 21
  • 253
  • 243
Wells
  • 10,415
  • 14
  • 55
  • 85
  • can you add controller or pid object data structure – Seminda Sep 01 '14 at 00:42
  • How is the pid value being set? Asyncronoously right? You should always keep a null check in your filter for the input because You filter will run every digest cycle and if the data is not available by that time you will get error during interpolation section which uses this filter. See http://plnkr.co/edit/jPx5LQ?p=preview – PSL Sep 01 '14 at 01:51
  • Yeah, async. I wrapped a `typeof(longname) != 'undefined'` around it and it seems to work. Not entirely grokking the binding but I get it. I'll read up. – Wells Sep 01 '14 at 02:12

2 Answers2

1

You issue is mainly with the absence of null check in your filter. Your filter is going to run during every digest cycle, it could so happen that the interpolation directive when refreshes itself during a digest cycle you don't have value for pid or pid.team available yet. You might be trying to load it with an sync call (ex:- http, resource), so whenever your filter runs with longname undefined your filter will fail and you will see the error $interpolate:interr which is caught during the interpolation. To fix it, just add a null check in your filter:-

 return function(longname) {
       //You should always do a null check because data might not be available by the time the filter runs.

        if(!angular.isString(longname)) return;  //or just if(!longname) return;

        var parts = longname.split(' ') ;
        return (parts[parts.length - 1] || "").toLowerCase(); //Just to be safer
    }

Plnkr

PSL
  • 123,204
  • 21
  • 253
  • 243
0

Main reason can be you not defind team.

I have done same filter with following controller its working.

function MyCtrl($scope) {
$scope.pid={pname:'test', pos:'test pos',group:'f b c d',team:'A B C G T H J'};

}

See the demo app

Also angularjs uses a 'dirty-check' approach, so it need to call all the filters to see if exists any change. After this it detect that have a change on one variable and then it execute all filters again to detect if has other changes. check this post

Community
  • 1
  • 1
Seminda
  • 1,745
  • 12
  • 15
  • Well, in your example, why does the `alert()` fire three times given that there is only one anchor element? – Wells Sep 01 '14 at 01:17
  • check the link http://stackoverflow.com/questions/9682092/databinding-in-angularjs – Seminda Sep 01 '14 at 01:23