meteor-messageformat icon indicating copy to clipboard operation
meteor-messageformat copied to clipboard

[v2] [msgfmt] You called mf() outside of a method/publish and without specifying a locale, defaulting to native (en)

Open isAlmogK opened this issue 9 years ago • 11 comments

I'm getting the following message [msgfmt] You called mf() outside of a method/publish and without specifying a locale, defaulting to native (en)

I take it this is due to a loading issue the JS code is running before msgfmt is load. Is that correct?

isAlmogK avatar May 06 '15 15:05 isAlmogK

So further testing I'm seeing it has noting to do with the loading order. What's the correct approach to use message format in common code? A number of packages are setup in common code. Search, data tables and so forth.

isAlmogK avatar May 06 '15 15:05 isAlmogK

Can you give an example of what you're trying to do?

It doesn't really make sense to use mf() in shared/common code?

mf() on the client will reactively update when the locale is changed. mf() on the server will use this.connection.locale inside a method/publish.

mf() on the server outside of a method/publish doesn't really make sense, unless you specify a locale to use (for e.g. mail templates, etc) where you get the locale from the user profile.

What is your use case?

gadicc avatar May 06 '15 15:05 gadicc

I'm using the following package - https://atmospherejs.com/aldeed/tabular

and this is how I have it setup, due note I have the isClient check but I'm still getting the message - https://gist.github.com/almogdesign/728d42096babd0e18c50

isAlmogK avatar May 06 '15 15:05 isAlmogK

I don't know tabular, but the problem is that you're initting once in the beginning (for the data in the 'columns' property). What happens if the user changes languages?

If this data will always be in the same language, just do e.g. mf('producerName', 'Producer Name', null, 'es') to get rid of the warning. It's just a hint that you're using mf() in a place where there is no user language set.

gadicc avatar May 06 '15 17:05 gadicc

Yea the table is not reactive I'm trying to work on that now

isAlmogK avatar May 06 '15 17:05 isAlmogK

Can you do this

mf('producerName', 'Producer Name', null, msgfmt.locale());

isAlmogK avatar May 06 '15 17:05 isAlmogK

Never mind does not work

isAlmogK avatar May 06 '15 17:05 isAlmogK

On the server? No. What you really want is to do that stuff reactively on the client. If it's being sent from the server to the client, I guess you'd want to instantiate once for each language and then figure out how to get the client to request the right one. I don't know tabular, but if it's sent globally (not a per template basis) to the client, maybe you could even just have a function in a Tracker.autorun() that replaces the relevant part of the table.

gadicc avatar May 06 '15 18:05 gadicc

I have the same issue, same error message. The strange thing is despite the warning message, it works on development; it doesn't work on (<myapp>.meteor.com) production.

My use case is to define the labels in SimpleSchema, which is preferred as the label is defined in one place rather than every AutoForm (and quickform for that matter).

Is there a way to have the SimpleSchema label attributes be localizable strings via mf() or similar? Preferably without having to create a separate function for each label.

Sojourneer avatar Dec 26 '15 02:12 Sojourneer

Ok, I came up with a hacky workaround by wrapping SimpleSchema [CreateSchema(defn) instead of new SimpleSchema(defn)] so that I can specify the labels as {key: .., message: ..} which are passed through mf(). Label is reactive, but autoform.options isn't for some reason. Anyway, here is the draft code.

var mfX = function(key, message, args) {
    if(Meteor.isClient)
        return mf(key, message, args, msgfmt.locale());
    else
        return mf(key, message, args, msgfmt.native);
};

var CreateSchema = function(defn) {
    _.each(defn, function(fieldDef,fieldName) {
        // Patch the label
        var label = fieldDef.label;
        if(typeof(label) == "object" && label.key && label.message) {
            fieldDef.label = function() { return mfX(label.key, label.message, label.params); }
            console.log("Rewriting label",fieldDef.label);
        }
        // Patch the autoform.options
        if(fieldDef.autoform && fieldDef.autoform.options) {
            var options = fieldDef.autoform.options;
            fieldDef.autoform.options = function () {
                var patchedOptions = _.map(options, function (option) {
                    if (typeof(option.label) == "object" && option.label.key && option.label.message)
                        option.label = mfX(option.label.key, option.label.message, option.label.params);
                    return option;
                });
                console.log("patchedOptions",patchedOptions);
                return patchedOptions;
            };
        }
    });
    return new SimpleSchema(defn);
};

Sojourneer avatar Dec 26 '15 04:12 Sojourneer

No, the above dynamic approach doesn't work with the messageFormat's static scanning approach. None of the labels in the above appear in the /translate.

So I added another syntactic marker, say mfD() for the deferred mf() that I want to use above. E.g. { .. label: mfD('key1', 'message1') ...

mfD function just returns the label {key: .., message: ...} objects, and the previous wrapper approach then does the patching to function calls as before. msgfmt:extract needs patching to pickup the marker (a one-line change in the javascript handler). Seems to work great.

Sojourneer avatar Dec 26 '15 05:12 Sojourneer