Search code examples
javascriptangularjsangular-translate

How to use a promise inside an object literal


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;
});

Solution

  • 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() 
        }),
        ....   
    ]