Skip to content
This repository has been archived by the owner on Jan 29, 2024. It is now read-only.

Returning multiple promises from a custom translation loader #70

Closed
danielbsig opened this issue Jun 9, 2013 · 16 comments
Closed

Returning multiple promises from a custom translation loader #70

danielbsig opened this issue Jun 9, 2013 · 16 comments

Comments

@danielbsig
Copy link

I've implemented a custom translation loader, which basically loads a single .json file using $http, pretty much in the same way as in the plunker example (http://plnkr.co/edit/n6MEMU).

My application is made out of several individual "apps", and each app will maintain its own list of translated texts in their own files, so my code needs to take this into account. I've experimented with using $q.all() to create a single promise object out of a list of promise objects for each sub-app:

mainApp.factory('languageLoader', function ($http, $q) {
return function (options) {

    var allPromises = [];

    // g_apps is an array containing the names of all 'apps':
    angular.forEach(g_apps, function(value,index){
        var langUrl = '/' + value + '/' + value +  '_' + options.key + '.json';

        var deferredInst = $q.defer();
        allPromises.push(deferredInst);

        $http({
            method: 'GET', 
            url: langUrl 
        }).success(function(data, status, header, config){
            console.log("Successfully loaded " + langUrl);
            deferredInst.resolve(data);
        }).error(function(data, status, header, config){
            console.log("Failed to load " + langUrl);
            deferredInst.reject(options.key);
        });
    });

    // Finally, create a single promise containing all the promises
    // for each app module:
    var deferred = $q.all(allPromises);

    return deferred;
};

});

Perhaps I'm making some mistake, and perhaps the library should be able to handle this, because if the code looks like this, then no translations work at all.

@0x-r4bbit
Copy link
Member

Hey @danielbsig !

So, the problem here is, that you're returning an array of resolved values through $q.all (as you can see here: http://docs.angularjs.org/api/ng.$q#all). angular-translate doesn't handle a sets of promised values, as you can see here: https://github.com/PascalPrecht/angular-translate/blob/master/src/translate.js#L512-L526.

You could either define loaders for your different sub apps, or we have to teach angular-translate to handle sets of promised values :)

I think the latter would be a cool thing!

@0x-r4bbit
Copy link
Member

But it won't work how its currently implemented, since the resolved data, which is actually a translation table, has to map to a corresponding language key. Now, when uses() triggers $loaderFactory with a language key, and we'll getting back an array of translation table then, how should angular-translate know, which table corresponds to which key?

We only have the key which should be used in this case.

@0x-r4bbit
Copy link
Member

Ah damn, just looked at your code again. Your loader tries to load translation tables for just one key, for sure. Okay, so I think we can implement this.

Do you want to make a PR, or should I take care of it?

@0x-r4bbit
Copy link
Member

Okay, that was easy. Landed in canary right here: 0e5d6d9 will make a minor release soonish!

@0x-r4bbit
Copy link
Member

Landed in master 0.9.3 ! :)

Now do $ bower cache-clean and afterwards $ bower install angular-translate :)

@0x-r4bbit
Copy link
Member

Lemme know if everything works as expected!

@danielbsig
Copy link
Author

Yes, this is the solution I came up with as well (although I have an additional check if this is an array of promises, as I see it the JSON file could theoretically contain an array of language definitions, but this is unlikely...)

And this works... kind of, but not completely. I'm not sure why, there seems to be a timing issue here, since some elements do get translated, but others won't. I'm not sure if a $scope.apply() would be needed, I have to investigate this a bit further.

I'm also having problems with loading json files which contain sub-definitions, i.e. something like this:

{
'myFirstSubApp': {
'FOO': 'bar',
'SMURF': 'barf'
}
}

but this is another problem and shouldn't be a part of this issue :-)

@0x-r4bbit
Copy link
Member

@danielbsig okay, so how about setting up a plunker with your exact problem, so I can take a look at it. Would love to help you out!

@danielbsig
Copy link
Author

Yep, that was next on my TODO list :-)

@0x-r4bbit
Copy link
Member

Great, just post the plunk here when you're done

@danielbsig
Copy link
Author

Check this out:

http://plnkr.co/edit/Hx8eXN

I may have made some errors, but at least this behaves in a similar way.

@0x-r4bbit
Copy link
Member

Okay, taking a look at it now

@0x-r4bbit
Copy link
Member

Here's the fix: http://plnkr.co/edit/1gtXwr?p=preview

$q.all() excepts and array of promises, not an array of deferreds :)

@0x-r4bbit
Copy link
Member

It's line 20 in app.js by the way :)

@danielbsig
Copy link
Author

Ah thank you very much :-)

I'm still a bit rusty when it comes to the concept of a promise. But this is then fully resolved!

@0x-r4bbit
Copy link
Member

Awesome!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants