Search code examples
angulardatepickerng-bootstrap

Angular 18 ngbDatepicker doesn't update value with ngModel


I try using ngbDatepicker, but I cannot get it to work with ngModel. It won't update the related variable, nor will it draw its value from it.

Here are some simple steps how to reproduce my problem from scratch.

I've created a new Angular 18 app like this:

ng new try-app

I've selected SCSS and No Server-Side Rendering.

Then I've installed ng-bootstrap like this:

npm install @ng-bootstrap/[email protected]

Then I've edited try-app\src\app\app.component.ts - it turned out to be like this:

import { Component } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { NgbDateStruct, NgbModule } from '@ng-bootstrap/ng-bootstrap';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [FormsModule, NgbModule],
  templateUrl: './app.component.html',
  styleUrl: './app.component.scss'
})
export class AppComponent {
    myDate?: NgbDateStruct;
    show() {
        console.log(this.myDate);
        alert(this.myDate);
    }
}

Then I've edited try-app\src\app\app.component.html - it turned out to be like this:

<input class="form-control" name="myDate" [(ngModel)]="myDate" ngbDatepicker #myDate="ngbDatepicker" (click)="myDate.toggle()" readonly />
<input type="button" (click)="show()" value="Show" />

Then I ran my app with ng serve.

When I select a date using the datepicker input field, let's say 2025-01-06 and then click the Show button, it says undefined.

If I then try to give an initial value to myDate, like this:

myDate: NgbDateStruct = {year: 2000, month: 2, day: 10}

The date value in the myDate variable doesn't show up in the input field.


Solution

  • There is a name collision in the template. In the template, you declare a local variable #myDate pointing to the datePicker, and you declare the date in the .ts file with the same name. If you change the name of one of these, it will work as expected. e.g.:

    <input class="form-control" name="myDate" [(ngModel)]="myDate" ngbDatepicker #myDatePicker="ngbDatepicker" (click)="myDatePicker.toggle()" readonly />