5

Im trying to aim so i can use i18n within functions that is called.

I have the error:

(node:15696) UnhandledPromiseRejectionWarning: TypeError: i18n.__ is not a function

How can i make so i18n would work inside functions and dont have to be within a req?

Server.js:

var    i18n = require('i18n-2');

global.i18n = i18n;
i18n.expressBind(app, {
    // setup some locales - other locales default to en silently
    locales: ['en', 'no'],
    // change the cookie name from 'lang' to 'locale'
    cookieName: 'locale'
});

app.use(function(req, res, next) {
    req.i18n.setLocaleFromCookie();
    next();
});

//CALL another file with some something here.

otherfile.js:

somefunction() {
               message = i18n.__("no_user_to_select") + "???";

}

How should i solve this?

maria
  • 207
  • 5
  • 22
  • 56

1 Answers1

5

If you read the docs carefull under Using with Express.js, it's clearly documented how it's used. After you bind i18n to express app through i18n.expressBind, i18n is available through the req object available to all express middlewares like:

req.i18n.__("My Site Title")

So somefunction should either be a middleware like:

function somefunction(req, res, next) {
  // notice how its invoked through the req object
  const message = req.i18n.__("no_user_to_select") + "???";
  // outputs -> no_user_to_select???
}

Or you need to explicitly pass in the req object through a middleware like:

function somefunction(req) {
  const message = req.i18n.__("no_user_to_select") + "???";
  // outputs -> no_user_to_select???
}

app.use((req, res, next) => {
  somefunction(req);
});

If you want to use i18n directly you need to instantiate it as documented like

const I18n = require('i18n-2');

// make an instance with options
var i18n = new I18n({
    // setup some locales - other locales default to the first locale
    locales: ['en', 'de']
});

// set it to global as in your question
// but many advise not to use global
global.i18n = i18n;

// use anywhere
somefunction() {
  const message = i18n.__("no_user_to_select") + "???";
  // outputs -> no_user_to_select???
}

Many discourage use of global.

// international.js
// you can also export and import
const I18n = require('i18n-2');

// make an instance with options
var i18n = new I18n({
    // setup some locales - other locales default to the first locale
    locales: ['en', 'de']
});

module.exports = i18n;

// import wherever necessary
const { i18n } = require('./international');
1565986223
  • 6,420
  • 2
  • 20
  • 33
  • For my current functions that I need to call is called within each other with a possibility of not having any req object. Possible to get languages based on userid that have some sort of i18n variable saved? I get what you mean here. (Y) – maria Apr 12 '19 at 17:50
  • Then you can use the global version by making an instance first. `Possible to get languages based on userid that have some sort of i18n variable saved` assuming you're retrieving from some db? – 1565986223 Apr 12 '19 at 17:51
  • Yes saved in db. Will chrck answer – maria Apr 12 '19 at 18:50
  • How would i approach this If some variable is based on userid database? I know this is out of the original question. Thanks for approach, will accept. – maria Apr 12 '19 at 18:53
  • you can use `setLocale(locale)` given `locale` is defined in your `option` like `.setLocale('de')` (assuming you've retrieved `de` from db) – 1565986223 Apr 12 '19 at 18:57
  • How Can i pass userid param to send to the international.js? – maria Apr 12 '19 at 19:04
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/191760/discussion-between-naga-elixir-jar-and-maria). – 1565986223 Apr 12 '19 at 19:08