Search code examples
angular.net-coreaspnetboilerplateboilerplate

Can not add language in ASP boilerplate (ASPNetZero)


I am trying to add Malay language in ASPNetZero framework, but its saying can not find module ./ms.js.

Following are the steps I have followed so far:
1. Added a XML file for Malay language
2. Added a new language in the DefaultLanguageCreator class
3. Selected my language from the menu bar.

For detail error see below:

core.js:14597 ERROR Error: Uncaught (in promise): Error: Cannot find module './ms.js'
Error: Cannot find module './ms.js'
    at .*\.js$ namespace object:179
    at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invoke (zone.js:388)
    at Object.onInvoke (core.js:16156)
    at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invoke (zone.js:387)
    at Zone.push../node_modules/zone.js/dist/zone.js.Zone.run (zone.js:138)
    at zone.js:872
    at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:421)
    at Object.onInvokeTask (core.js:16147)
    at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:420)
    at Zone.push../node_modules/zone.js/dist/zone.js.Zone.runTask (zone.js:188)
    at resolvePromise (zone.js:814)
    at resolvePromise (zone.js:771)
    at zone.js:873
    at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:421)
    at Object.onInvokeTask (core.js:16147)
    at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:420)
    at Zone.push../node_modules/zone.js/dist/zone.js.Zone.runTask (zone.js:188)
    at drainMicroTaskQueue (zone.js:595)
defaultErrorLogger @ core.js:14597
push../node_modules/@angular/core/fesm5/core.js.ErrorHandler.handleError @ core.js:14645
next @ core.js:16628
schedulerFn @ core.js:12609
push../node_modules/rxjs/_esm5/internal/Subscriber.js.SafeSubscriber.__tryOrUnsub @ Subscriber.js:196
push../node_modules/rxjs/_esm5/internal/Subscriber.js.SafeSubscriber.next @ Subscriber.js:134
push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber._next @ Subscriber.js:77
push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.next @ Subscriber.js:54
push../node_modules/rxjs/_esm5/internal/Subject.js.Subject.next @ Subject.js:47
push../node_modules/@angular/core/fesm5/core.js.EventEmitter.emit @ core.js:12593
(anonymous) @ core.js:16178
push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invoke @ zone.js:388
push../node_modules/zone.js/dist/zone.js.Zone.run @ zone.js:138
push../node_modules/@angular/core/fesm5/core.js.NgZone.runOutsideAngular @ core.js:16115
onHandleError @ core.js:16178
push../node_modules/zone.js/dist/zone.js.ZoneDelegate.handleError @ zone.js:392
push../node_modules/zone.js/dist/zone.js.Zone.runGuarded @ zone.js:154
_loop_1 @ zone.js:677
api.microtaskDrainDone @ zone.js:686
drainMicroTaskQueue @ zone.js:602
Promise.then (async)
scheduleMicroTask @ zone.js:578
push../node_modules/zone.js/dist/zone.js.ZoneDelegate.scheduleTask @ zone.js:410
onScheduleTask @ zone.js:297
push../node_modules/zone.js/dist/zone.js.ZoneDelegate.scheduleTask @ zone.js:401
push../node_modules/zone.js/dist/zone.js.Zone.scheduleTask @ zone.js:232
push../node_modules/zone.js/dist/zone.js.Zone.scheduleMicroTask @ zone.js:252
scheduleResolveOrReject @ zone.js:862
resolvePromise @ zone.js:808
(anonymous) @ zone.js:724
webpackJsonpCallback @ bootstrap:25
(anonymous) @ 892.js:1

Solution

  • In ASPNETZero date picker is in ngx-bootstrap, so in this lib they use moment.js, your three steps are right but you missed some steps that explained below:

    1. Add a XML file for Malay language (...\aspnet-core\src\YOURCOMPANY.Core\Localization\YOURCOMPANY\YOURCOMPANY.ms.xml)
    2. Added a new language in the DefaultLanguageCreator class

    First of all, in your angular project edit this file ...\angular\src\assets\appconfig.json, and add localMapping suitable conversion (to en for now), don't forget set this configuration to appconfig.production.json.

            "localeMappings": {
                "angular": [
                  {
                    "from": "ms",
                    "to": "en"
                  }
                ],
                "moment": [
                  {
                    "from": "ms",
                    "to": "en"
                  },
                  ...
                ],...
    
    • Then go this location : (...\angular\src\assets\ngx-bootstrap\ngx-bootstrap-locale-mapping.service.ts), map you culture like below:
    const cultureMap = {
                'zh-Hans': 'zh-cn',
                'es-MX': 'es',
                'vi': 'en-gb',
                'ms': 'ms'
                // Add more here
            };
    

    Set your module map:

    getModuleName(locale: string): string {
            const moduleNameMap = {
                'zh-Hans': 'zhCn',
                'es-MX': 'es',
                'pt-BR': 'ptBr',
                'vi': 'enGb',
                'ms': 'ms'
    
                // Add more here
            };
    

    You can map your culture like 'ms': 'en', if you do like this you will get your SPA date-picker in Georgian type, but if you want to change the moment of your date-pickers, you have to add your i18n overwrite, for doing this:

    add this folder js file to (...\angular\src\assets\ngx-bootstrap\custom-i18n\ms.js) you can find your moment.js culture on the net or simply edit other language to get your suitable moments.

    finally, go to this file: (...\angular\src\assets\ngx-bootstrap\ngx-bootstrap-datepicker-config.service.ts) and change this function like below:

    static registerNgxBootstrapDatePickerLocales(): Promise<boolean> {
            if (abp.localization.currentLanguage.name === 'en') {
                return Promise.resolve(true);
            }
    
            let supportedLocale = new NgxBootstrapLocaleMappingService().map(abp.localization.currentLanguage.name).toLowerCase();
            let moduleLocaleName = new NgxBootstrapLocaleMappingService().getModuleName(abp.localization.currentLanguage.name);
    
            if (abp.localization.currentLanguage.name === 'ms') {
                return new Promise<boolean>((resolve, reject) => {
                    import(`assets/ngx-bootstrap/custom-i18n/ms.js`)
                        .then(module => {
                            defineLocale(abp.localization.currentLanguage.name.toLowerCase(), module[`msLocale`]);
                            resolve(true);
                        }, reject);
                });
            }
    
            return new Promise<boolean>((resolve, reject) => {
                import(`ngx-bootstrap/chronos/esm5/i18n/${supportedLocale}.js`)
                    .then(module => {
                        defineLocale(abp.localization.currentLanguage.name.toLowerCase(), module[`${moduleLocaleName}Locale`]);
                        resolve(true);
                    }, reject);
            });
        }
    

    As you can see, in Promise ms.js file import function we call your ms.js module name as msLocale, this is an exported variable declared in your ms.js file.

    If you can't find your moment culture js file in this link: moment.js locales

    Simply write yourself, this is a official tutorial: moment.js customization