angulartypescriptangular18

Why is the value from the input immediately displayed? How to fix it?


Why is the value I enter into the input field immediately displayed, instead of appearing after I click the add button?"

The issue is that inputValue is being immediately bound to the app-new-todo component via two-way binding using [(ngModel)]="inputValue". As a result, the entered value is displayed as soon as the user types into the input field. I would like it to only appear after clicking the "ADD" button.

How can I adjust the code to prevent the immediate display and ensure that the task only shows up after the button click?

Here is code:

  export interface TodoData {
  id: number;
  todo: string;
  done: boolean;
}
export class TodoComponent {
  @Output() todo = new EventEmitter<TodoData>();
  inputValue = '';
  done = false;

  addTask() {
    this.todo.emit({
      id: Math.floor(Math.random() * 1000),
      todo: this.inputValue,
      done: this.done,
    });
  }
}

HTML:
<section>
  <form (ngSubmit)="addTask()">
    <div>
      <input
        name="todo"
        type="text"
        placeholder="Enter new task"
        [(ngModel)]="inputValue"
      />
      <button>ADD</button>
    </div>
  </form>
  <app-new-todo [task]="inputValue" />
</section>


export class AppComponent {
  onAddTask(data: { id: number; todo: string; done: boolean }) {
    console.log(data.todo);
  }
}

HTML: 
<app-header />
<app-todo (todo)="onAddTask($event)" />

export class NewTodoComponent {
  @Input({ required: true }) task!: string;
}

HTML:
<div>
  <h1>{{ task }}</h1>
</div>



Solution

  • You are using two-way data binding which updates the property immediately.

    The sample project is managed on Stackblitz.

    File: todo.component.html

    <div *ngIf="task">
      <!-- Only display if task is not empty -->
      <h1>{{ task }}</h1>
    </div>
    
    

    File: todo.component.ts

    @Input({ required: true }) task!: string;
    

    File: new-todo.component.html

    <section>
      <form (ngSubmit)="addTask()">
        <div>
          <input
            name="todo"
            type="text"
            placeholder="Enter new task"
            [(ngModel)]="inputValue"
          />
          <button type="submit">ADD</button>
        </div>
      </form>
    </section>
    

    File: new-todo.component.ts

    export class NewTodoComponent {
      @Output() todo = new EventEmitter<TodoData>();
      inputValue = '';
      done = false;
    
      addTask() {
        // Emit the todo task only when Add button is clicked
        this.todo.emit({
          id: Math.floor(Math.random() * 1000),
          todo: this.inputValue,
          done: this.done,
        });
        // Optionally clear the input field after adding the task
        this.inputValue = '';
      }
    }
    
    export interface TodoData {
      id: number;
      todo: string;
      done: boolean;
    }
    

    app.component.html

    <app-todo [task]="taskToDisplay"></app-todo>
    <app-new-todo (todo)="onAddTask($event)"></app-new-todo>
    

    app.component.ts

    taskToDisplay: string = '';
    
    onAddTask(data: TodoData) {
      // Set the task to be passed to the new-todo component
      this.taskToDisplay = data.todo;
      console.log(data.todo);
    }
    

    NOTE: Don't forget to add the necessary imports