1

With Angular I am using this date time picker in loop and I need to assign a unique reference. So far I hardcode it to req_d1 but it creates some problem. I would like to know how could I set a dynamic unique reference in the loop with Angular, thanks! Remarks: the number of rows is dynamic also, it could be 0, 1 or 20, or even more.

<tr *ngFor="let row of rows; let i = index">
    <td>{{ row.name }}</td>
    <td>
        <input
            type="text"
            name="date{{i}}"
            [value]="row.planned_date"
            (blur)="updatePlannedDate(row, $event)"
            [owlDateTime]="req_d1"
            [owlDateTimeTrigger]="req_d1"
        />
        <owl-date-time
            #req_d1
            [pickerType]="'calendar'"
        ></owl-date-time>
    </td>
<td>
7
  • Most likely, using iterated variables is the wrong approach here anyway. You should probably rather bind the element to something - what is it you want to achieve?
    – maio290
    Commented Sep 2 at 10:01
  • @Pierre what is the actual problem you are facing with hardcoding, that is the main question here! Commented Sep 2 at 10:03
  • @NarenMurali in the console I have some logs from the date time picker that something is undefined: TypeError: Cannot read properties of undefined (reading 'formatString') at _OwlDateTimeInputDirective.formatNativeInputValue (danielmoncada-angular-datetime-picker.mjs:5810:138)
    – Pierre
    Commented Sep 2 at 10:07
  • @maio290 I want to display a table that contains a list of actions, 1 action per row, having a name and a planned date which should be editable, thus the date time picker in the *ngFor
    – Pierre
    Commented Sep 2 at 10:09
  • @Pierre please share the code of updatePlannedDate Commented Sep 2 at 10:10

1 Answer 1

1

It's due to some wierd bug related to using [value], instead go for [(ngModel)] of template driven angular forms. The bug does not happen, when we use this directive and it does the same thing.

        <input
            type="text"
            name="date{{i}}"
            [(ngModel)]="row.planned_date"
            *ngIf="req_d1.formatString"
            [owlDateTime]="req_d1"
            [owlDateTimeTrigger]="req_d1"
        />

Full Code:

import { Component, importProvidersFrom } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
import { provideAnimations } from '@angular/platform-browser/animations';
import { CommonModule } from '@angular/common';
import {
  OwlDateTimeModule,
  OwlNativeDateTimeModule,
} from '@danielmoncada/angular-datetime-picker';
import { ReactiveFormsModule, FormsModule } from '@angular/forms';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [
    CommonModule,
    OwlDateTimeModule,
    OwlNativeDateTimeModule,
    ReactiveFormsModule,
    FormsModule,
  ],
  template: `
    <div *ngFor="let row of rows;trackBy: trackByFn; let i = index">
    <div>{{ row.name }}</div>
    <div>
        <owl-date-time
            #req_d1="owlDateTime"
            [pickerType]="'calendar'"
        ></owl-date-time>
        <input
            type="text"
            name="date{{i}}"
            [(ngModel)]="row.planned_date"
            *ngIf="req_d1.formatString"
            [owlDateTime]="req_d1"
            [owlDateTimeTrigger]="req_d1"
        />
    </div>
<div>
  `,
})
export class App {
  rows = [
    { name: 1, planned_date: new Date() },
    { name: 2, planned_date: new Date() },
    { name: 3, planned_date: new Date() },
    { name: 4, planned_date: new Date() },
  ];

  trackByFn(index: number) {
    return index;
  }
}

bootstrapApplication(App, {
  providers: [
    provideAnimations(),
    importProvidersFrom([OwlDateTimeModule, OwlNativeDateTimeModule]),
  ],
});

Stackblitz Demo

1
  • 1
    You are right, using ngModel fixes this, thanks a lot!
    – Pierre
    Commented Sep 2 at 11:58

Not the answer you're looking for? Browse other questions tagged or ask your own question.