jamesarosen/ember-i18n

Can i18n be used in a serializer to addTranslations()

Closed this issue · 3 comments

Hi,
I am getting drug data from a server that has English drug name as the ID and a bunch of relationships. One for each language being requested by the app E.g.

"{"type":"drug","id":"Abacavir","attributes":{"witness":0},"relationships":[{"id":"abacavir","type":"es"}]}"

I was planing to strip the relationships from the json and pass the data to the model after adding the language data to the i18n service via addTranslations().

        export default DS.JSONAPISerializer.extend({
            i18n: Ember.inject.service('i18n'),
            normalizeResponse: function(store, primaryModelClass, payload, id, requestType) {
            if (payload.data[0] && payload.data[0].type === 'drug') {
                let json = {};
                payload.data.forEach(function(rs){
                        json = {};
                        json[rs.id] = rs.id;
                    this.get('i18n').addTranslations('en', json);
                        rs.relationships.foreach(function(locale) {
                            json = {};
                            json[rs.id] = locale.id;
                        this.get('i18n').addTranslations(locale.type, json);
                    });
                    delete rs.relationships;
                });
            }
            return this._super(store, primaryModelClass, payload, id, requestType);
            }

The drug model

export default DS.Model.extend({
    witness: DS.attr('boolean')
});

Trouble is I haven't been able get access to the i18n service from within the serializer.
The rest of the app has no problem in utilizing all the functionality that i18n service offers.
I've tried every thing I can think of to get a handle on the service but no go.
I'd like to know if it can be done.
If that is not possible what other approach to entering this data into the i18n tables would be best?

I think you're on the right track. You just have a scoping problem.

payload.data.forEach(function(rs){
  json = {};
  json[rs.id] = rs.id;
  this.get('i18n').addTranslations('en', json); // this isn't the serializer here
  rs.relationships.foreach(function(locale) {
    json = {};
    json[rs.id] = locale.id;
    this.get('i18n').addTranslations(locale.type, json); // this isn't the serializer here
  });
  delete rs.relationships;
});

You can fix this by changing those callbacks to use ES6 => syntax, which preserves this:

payload.data.forEach((rs) => {
  json = {};
  json[rs.id] = rs.id;
  this.get('i18n').addTranslations('en', json); // this is now the serializer
  rs.relationships.forEach((locale) => {
    json = {};
    json[rs.id] = locale.id;
    this.get('i18n').addTranslations(locale.type, json); // this is now the serializer
  });
  delete rs.relationships;
});

or you can save off this.get('i18n') into a closure-local variable before the callbacks:

const i18n = this.get('i18n');
payload.data.forEach(function(rs){
  json = {};
  json[rs.id] = rs.id;
  i18n.addTranslations('en', json); // no this
  rs.relationships.forEach(function(locale) {
    json = {};
    json[rs.id] = locale.id;
    i18n.addTranslations(locale.type, json); // no this
  });
  delete rs.relationships;
});

Thank you James.
I feel simultaneously elated (because the problem was resolved) and an idiot (because I missed a pattern I have used many times before in this vary project)

Thanks again
Noel

Happy to help :)