What is the best way to implement a custom NgbDateParserFormatter from angular-bootstrap in Angular 8?

Currently, I am working on customizing the appearance of dates in a form using Angular-Bootstrap's datepicker with NgbDateParserFormatter. The details can be found at here.

My goal is to display the date in the format of year-month-day in the form field and present it as day/month/year. To achieve this, I have implemented the following code in the component:

<...>
@Injectable()
export class CustomAdapter extends NgbDateAdapter<string> {

    readonly DELIMITER = '-';

    fromModel(value: string | null): NgbDateStruct | null {
        console.log('fromModel start', value);
        if (value) {
            let date = value.split(this.DELIMITER);
            return {
                day: parseInt(date[0], 10),
                month: parseInt(date[1], 10),
                year: parseInt(date[2], 10)
            };
        }
        return null;
    }

    toModel(date: NgbDateStruct | null): string | null {
        console.log('toModel start', date);
        let res: string = date ?
            date.year + this.DELIMITER + (date.month + '').padStart(2, "0") + this.DELIMITER + (date.day + '').padStart(2, "0")
            : null;
        console.log('toModel end', res);
        return res;
    }
}

@Injectable()
export class CustomDateParserFormatter extends NgbDateParserFormatter {

    readonly DELIMITER = '/';

    parse(value: string): NgbDateStruct | null {
        console.log('parser start', value);
        if (value) {
            let date = value.split(this.DELIMITER);
            console.log('parser end', date);
            return {
                day: parseInt(date[0], 10),
                month: parseInt(date[1], 10),
                year: parseInt(date[2], 10)
            };
        }
        return null;
    }

    format(date: NgbDateStruct | null): string {
        console.log('formatter start', date);
        let res: string = date ?
             (date.day + '').padStart(2, "0") + this.DELIMITER + (date.month + '').padStart(2, "0") + this.DELIMITER + date.year
            : null;
        console.log('formatter end', res);
        return res;
    }
}

@Component({
    <...>
    providers: [
        { provide: NgbDateAdapter, useClass: CustomAdapter },
        { provide: NgbDateParserFormatter, useClass: CustomDateParserFormatter }
    ]
})
export class MyComponent implements OnInit {
    myForm: FormGroup;
    <...>
    dpModel: any;

    constructor(
        <...>
        private ngbCalendar: NgbCalendar,
        private dateAdapter: NgbDateAdapter<string>
    ) {
        this.myForm = this.formBuilder.group({
            <...>
            date: [''],
            <...>
        });
    }

For template implementation:

<div class="form-group">
    <label for="data" class="col-form-label">Date:</label>
    <div class="input-group">
      <input class="form-control" placeholder="dd/mm/yyyy"
            name="data" [(ngModel)]="dpModel" 

