In angular-translate version 2.0 the $translate service no longer returns the actual translation but a promise. I can see that is a good idea because there could be some asynchronous loading going on. But it confuses me how to use the service properly in my case, because I used the $translate service inside an object literal, like this
$scope.myDefs = [
...
{
field: 'supplier',
displayName: $translate('Supplier'),
cellTemplate: "<div class=\"ngCellText\">...</div>"
},
...
{
field: 'supplierSize',
displayName: $translate('Size'),
width: 100,
cellClass: "center"
}
...
];
Question: How do I use a promise inside an object literal?
It is supposed to (according to the documentation) be used like this:
$translate('HEADLINE').then(function (headline) {
$scope.headline = headline;
});
In angular-translate version 2.0 the $translate service no longer returns the actual translation but a promise. I can see that is a good idea because there could be some asynchronous loading going on. But it confuses me how to use the service properly in my case, because I used the $translate service inside an object literal, like this
$scope.myDefs = [
...
{
field: 'supplier',
displayName: $translate('Supplier'),
cellTemplate: "<div class=\"ngCellText\">...</div>"
},
...
{
field: 'supplierSize',
displayName: $translate('Size'),
width: 100,
cellClass: "center"
}
...
];
Question: How do I use a promise inside an object literal?
It is supposed to (according to the documentation) be used like this:
$translate('HEADLINE').then(function (headline) {
$scope.headline = headline;
});
Share
Improve this question
edited Feb 23, 2014 at 23:01
swenedo
asked Feb 23, 2014 at 22:54
swenedoswenedo
3,1149 gold badges32 silver badges50 bronze badges
1
- I wish you could "follow" a question on SO without necessarily marking it as a favorite. or... "notify when accepted". I know there's a super slick way to do this, but it's Sunday evening and my brain won't re-engage properly. I do like @calebboyd's answer below, but something tells me there's a way to create a custom service to do what you want... which is sorta what he did, just not abstracted to the service layer. – Brian Vanderbusch Commented Feb 24, 2014 at 0:45
4 Answers
Reset to default 14If you know that there's no asynchronous stuff going on, you can use $translate.instant()
which behaves exactly like $translate()
in 1.x.
You'd need to have a direct reference. Or a helper function that has closure over the reference. Like:
$scope.myDefs = [
...
createArrayObject({
field: 'supplier',
displayName: $translate('Supplier'),
cellTemplate: "<div class=\"ngCellText\">...</div>"
}),
createArrayObject(.....
]
and elsewhere
function createArrayObject(obj){
obj.displayName.then(function(data){
obj.displayName = data;
});
return obj;
}
Update
as Brian suggested below, Its always a good idea to write generic code you can use all over.
var forEach = angular.forEach,
isFunction = angular.isFunction;
function resolveProperties(obj){
forEach(obj,function(val,key){
if(isFunction(val.then)){
val.then(function(data){
obj[key] = data;
});
}
});
}
So you can use it like...
[
resolveProperties({
myPropertyToResolve: promiseReturningFunction()
}),
....
]
If you re using ui-grid, solution is to add headerCellFilter: 'translate' to columnsDefs (means myDefs) and displayName must have translation key.
Here is,
$scope.myDefs = [
{
field: 'supplier',
displayName: "Supplier",
cellTemplate: "<div class=\"ngCellText\">...</div>",
headerCellFilter: 'translate'
},
{
field: 'supplierSize',
displayName: "Size",
width: 100,
cellClass: "center",
headerCellFilter: 'translate'
}
];
Another idea is to loop through your literal and replace all the promises with values. However I don't know what happens if you call then, when a promise has already been resolved.
angular.forEach($scope.myDefs, function(element){
element.displayName.then(function(result){
element.displayName= result;
})
})