I am writing a directive that accesses a service to get the translated strings of the page. The service will make a call to the server on loading the page and get the strings back, it works with the controller displaying everything fine but doesn't work in the directive.
var blockUserAction = function () {
return {
restrict: 'AE',
replace: 'true',
scope: {
theirId: "=theirId"
},
controller: function ($scope, translationsService) {
translationsService.init(); //does http request. Already called on mod.run() so redundant here.
$scope.caption = translationsService.translations.Conversation.OptionsMenu.BlockUser.value;
$scope.btnClick = function () {
debugger;
};
},
template: "<a href='#' data-ng-click='btnClick()'>{{caption}}</a>"
};
}
I have already called the translations.init() on the module.run() and works with the controller but I'm calling it here again to see if that helps... it doesn't really. I can see by debugging the btnClick() that once the service comes back with the strings the object is updated, so "translationsService.translations.Conversation.OptionsMenu.BlockUser.value" has its value but $scope.caption hasn't been updated.
I've been playing a bit with watch() and apply() but I have the feeling that I'm over complicating something that should be as simple as accessing the service, which is a singleton, and get the value.
theirId is a value that the parent controller sets on the directive tag through the view so the directive doesn't need to know about who is using it, it only needs the id and access to the services to use: translations and the profiles (removed this one to simplify atm) services .
Example:
<a block-user-action theirId="5"></a>
Does anyone know if I am supposed to call watch/apply or set it differently or this is just a bug as the main controller doesn't seem to have any problem with this but this other one does?
Also, this directive has been declared as part of the main module so it should have access to the service without problems:
app.directive('blockUserAction', blockUserAction);
app.run(function(messagingTranslations){
messagingTranslations.init();
})
update
The translations.init():
var messagingTranslations = function (globalizationService) {
return {
init: function () {
globalizationService.setTranslations(this.translations);
},
translations: new function () {
...
}
};
};
The service method called:
this.setTranslations = function (list) {
var ids = getListOfIds(list);
return getTranslationsFromServer(ids).then(function (response) {
setTranslationValues(list, response);
return list;
});
}
update2
I've set a watch over translations...value and console.logged everything I can see that the directive is created, the scope assigned to empty string (default value) and after all of that has happened the watch fired... but there's no value?
var myDirective = function () {
return {
restrict: 'AE',
replace: 'true',
scope: {
theirNoid: "=theirNoid"
},
controller: function ($scope, translationsService) {
translationsService.init();
console.log("init called");
$scope.$watch('translationsService.translations.Conversation.OptionsMenu.BlockUser.value', function () {
console.log('hey, myVar has changed!: ' + translationsService.translations.Conversation.OptionsMenu.BlockUser.value);
});
$scope.caption = translationsService.translations.Conversation.OptionsMenu.BlockUser.value;
console.log("caption set");
$scope.btnClick = function () {
console.log('I clicked the button and the value is: ' + translationsService.translations.Conversation.OptionsMenu.BlockUser.value);
};
},
template: "<a href='#' data-ng-click='btnClick()'>{{caption}} eee</a>"
};
}
log:
init called
caption set
hey, myVar has changed!:
But if I click the button the log is:
I clicked the button and the value is: Block user
their-idin the anchor tag bound to a value on the scope than the directive will watch automatically. See fiddle for a little demo using a timeout to change the value in the controller scope. I would console.log everything you can on your translationsService to see if there is maybe something in there.translationsService.init()were setup to return a promise than you might be better off. It's possible that the init doesn't return in the time you are setting the caption variable in the directive. However that should give you an error in the console.$watchfires on all$digestcalls, one of those calls happens on initialization. This does not mean that the value of what your watching has necessarily changed.