angulardata-binding

ngModel gives error on build project in Angular


I am using angular 19 and getting error in building project. My app.component.html is

<div>
  <div className="navbar">
    <nav >
      <ul>Todo App</ul>
    </nav>
  </div>


  <div className = "heading" id = "headingBegin">
    <div >Put your todo items here</div>
  </div> 

<div id = "headingForm">
  <form action="">
    <label for="todotitle">Todo Title</label><br>
    <input [(@ngModel)]="task"  type="text" id="todoid"  value=""><br>
    <label for="desc">Todo Description </label><br>
    <input type="text" id="descname" name="descname" value=""><br><br>
    <input type="button" id="submit-btn" value="Add Todo" (click)="addTask()" >

  </form>

  @for(task of taskList; track task.id){
  <ul class="task-list">
    <li> {{task.id}}</li>
    <li> {{task.name}}</li>
    <li> <button (click)="deleteTask(task.id)">Delete</button> </li>
  </ul>
  }
</div>

</div>

My app.component.ts is -

import { Component } from '@angular/core';
import { RouterOutlet } from '@angular/router';
import { FormsModule } from '@angular/forms';

@Component({
  selector: 'app-root',
  imports: [RouterOutlet,FormsModule],
  templateUrl: './app.component.html',
  styleUrl: './app.component.css'
})
export class AppComponent {
  title = 'todoapp';
  task = "client meet at 12"
 // taskList: {id : number, name : string, desc : string, completed: boolean}[] = []
  taskList: {id : number, name : string}[] = []

  changed(){

  }
  
  addTask(){

    //let first = array.map(taskList => taskList[0]).filter(val => !isNaN(val));;
    //let max = Math.max(...first);

    this.taskList.push({id: this.taskList.length+1, name: this.task })
    this.task = "";
  }
  deleteTask(id:number){
    this.taskList = this.taskList.filter((item)=>item.id != id)
  }
}

and the error I am getting is -

 [ERROR] NG5002: The animation trigger output event (@ngModelChange) is missing its phase value name (start or done are currently supported) [plugin angular-compiler]

As you can see I am binding "task" to two way binding with input element using ngModel directive. But don't know where I have gone wrong. Installation was done without error.


Solution

  • I am not sure why you are using @ngModel for two way binding. Obviously, angular will consider it an animation. You should be using [(ngModel)] for this purpose. Make sure you import FormsModule in your component.ts class file. Overall it should look like:

    <div>
      <div class="navbar">
        <nav>
          <ul>Todo App</ul>
        </nav>
      </div>
    
      <div class="heading" id="headingBegin">
        <div>Put your todo items here</div>
      </div>
    
      <div id="headingForm">
        <form action="">
          <label for="todotitle">Todo Title</label><br>
          <input [(ngModel)]="task" type="text" id="todoid" value=""><br>
          <label for="desc">Todo Description </label><br>
          <input type="text" id="descname" name="descname" value=""><br><br>
          <input type="button" id="submit-btn" value="Add Todo" (click)="addTask()">
        </form>
    
        <ul class="task-list" *ngFor="let task of taskList; trackBy: trackByTaskId">
          <li>{{ task.id }}</li>
          <li>{{ task.name }}</li>
          <li><button (click)="deleteTask(task.id)">Delete</button></li>
        </ul>
      </div>
    </div>

    Your TS file should look somewhat like:

    import { Component } from '@angular/core';
    import { RouterOutlet } from '@angular/router';
    import { FormsModule } from '@angular/forms';
    
    @Component({
      selector: 'app-root',
      imports: [RouterOutlet, FormsModule],
      templateUrl: './app.component.html',
      styleUrls: ['./app.component.css']
    })
    export class AppComponent {
      public title: string = 'todoapp';
      public task: string = 'client meet at 12';
      public taskList: { id: number; name: string }[] = [];
    
      public addTask(): void {
        this.taskList.push({ id: this.taskList.length + 1, name: this.task });
        this.task = '';
      }
    
      public deleteTask(id: number): void {
        this.taskList = this.taskList.filter((item) => item.id !== id);
      }
    
      public trackByTaskId(index: number, task: { id: number; name: string }): number {
        return task.id;
      }
    }