            ngbDatepicker #d="ngbDatepicker" formControlName="data">
      <div class="input-group-append">
           <button class="btn btn-outline-secondary fa fa-calendar-alt" (click)="d.toggle()"></button>
      </div>
    </div>
</div>

After clicking on a date within the datepicker, these are the debug outputs from the code included:

toModel start NgbDate {year: 2020, month: 6, day: 18}
toModel end 2020-06-18
fromModel start 2020-06-18
formatter start null
formatter end null
toModel start null
toModel end null
fromModel start null
fromModel start 2020-06-18
In analyzing the output, there seems to be an issue where the component passes null to the formatter. Additionally, after selecting a date, a red line appears beneath the datepicker. I have experimented with different approaches like using myform.date instead of dpModel without success. I am currently utilizing Angular 8 for this project.

Answer №1

Instead

fromModel(value: string | null): NgbDateStruct | null {
    console.log('fromModel start', value);
    if (value) {
        let date = value.split(this.DELIMITER);
        return {
            day: parseInt(date[0], 10),
            month: parseInt(date[1], 10),
            year: parseInt(date[2], 10)
        };
    }
    return null;
}

recommend

fromModel(value: string | null): NgbDateStruct | null {
    if (value) {
        let date = value.split(this.DELIMITER);
        return {
            year: parseInt(date[0], 10),
            month: parseInt(date[1], 10),
            day: parseInt(date[2], 10)
        };
    }
    return null;
}

PS.: Keep in mind the year<->day switcharoo

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Empty array being returned by Mongoose after calling the populate() function

I've been struggling for the past 3-4 hours, banging my head against the wall and scouring countless articles here on StackOverflow, but I just can't seem to get my response to populate an array correctly. I'm working with Express.js, Typesc ...

Receiving constant errors on Search Input in React: continuously encountering the error "Cannot read property 'value' of undefined."

Attempting to incorporate the < ChipInput /> element from https://github.com/TeamWertarbyte/material-ui-chip-input. Using material-UI react component, my current setup includes: A functional search input bar. When an artist's name is typed, it ...

Angular application triggering multiple subscribe method calls upon a link click event

Here is the code for my navbar component: <li *ngFor="let item of menu"> <a *ngSwitchCase="'link'" routerLinkActive="active" [routerLink]="item.routerLink" (click)="Navigation(item.title)&q ...

Using asynchronous import statements in Vue allows for more efficient loading of components

I am using Vue and have a method in my file called load.js. async function loadTask(x) { return await x; // Some async code } export { loadTask }; In one of my Vue components, I call the method but encounter an issue where the use of await prevents the ...

Is there a way to position the Image component from next/image using absolute positioning?

Is it possible to use an element Image from 'next/image' with the CSS style { position: absolute; left: 50% }? It appears that it is not being applied. For example: import React from 'react' import Image from 'next/image' imp ...

Sending form data using javascript without refreshing the page

I have a wall/social system similar to Facebook where users can post statuses. I want to add the functionality for users to like, dislike, and comment on a status without the page reloading. How can I achieve this with the form below? if(empty($_GET[&apos ...

Retrieving user input in Angular and showcasing extracted keywords

I want to give users the flexibility to customize the format of an address according to their preference. To achieve this, there will be a text input where users can enter both keywords and regular text. The goal is to detect when a keyword is entere ...

JavaScript: Share module contents internally through exporting

When working with Java, there are 4 different visibility levels to consider. In addition to the commonly known public and private levels, there is also the protected level and what is referred to as the "default" or "package-local" level. Modifier Clas ...

Building a MEAN stack application using Angular 5 and implementing passportJS for authentication

What's the process for implementing authentication in a MEAN stack using Angular 5, Node.js, and Passport.js? ...

What are some ways to incorporate texture into objects using three.js?

Having trouble adding texture to my central sphere (earth) without the object disappearing. Can someone provide guidance on where I might be making a mistake? Your help is appreciated. For reference, here is the link to my jsbin http://jsbin.com/cabape/edi ...

Stop the page from scrolling when a modal is displayed in React

I've encountered an issue with my custom modal component where the background stops scrolling when the modal is open. Initially, I attempted to solve this by using the following code: componentDidMount() { document.body.style.overflow = 'hi ...

Is it possible to pass a parameter to a PHP controller using JavaScript without relying on jQuery or AJAX?

Is it possible to achieve the task at hand? That's the main question here. My goal is to extract data from a popup window and then, upon closing it, send this extracted content to a PHP controller for further processing. I'm facing conflicts wi ...

directive does not execute when the <Enter> key is pressed

I recently came across a helpful post on Stack Overflow about creating an Enter keypress directive. After following the instructions, here is my JavaScript code that replicates the functionality: JavaScript var app = angular.module('myApp', [] ...

When functions are sent to children of a react component, they do not inherit the context of the parent

I'm facing an issue while working with React where I am encountering difficulty passing a function from a parent component to multiple children components. The function calls other functions that are also housed within the parent component. Although ...

Surprising outcome from the glob-fs glob.readdirSync function

Below is some nodejs code that I am working with. The client initially calls /api/demosounds and then calls /api/testsounds. var glob = require('glob-fs')({ gitignore: true }); app.get('/api/demosounds',function(req,res){ var d ...

Is there a way to have one element automatically expand when another is selected?

I'm currently utilizing the date and time picker from . However, I need some assistance with the current setup. Currently, the date and time pickers are in separate input fields. In order to select a date, I have to click on the Date input field, and ...

When integrating AngularJS with CKEditor, an error regarding module dependency injection may occur, causing the following message to be displayed:

Just starting out with Angularjs and attempting to integrate Ckeditor into my webapp. Currently encountering the following error: Uncaught Error: [$injector:modulerr] http://errors.angularjs.org/1.5.8/$injector/modulerr?p0=editor&p1=Error%3A%…Flo ...

observing which specific element corresponds to the nth child?

Exploring the concept illustrated in https://api.jquery.com/eq/, imagine a scenario with the following HTML structure: <ul> <li>list item 1</li> <li>list item 2</li> <li>list item 3</li> <li>list item ...

By default, all groups in the Kendo UI Angular 2 Grid are collapsed

Just started using the new Kendo UI for Angular 2 Grid and I have a question - is it possible to collapse all groups by default when grouping data? I noticed there is a method called collapseGroup(), but it's unclear how to use it or if there's ...

Active Angular component utilizing *ngIf during the programmatically lazy loading of a Module

I find myself in a situation where I need to load numerous components on a specific route within my application. These components are controlled by a logic with *ngIf directives that allow me to show or hide them dynamically. For instance: <div *ngIf=& ...