Translate-ngx & Ionic 4

#1

Hi all, i’m using this code:

this.translate.get('ALERT_ERROR').subscribe(text => this.ALERT_ERROR = text);

but vs.code said me this:

@deprecated — Use an observer instead of a complete callback
@deprecated — Use an observer instead of an error callback
@deprecated — Use an observer instead of a complete callback

Can i use a better syntax ?
Thanks for help

#2

Hi @blondie :wave:

Not better, but here’s an alternative way of getting static values using promises and async/await:

async myFunction() {
  this.ALERT_ERROR = await this.translate.get('ALERT_ERROR').toPromise();

  // Or get several values passing an array
  const i18n = await this.translate.get(['ALERT_ERROR', 'ALERT_OK']).toPromise();
  this.ALERT_ERROR = i18n['ALERT_ERROR'];
  this.ALERT_OK = i18n['ALERT_OK'];
}

Best,
Rodrigo

#3

Hi Rodrigo, i need a little more help, look this function:

async ch3(key) {
    let value = '';
    value = await this.translate.get(key).toPromise();
    return value;
    debugger;
  }

If i call this function with:

console.log( this.ch3( 'VALIDATORS.EMAIL.REQUIRED'));

I see [object Promise] instead my string… why?
Thanks for help… :slight_smile:

#4

Because async functions always return a promise with your value :slight_smile: That is the reason why you can’t use await outside an async function, and you’ll often see it referenced as async/await.

If you want to print the resolved value of the promise returned by ch3(value), you need to use await or its .then() method:

// Using async/await
async otherFunction() {
  console.log(await this.ch3('VALIDATORS.EMAIL.REQUIRED'));
}

// Using Promise.then()
otherFunction() {
  this.ch3('VALIDATORS.EMAIL.REQUIRED').then(value => console.log(value));
}
#5

Sorry again, one step before, this my real code:

this.validation_messages = {
      'email': [
        { type: 'required', message: 'm1'},
        { type: 'pattern', message: 'm2' }
      ],
      'password': [
        { type: 'required', message: 'm3' },
        { type: 'minlength', message: 'm4' }
      ]
    };

i’ve to replace strings m1, m2, m3, m4 with translated versions, how can i do ?
Thanks again :beer:

#6

With async/await or promise chains?

#7

the more simple and correct way…

#8
async myFunction() {
  const i18n = await this.translate.get(['m1', 'm2', 'm3', 'm4']).toPromise();

  this.validation_messages = {
    email: [
      { type: 'required', message: i18n['m1'] },
      { type: 'pattern', message: i18n['m2'] }
    ],
    password: [
      { type: 'required', message: i18n['m3'] },
      { type: 'minlength', message: i18n['m4'] }
    ]
  };
}
#9

I’m a disaster… look:

  ionViewDidEnter() {
    // ugly fix for possible race condition: make sure that the translate module is fully loaded
    setTimeout(() => {
      this.translateMV();
    }, 500);
  }

  async translateMV() {
    const i18n = await this.translate.get([ 'VALIDATORS.EMAIL.REQUIRED',
                                            'VALIDATORS.EMAIL.PATTERN',
                                            'VALIDATORS.PASSWORD.REQUIRED',
                                            'VALIDATORS.PASSWORD.MINLENGTH']).toPromise();
    this.validation_messages = {
      email: [
        { type: 'required', message: i18n['m1'] },
        { type: 'pattern', message: i18n['m2'] }
      ],
      password: [
        { type: 'required', message: i18n['m3'] },
        { type: 'minlength', message: i18n['m4'] }
      ]
    };
    debugger;
  }

Result on debug:

what’s wrong ?
:beer::beer::beer:

#10

You have to the replace 'm1' etc. to the same keys you’re passing in the array to the translate.get(). Like i18n['VALIDATORS.EMAIL.REQUIRED']. I just used the same values you had in your example so you see that the translation strings have to match.

Also, the “fix” you have with the timeout in ionViewDidEnter() is not needed, that’s why you are “awaiting” the promise from the translate in translateMV() :wink:

#11

How can i send you beers ? :slight_smile:
Thanks a lot…

#12

Hahaha not yet, but maybe I should start making a donation page for beers and coffees :joy:

#13

maybe it’s better… & last question…
is it possible to read i18n array from another function of same page ?

#14

If you store it inside a class property, like you did in this.validation_messages you can access the resolved values from any function in the page/component. Just keep in mind what this property will be undefined until your translation function has finished executing.

#15

Why exactly is async needed here and await? I though .then is used to wait for a promise to finish before proceeding.

#16

async/await is just a newer and more readable way to use promises as if it were executed synchronously: https://developers.google.com/web/fundamentals/primers/async-functions

But you can keep using .then() and .catch(), there’s nothing wrong with that. I just prefer async/await because it’s extensively used in the Ionic 4 docs and new devs would find it more familiar.