TopBanana9000
TopBanana9000

Reputation: 898

Angular Material DatePicker not Changing when Moment locale does

Details: Angular Material 7 DatePicker with moment js

Problem: When the language of my web application is changed, the datepickers do not change locale.

Desired result: Every time I change the language in my application, my date pickers should also change to that locales format and language. At the moment, I need to toggle between dd/MM/yyyy and MM/dd/yyyy.

Could anyone point me in the right direction? I am new to moment and cannot seem to get the formatting done properly.

Code:

HTML

<mat-form-field>
  <mat-label>From date</mat-label>
  <input name="fromDate" [min]="minDate" [max]="maxDate" [formControl]="displayFromDate" 
                     matInput [matDatepicker]="fromDatePicker">
  <mat-datepicker-toggle matSuffix [for]="fromDatePicker"></mat-datepicker-toggle>
  <mat-datepicker #fromDatePicker disabled="false"></mat-datepicker>
</mat-form-field>

Some of my translation service code that changes the moment locale: the lang parameter will either be 'en' or 'fr' and is toggled by a switch that the app is listening to.

public use(lang: string): void {
  this._currentLang = lang;
  moment.locale(lang);      
  this.currentLang$.next(this.currentLang);
}

App.module.ts

import { MAT_MOMENT_DATE_FORMATS, MomentDateAdapter } from '@angular/material-moment-adapter';

import { DateAdapter, MAT_DATE_FORMATS, MAT_DATE_LOCALE } from '@angular/material/core';

import localeFr from '@angular/common/locales/fr';
import localeEn from '@angular/common/locales/en';

registerLocaleData(localeFr);
registerLocaleData(localeEn);

...

imports: [
BrowserModule,
FormsModule,
ReactiveFormsModule,

...

{ provide: DateAdapter, useClass: MomentDateAdapter, deps: [MAT_DATE_LOCALE] },
{ provide: MAT_DATE_FORMATS, useValue: MAT_MOMENT_DATE_FORMATS },],

Component code using the datepicker:

this.translationService.currentLang$.subscribe(currentLang => {      
  this.displayFromDate = new FormControl({ value: moment(this.displayFromDate.value).format(), disabled: true });
  console.log('displayFromDate', this.displayFromDate);
});

Upvotes: 2

Views: 7216

Answers (3)

Maickel Bourscheid
Maickel Bourscheid

Reputation: 13

I solved all, all my datetime problems like this:

npm remove moment
npm remove @angular/material-moment-adapter
npm i @angular/material-luxon-adapter

in app.module.ts:

import { LuxonDateAdapter, MAT_LUXON_DATE_ADAPTER_OPTIONS, MAT_LUXON_DATE_FORMATS } from '@angular/material-luxon-adapter';

providers: [
     {provide: MAT_DATE_LOCALE, useValue: 'default'},
     {provide: DateAdapter, useClass: LuxonDateAdapter, deps: [MAT_DATE_LOCALE, MAT_LUXON_DATE_ADAPTER_OPTIONS]},
     {provide: MAT_DATE_FORMATS, useValue: MAT_LUXON_DATE_FORMATS}
    ]

Edit chrome://settings/languages for tests

Upvotes: 0

Pinaki
Pinaki

Reputation: 1030

You can call moment.tz.guess() with an optional boolean argument "ignoreCache". If set to true, the cache will be ignored and overwritten with the new value.

Moment doc URL - https://momentjs.com/timezone/docs/#/using-timezones/guessing-user-timezone/

Working example - https://codesandbox.io/s/material-date-locale-jyylz

Upvotes: 0

TopBanana9000
TopBanana9000

Reputation: 898

I missed this in the angular documentation. If anyone else comes across this digging for the same information, make sure you're using the data adapter to set your locale.

constructor(private adapter: DateAdapter<any>) {}

toggleLocale() {
  this.adapter.setLocale(moment.locale());
}

Upvotes: 2

Related Questions