Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Race condition when injecting translate pipe into component #363

Closed
nrbbrg-at opened this issue Dec 19, 2016 · 8 comments
Closed

Race condition when injecting translate pipe into component #363

nrbbrg-at opened this issue Dec 19, 2016 · 8 comments

Comments

@nrbbrg-at
Copy link

I'm submitting a ... (check one with "x")

[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

The translate pipe does not function properly when injected into a component. See the attached plunker (inside ngOnInit()) for an example of this race condition.

Expected/desired behavior

Depends on the answer to this question: How should ng2-translate be used inside of a component? As far as I can tell it's an undocumented use case. If injecting the service, values do not update when the language is changed. Pipe encapsulates this functionality, and is also available to be injected into components, so it would seem the logical choice. If it is indeed the right thing to use, then it should function identically to when it's used inside a template.

Reproduction of the problem
If the current behavior is a bug or you can illustrate your feature request better with an example, please provide the steps to reproduce and if possible a minimal demo of the problem via https://plnkr.co or similar (you can use this template as a starting point: http://plnkr.co/edit/tpl:btpW3l0jr5beJVjohy1Q).

http://plnkr.co/edit/kzbZ4O0VKnqiYWzhsSxI

What is the expected behavior?

Already answered this.

What is the motivation / use case for changing the behavior?

Avoid the boilerplate of having to copy and paste sections of TranslatePipe to get the desired functionality.

Please tell us about your environment:

  • ng2-translate version: x.x.x

ng2-translate 4.2.0

  • Angular version: 2.0.0-rc.X

angular 2.3.1

  • Browser: [all | Chrome XX | Firefox XX | IE XX | Safari XX | Mobile Chrome XX | Android X.X Web Browser | iOS XX Safari | iOS XX UIWebView | iOS XX WKWebView ]

Tested in chrome.

  • Language: [all | TypeScript X.X | ES6/7 | ES5]

Typescript

@ocombe
Copy link
Member

ocombe commented Dec 19, 2016

Hello,

I'm not sure I understand why you need to inject the pipe into the component ?

If injecting the service, values do not update when the language is changed.

You can subscribe to onLangChange events, isn't it what you need ?

@nrbbrg-at
Copy link
Author

If that's the proper use case then I'm fine with it, but injecting the translate pipe seems cleaner than having to manage that subscription in each component.

@ocombe
Copy link
Member

ocombe commented Dec 19, 2016

Well the thing is that if you inject the pipe in your component I have no idea if the subscriptions in the pipe are really cleaned up after the component is destroyed (when it's in the template it gets handled by angular with the OnDestroy life cycle hook).

@nrbbrg-at
Copy link
Author

nrbbrg-at commented Dec 19, 2016

So, basically you're left with having to do this (is it correct?):

    this.translate.get('HOME.TITLE').subscribe((value: string) => {
      this.myValue = value;
    });
    this.translate.onLangChange.subscribe((event: any) => {
      this.translate.get('HOME.TITLE').subscribe((value: string) => {
        this.myValue = this.translate.transform('HOME.TITLE');
      });
    });

It's quite a bit of boilerplate, and it gets a lot bigger when using multiple values.

@SamVerschueren
Copy link
Contributor

I'm just wondering about the use case of this? What are you trying to do that's not possible with using a pipe in the template itself?

@ocombe
Copy link
Member

ocombe commented Dec 19, 2016

You can use "instant":

    this.translate.get('HOME.TITLE').subscribe((value: string) => {
      this.myValue = value;
    });
    this.translate.onLangChange.subscribe((event: LangChangeEvent) => {
      this.myValue = this.translateService.instant('HOME.TITLE');
      // or even if you don't use parameters:
      // this.myValue = event.translations['HOME']['TITLE'];
    });

But I get what you want, some kind of observable that would get the translation immediately and then call the callback when the lang changes as well. It makes sense and would be easier than doing 2 subscriptions. I'll see how to implement that when I get the time.

@nrbbrg-at
Copy link
Author

@SamVerschueren I've encountered a few situations where this is useful. Since the one I'm dealing with now is the only one that comes to mind, I'll use that as an example. We have a custom select box plugin that uses ul / li structure. The selected value is set by a callback. I could keep the translation key as the value and then put it in a pipe in the template instead, but the problem is that the selected value is sometimes distances, such as "100km", but also the string "Anywhere", which must get translated.

@ocombe Thanks!

@ocombe
Copy link
Member

ocombe commented Dec 21, 2016

Follow up this issue in #330, closing this one as I believe it's a duplicate (the desired functionality is the same in both cases)

@ocombe ocombe closed this as completed Dec 21, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants