core icon indicating copy to clipboard operation
core copied to clipboard

Dynamic inline variables for the translate directive #423

Open Verurteilt opened this issue 8 years ago • 13 comments

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

Verurteilt avatar Feb 17 '17 16:02 Verurteilt

You still can use TranslateService to get a dynamic translation. But I agree, it would be simpler if translator pipe could do the same.

diamond-darrell avatar Feb 28 '17 08:02 diamond-darrell

@kamok No, it doesn't.

Verurteilt avatar Mar 22 '17 20:03 Verurteilt

@Verurteilt How are you navigating around this issue? Do what @diamond-darrell said and get a dynamic translation to render on your view?

kamok avatar Mar 22 '17 20:03 kamok

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.

kamok avatar Mar 22 '17 20:03 kamok

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 avatar Mar 22 '17 21:03 ocombe

@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 avatar Jul 04 '17 10:07 StefH

@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).

Verurteilt avatar Jul 04 '17 16:07 Verurteilt

I will double check the version and my code for bugs. I keep you updated.

StefH avatar Jul 04 '17 17:07 StefH

@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 avatar Jul 05 '17 06:07 StefH

@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.

Verurteilt avatar Jul 05 '17 16:07 Verurteilt

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.

StefH avatar Jul 05 '17 17:07 StefH

@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 avatar Jul 12 '17 13:07 kamok

@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.

victorct avatar Jul 12 '17 14:07 victorct