Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What changed in angular 1.3 that broke my code?

Tags:

angularjs

My code worked in Angular 1.2, but does not work in 1.3 and I cannot figure out what changed in angular and what I should change in my code to fix it.

I have set up a plunkr example.

The code in HTML is simply

{{ 'guy' | change }}

The javascript code is:

angular.module('app').service('MyService', function( $timeout ){

  var data = null;

  $timeout(function(){
     data = 'this is data';
  },2000);

  this.transform = function(){
    return data;
  }

});


angular.module('app').filter('change', function( MyService ){
  return function(input){
    return MyService.transform();
  }
});

The idea is that the filter's result depends on an async response.

In Angular 1.2, the view updated accordingly. In Angular 1.3 it does not.

To switch between angular 1.2 and angular 1.3 - you need to change the route to angular at the top of the HTML file. between

<script data-require="[email protected]" data-semver="1.3.0" src="//code.angularjs.org/1.3.0/angular.js"></script> 

and this

<script data-require="[email protected]" data-semver="1.2.0" src="//code.angularjs.org/1.2.0/angular.js"></script>

I also tried 1.3.1 - same issue.

like image 701
guy mograbi Avatar asked Nov 07 '14 16:11

guy mograbi


1 Answers

This is due to an optimization introduced since 1.3.0-rc2.

Basically, the $parse service performs dirty-checking on the inputs and only re-evaluate the expression if at least one of the inputs has been changed. In your example, the literal 'guy', the sole input of the expression, is never changed, so the entire expression including the filter won't get re-evaluated. The implication is that filters should be stateless, returning the same result for the same input.

Assume you are aware of and accept the performance penalty, you can bypass this optimization by telling AngularJS that you're filter is stateful, like this:

angular.module('app').filter('change', function( MyService ){
  var fn = function(input) {
    return MyService.transform();
  }
  fn.$stateful = true;
  return fn
});

This is the new plunkr that works as you would expect.

like image 125
Buu Nguyen Avatar answered Sep 19 '22 21:09

Buu Nguyen