Angular Material Datepicker | Lazy Loading + CustomDateAdapter + Internationalization - RangeError: Maximum call stack size exceeded

╄→гoц情女王★ 提交于 2020-05-28 06:53:45

问题


Structure Question

I'm not quite sure If I found the right place for this 2 code lines:

providers: [
    { provide: MAT_DATE_LOCALE, useValue: 'de-DE' },
    { provide: DateAdapter, useClass: CustomDateAdapter, deps: [MAT_DATE_LOCALE, Platform] }
  ]

Currently they are in my material.module => which is imported in shared.module => which is imported in app.module and every lazy loaded module.

CustomDateAdapter:

@Injectable()
export class CustomDateAdapter extends NativeDateAdapter {
    subscription: any;

    format(date: Date, displayFormat?: string | Object): string {
        if (!this.subscription) {
            this.subscription = appLocale.subscribe(v => {
                this.setLocale(v);
            })
        }
        return super.format(date, displayFormat);
    }
}

the appLocal is in my translation Service:

export const appLocale: BehaviorSubject<string> = new BehaviorSubject('de');

(I found this code working here: Blitz)

My situation is - I have a datepicker and I can switch language between three languages without reloading the site.

My problem - I have a global service for translation - so it's not like in the stackblitz above that I'm changing language in the component because this is a dropdown in the app.component. As I import material in app.module and lazy loaded module (where the datepicker is) this couldn't work because I had two instances of CustomDateAdapter and just changed the app.component one. (I hope I understood this import/export/providers stuff right..)

I think I fixed that with the BehaviorSubject and the subscription.. but is this the right way to do this? I just want to register the two providers one time globally.

Error Question

Sorry for the long structure question as it is acutally working. Unfortunately I'm getting this error.

osp-error-handler.ts:12 RangeError: Maximum call stack size exceeded
    at BehaviorSubject.push../node_modules/rxjs/internal/Observable.js.Observable._trySubscribe (Observable.js:51)
    at BehaviorSubject.push../node_modules/rxjs/internal/Subject.js.Subject._trySubscribe (Subject.js:102)
    at BehaviorSubject.push../node_modules/rxjs/internal/Observable.js.Observable.subscribe (Observable.js:30)
    at CustomDateAdapter.push../src/app/shared/plugins/material/mat-datepicker.ts.CustomDateAdapter.format (mat-datepicker.ts:40)
    at MatDatepickerInput.push../node_modules/@angular/material/esm5/datepicker.es5.js.MatDatepickerInput._formatValue (datepicker.es5.js:3259)
    at MatDatepickerInput.set [as value] (datepicker.es5.js:2961)
    at SafeSubscriber._next (datepicker.es5.js:2900)
    at SafeSubscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.SafeSubscriber.__tryOrUnsub (Subscriber.js:196)
    at SafeSubscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.SafeSubscriber.next (Subscriber.js:134)
    at Subscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber._next (Subscriber.js:77)

The error just happens first time I open the page with the datepickers. When I change the date or switching route it doesn't happen again. I think there is something wrong with:

 return super.format(date, displayFormat);

I hope someone can help :)

Edit 1 - error fixed:

Changed the format function to:

    format(date: Date, displayFormat?: string | Object): string {
        let loc = appLocale.getValue();
        if (this.locale !== loc)
            this.setLocale(loc);
        return super.format(date, displayFormat);
    }

Thanks to Sergey leading me into the right direction. If you subscribe to an BehaviorSubject you will get a lot of change calls (even if it is the same value -don't exactly know why). As it is not working without the if I think If you call setLocale the format func gets called again because of a change trigger inside - so you would never get out of this..

来源:https://stackoverflow.com/questions/56054960/angular-material-datepicker-lazy-loading-customdateadapter-internationaliz

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!