Dynamic inline variables for the translate directive #423
I'm submitting a ...
[x ] bug report => check the FAQ and search github for a similar issue or PR before submitting
[ ] support request => check the FAQ and search github for a similar issue before submitting
[ ] feature request
Current behavior When passing a variable inside the translateParams on the translate directive, the text gets rendered once, it will not change even if you change the variable.
It seems to be that this only happens with objects, arrays, etc. and not with strings or numbers.
Expected/desired behavior Whenever the translateParams variable change the text should be rendered again
Reproduction of the problem
http://plnkr.co/edit/4nHPcxwspCsQJyRQ69vP?p=preview
What is the expected behavior?
Whenever the translateParams variable change the text should be rendered again
What is the motivation / use case for changing the behavior?
Suppose you have a list of users, and an inline modal, whenever you click a user you want to show a modal with a text containing the name of the user in the middle, so you have a variable globalUser, everytime you click a user the globalUser variable changes so you expect the modal text to have the name of the current user, this doesn't happen with the actual behaviour, it keeps showing the text that the variable has at the moment it renders.
Please tell us about your environment:
OSX: Sierra Darwin l 16.3.0 Darwin Kernel Version 16.3.0: Thu Nov 17 20:23:58 PST 2016; root:xnu-3789.31.2~1/RELEASE_X86_64 x86_64
-
ngx-translate version: 6.0.0
-
Angular version: 2.4.7
-
Browser: all
You still can use TranslateService to get a dynamic translation. But I agree, it would be simpler if translator pipe could do the same.
@kamok No, it doesn't.
@Verurteilt How are you navigating around this issue? Do what @diamond-darrell said and get a dynamic translation to render on your view?
Sorry to spam, I found a temporary workaround:
On every single update on your params do this:
this.translate.use(this.translate.currentLang);
This forces a reload. Kinda hacky though.
Hey, yeah it's a bug because I only test for equality in references. The pipe uses a custom function that I stole from AngularJS source code to compare object: https://github.com/ngx-translate/core/blob/master/src/translate.pipe.ts#L44 I don't use it in the directive (and I should). A PR to fix this would be nice and very easy to do, just use this "equals" function here to compare the parameters: https://github.com/ngx-translate/core/blob/master/src/translate.directive.ts#L27
@ocombe
Just double check about your previous comment: while testing this bug, it seems that for both the pipe and also the directive, you still have to refresh/update the full params object.
Just updating a property like:
this.params.field = 'abc';
this.translate.use(this.translate.currentLang);
does not work.
The code below seems to work:
this.params = { field: 'abc' };
this.translate.use(this.translate.currentLang);
@StefH what version do you have? It seems to be this bug was already fixed, if you still have trouble try using ImmutableJS (http://blog.scottlogic.com/2016/01/05/angular2-with-immutablejs.html).
I will double check the version and my code for bugs. I keep you updated.
@Verurteilt I did check the code and I made a small mistake somewhere.
The code below works fine:
this.params = { field: 'abc' };
this.translate.use(this.translate.currentLang);
However, it would be nicer if this method:
this.translate.use(this.translate.currentLang);
was not required, or maybe create a new method called:
refresh();
which refreshes the data. ( @ocombe , is this possible? )
@StefH What version of the library do you have? this.translate.use(this.translate.currentLang); is used to set the language, that shouldn't be inconvenient when updating a variable.
I'm using latest 7.0.0
Personally I like the refresh() method more because I don't want to update the language, just force a refresh.
@Verurteilt It's not about in inconvenience, it's about being clear on what a method is doing. Other people working on the codebase would be like "Why is this dead code here?". Unless you leave a comment saying that a bug in the ngtranslate requires it to "refresh" to translation. Which is why having a refresh() is better.
@kamok I don't know what @StefH is trying to do, all he said was
This code works well:
this.params = { field: 'abc' }; this.translate.use(this.translate.currentLang);
I don't know if he is using that variable, updating or even binding it, that's why I think he has a bug in his code and not necessarily in the library, as you can see the library uses a method to check if two variables are equal (https://github.com/ngx-translate/core/blob/master/src/translate.directive.ts#L27) and if not it updates the translations.