Nativescript: Incorrect locale with momentjs

Created on 17 Jan 2017  路  25Comments  路  Source: NativeScript/NativeScript

Please, provide the details below:

Tell us about the problem

Setting the locale of momentjs doesn't work as expected on iOS. It keeps setting the moment's locale to english.
While searching the web if there was an issue, I found that people have had the same issue on Android part: https://github.com/NativeScript/android-runtime/issues/334
@slavchev sent a fix for android part but it seems there isn't any for iOS.

Which platform(s) does your issue occur on?

iOS

Please provide the following version numbers that your issue occurs with:

  • CLI: 2.5.0-2016-12-02-7315
  • Cross-platform modules: 2.5.0-2016-12-01-4913
  • Runtime(s): iOS: 2.5.0-2017-1-4-2
  • Plugin(s): moment: 2.16.0

Please tell us how to recreate the issue in as much detail as possible.

Try to set the moment.locale('fr') it will keep displaying dates in english.

More info

I applied the fix mentionned here: https://groups.google.com/forum/#!topic/nativescript/AkUxmZBXZ5M
It works but clearly it is not a stable solution.

ios question

Most helpful comment

import * as moment from "moment/moment.js";

Something related to the absolute path being wrong once NativeScript has compiled the app.

All 25 comments

Hi @vincentpalita

I've tested momentjs on my side and it works as expceted. Here is the sample code I've used

import * as moment from "moment";

export function navigatingTo(args: EventData) {
    console.log(moment().format("dddd")); // Wednesday

    console.log(moment.locale("bg")) // set and prints bg
    console.log(moment.locale()); // Prints bg

    console.log(moment().format("dddd")); // 小褉褟写邪
}

Hi @NickIliev !

Thanks for getting back to me this quickly!!
Well we double checked and still have "en".

May I ask you which version of momentjs did you install?
Thank you!
Vincent

@victorsosa

The latest from npm as follows:

"version": "2.17.1",

btw I have tested with chaning the package.json of momentjs to

    "main": "moment.js",

Here is the sample application I've created for testing purposes.
Perhaps, you should have the wanted localisation (in my case I had BG enabled on my MAC and PC). I also noticed that if you cache your moment or lazy load it the locale() change won't be respected.

@NickIliev : ooh. You applied the fix mentioned in the Google group?

My point was that we shouldn't have to do that and we should be able to use the momentjs package straight from the npm repository.
It seems to be OK on android side not on the iOS because of the "main" setting.

@vincentpalita I've just tried my application without the modification in the package.json (with the default settings from npm install) and it works as expected.
Have your tried my sample application at your side? (preferably using some of your locally installed languages instead of bg)

Hey @vincentpalita - were you able to resolve your issue?

@vincentpalita @NickIliev Were you able to resolve your issue......? Need it too.

@NickIliev @vincentpalita @borissau - Same issue here on iOS. Doing as @NickIliev showed above will print:

CONSOLE LOG file:///app/shared/momentLocale.js:15:12: Monday
CONSOLE LOG file:///app/shared/momentLocale.js:17:12: en
CONSOLE LOG file:///app/shared/momentLocale.js:18:12: en
CONSOLE LOG file:///app/shared/momentLocale.js:20:12: Monday

Doing the workaround that was posted on Google Groups did fix it but it is not a stable solution.

Doing the workaround that was posted on Google Groups did fix it but it is not a stable solution.

This solution work for iOS platform ?

@borissau - It did the trick for me, yes.

So, to avoid modifying directly the node_modules folder, and ...fork the official momunt github. Do you have any solution to override the line :
"main": "moment.js", ?

import * as moment from "moment/moment.js";

Something related to the absolute path being wrong once NativeScript has compiled the app.

@devantoine - Wow, that's definitely a more acceptable solution! Don't even need the extension part ".js".

import * as moment from "moment/moment";

Or:

var moment = require("moment/moment");

@NickIliev, sorry for not getting back to you before...
Well with the new nativescript-angular (1.4.0) the problem disappeared.
No need to double moment in the import. Direct import to "moment" works fine.

Problem still exists.
Steps to reproduce:

tns create --ng momentTest
cd momentTest
npm install moment --save
tns run ios

app.component.ts:

import { Component } from "@angular/core";
import * as moment from 'moment';

@Component({
    selector: "ns-app",
    templateUrl: "app.component.html",
})

export class AppComponent {
    constructor() {
        moment.locale('es');
        console.log(moment().format('LLL'));
    }
 }

import * as moment from 'moment/moment' do the trick, but I need moment to work with angular2-moment. So it won't work for me.
Changing main setting inside moment/package.json works too, but it is not a suitable solution.

@NickIliev could you reopen this issue?

@trunkovich the issue is not related to a problem in NativeScript modules but is related to the fact that the moment library needs some modifications to be a compatible NativeScript plugin.

To make the plugin compatible with NativeScript you should either clone the source, modify the main property in itspackage.json and then create a new package with npm pack

Change the package.json file of moment library as follows

"main": "./moment.js",

and change it is follows

"main": "moment",

Another solution would be to directly modify this entry after the library is installed in node_modules (not so good solution as it will require to manually modify the source after each time the node_modules folder is removed)

After the change is applied the moment library is working as expected on both iOS and Android

import { EventData } from 'data/observable';
import { Page } from 'ui/page';
import { HelloWorldModel } from './main-view-model';

import * as moment from "moment";


export function navigatingTo(args: EventData) {

    console.log(moment().format("dddd"));

    console.log(moment.locale("bg"))
    console.log(moment.locale());

    console.log(moment().format("dddd"));
}

@NickIliev why it works on android and web without any issues but doesn't work on iOS?

@trunkovich good question!
I have logged this as a bug in iOS runtime - you can track its development here

@NickIliev thank you.

@trunkovich keep in mind that moment is JavaScript library and even when the iOS runtime implements the module path resolution fix, this library will not comply with the requirements for NativeScript plugins.

For example, it won't be possible to bundle your NativeScript application with WebPack due to this mandatory setting. That said the workaround above will have to be applied once again if you need to bundle the application with WebPack.

If you use Typescript, you can change the tsconfig.json to

...
"paths": {
            "*": [
                "./node_modules/tns-core-modules/*",
                "./node_modules/*"
            ],
            "moment": ["./node_modules/moment/moment.js"]
        }
...

@baltruschat Are you sure, your solution didn't work for me (NativeScript + Angular). @devantoine's solution worked in web pack too.

I have the same issue with Moment Timezone. import * as moment from moment-timezone doesn't work. I think the problem is that Moment Timezone itself depends on Moment, and I don't know how to force it to use a specific path.

Does anyone have any ideas?

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

hshristov picture hshristov  路  3Comments

OscarLopezArnaiz picture OscarLopezArnaiz  路  3Comments

valentinstoychev picture valentinstoychev  路  3Comments

fmmsilva picture fmmsilva  路  3Comments

minjunlan picture minjunlan  路  3Comments