Perhaps this is a fundamental misunderstanding of Angular scope, but here goes.
I have a service that handles changing a language preference:
languageService.js
function languageService() {
var language = "en";
var service = {
getLanguage: getLanguage,
setLanguage: setLanguage
};
function getLanguage () {
return language;
}
function setLanguage (newLang) {
language = newLang;
}
return service;
}
I also have a filter that formats something:
someFilter.js
function myFilter(languageService) {
return function(num) {
var french = languageService.getLanguage() === 'fr';
if (french) {
return "is french!"
} else {
return "is other."
}
}
}
I try to use this filter in some HTML: Blah blah {{ 'test' | someFilter }}
.
It works, but only on load; if I call setLanguage('en')
, the binding doesn't change.
Perhaps this is a fundamental misunderstanding of Angular scope, but here goes.
I have a service that handles changing a language preference:
languageService.js
function languageService() {
var language = "en";
var service = {
getLanguage: getLanguage,
setLanguage: setLanguage
};
function getLanguage () {
return language;
}
function setLanguage (newLang) {
language = newLang;
}
return service;
}
I also have a filter that formats something:
someFilter.js
function myFilter(languageService) {
return function(num) {
var french = languageService.getLanguage() === 'fr';
if (french) {
return "is french!"
} else {
return "is other."
}
}
}
I try to use this filter in some HTML: Blah blah {{ 'test' | someFilter }}
.
It works, but only on load; if I call setLanguage('en')
, the binding doesn't change.
- 1 You need to return 'service' from languageService.js. Also, in your filter make sure you're actually calling the getLanguage method () when you declare var french. – Matthew Clise Commented Mar 15, 2016 at 18:18
- Yeah, sorry, I cut out some boilerplate for brevity's sake. I'll add it in. – opticon Commented Mar 15, 2016 at 18:19
1 Answer
Reset to default 7There are actually two issues with your code.
First, in the service you should fire a digest when your var changes. So it would be
myApp.factory('languageService', ['$rootScope', function ($rootScope) {
var language = "en";
var service = {
getLanguage: getLanguage,
setLanguage: setLanguage
};
function getLanguage () {
return language;
}
function setLanguage (newLang) {
language = newLang;
$rootScope.digest();
}
return service;
}]);
Second and more subtle one. In angular, filters get updated only if the value you pass them in the markup changes (in your case is 'test'), for any other change to the scope your filter will be pletely ignored.
The solution is to force angular to parse that particular filter on any digest.
myApp.filter('someFilter', ['localeService', function (localeService) {
function filter (value) {
var french = languageService.getLanguage === 'fr';
if (french) {
return "is french!"
} else {
return "is other."
}
}
filter.$stateful = true; // This line does the trick
return filter;
}]);
You can get more info on the Angular Docs