What is the functionality of ngModel in the Angular Heroes Tour tutorial?

Hello everyone, this is my first post here. I have been diving into the Angular Tour of Heroes using Angular 6 and I think I understand how ngModel works, but there's one thing that puzzles me. How does it manage to update the data in my list when the ngModel is linked to a different variable? Below is the code snippet that has been causing some confusion:

The heroes variable holds a list of mock data with each item having a type defined as Hero, consisting of an ID and a name.

A list of heroes is displayed through the use of a variable called hero.

Whenever a hero is clicked, the variable selectedHero is set to that specific Hero object.

Following this selection, the details of the chosen hero are shown below the list.

I comprehend that any changes made to selectedHero.name by using ngModel on the input field also affect the corresponding hero's name in the list. But, I am uncertain about how to prevent this auto-update from happening.

P.S. Since I'm new here, I couldn't locate any answers related to this issue. Apologies if this post isn't in the right place.

heroes.component.html

<h2>My Heroes</h2>
<ul class="heroes">
  <!--calls function when selected and changes the background color to the selected class-->
  <li *ngFor="let hero of heroes"
      (click)="onSelect(hero)"
      [class.selected]="hero === selectedHero">

    <span class="badge">{{hero.id}}</span> {{hero.name}}
  </li>
</ul>

<div *ngIf="selectedHero">
  <h2>{{ selectedHero.name }}</h2>
  <div>id: {{ selectedHero.id }}</div>
  <div>
    <label>name:
      <input [(ngModel)]="selectedHero.name" placeholder="Hero Name">
    </label>
  </div>
</div>

heroes.component.ts

import { Component, OnInit } from '@angular/core';
import { Hero } from '../hero';
import { HEROES } from '../mock-heroes';

@Component({
  selector: 'app-heroes',
  templateUrl: './heroes.component.html',
  styleUrls: ['./heroes.component.css']
})
export class HeroesComponent implements OnInit {
  heroes = HEROES;
  selectedHero: Hero; // undefined until selected
  onSelect(hero: Hero) {
    this.selectedHero = hero;
  }

  constructor() { }

  ngOnInit() {
  }

}

Heroes HTML page

Answer №1

ngModel facilitates two-way data binding, meaning that the variable selectedHeros.name in the input is directly linked to the hero-item in the list heroes. There is no separate variable for the input field. Therefore, any changes made to selectedHero.name in the input field will directly affect the value of the item in the list.

An informative explanation on two-way data binding can be found here. In the provided example, you can also express the ngModel in the input using this alternative method:

<input [value]="selektedHero.name" (input)="selektedHero.name = $event.target.value">

Although ngModel does not prevent changes to the variables in the list, you have the option to modify the input to avoid using ngModel. For instance, you can implement the following:

<input [value]="selektedHero.name"></input>

This way, you will display the value of selektedHero.name in the input field without affecting the variables in the list when the value is changed.

A comparison between the two methods can be observed below:

<input [(ngModel)]="selectedEntry">
<br/>
<input [value]="selectedEntry">
<br/>
{{selectedEntry | json}}

In the given examples, modifying the text in the first input field on your website will result in a change in the value of

selectedEntry</code). However, altering the text in the second input field will not impact the value of <code>selectedEntry
(demonstrating one-way data binding only). The concept also applies to @Input directives, where merely a reference to the current variable is established.

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

Get rid of the box-shadow that appears on the top side of mat-elevation

I placed a mat-paginator at the bottom of my mat-table which is styled with a mat-elevation-z4 class. However, when I added the mat-elevation-z4 class to the mat-paginator component as well, the upper shadow from the paginator appears to overflow onto the ...

Divide a string using multiple delimiters just one time

Having trouble splitting a string with various delimiters just once? It can be tricky! For instance: test/date-2020-02-10Xinfo My goal is to create an array like this: [test,Date,2020-02-10,info] I've experimented with different approaches, such ...

parsing objects within an HTML component in Angular

Is there a way to utilize an object as the @input parameter in HTML? For example: <app-home [param]="user.salary"></app-home> However, the type of my user object is structured like this: user:Person=new Employee(); The classes invol ...

What could be causing the QullJS delta to display in a nonsensical sequence?

The outcome showcased in the delta appears as: {"ops":[{"retain":710},{"insert":" yesterday, and she says—”\n“The clinic?","attributes":{"prediction":"prediction"}},{"del ...

Working with multiple observables in an array of properties using RXJS

I'm relatively new to using rxjs in my angular projects and I'm facing a challenge with a simple scenario. When making an http call to retrieve a group, it returns data including a list of "buddy ids", "genre ids", and a "region id". In order t ...

What is the mechanism through which ng-bootstrap incorporates the NgbRadioGroup and NgbButtonLabel into their NgbRadio directive in Angular 2?

Below is the code snippet for label: import {Directive} from '@angular/core'; @Directive({ selector: '[ngbButtonLabel]', host: {'[class.btn]': 'true', '[class.active]': 'active', &apos ...

What are the essential requirements for an Angular application to function properly with minimal dependencies?

If a new developer wants to begin learning Angular from scratch, what are the essential npm packages that they need to install in order to start building an Angular application with minimal dependencies? ...

What function does the ng-template serve when encapsulated within an ng-select component?

Upon observing various instances of ng-select, I've noticed that it often involves wrapping a ng-template, as exemplified below: <ng-select [items]="cities" [(ngModel)]="selectedCity" bindLabel="name" bindV ...

Having trouble installing Popper.js?

I have encountered an issue while attempting to install popper.js in my angular project. ng new <<project>> cd <<project>> npm install popper --save npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@^1.0.0 (node_modules&b ...

Tips for implementing a cascading dropdown feature in Angular 7 Reactive Formarray: Ensuring saved data loads correctly in the UI form

I recently found a helpful guide on stackoverflow related to creating cascading dropdowns in an Angular reactive FormArray, you can check it out here After following the instructions, I managed to achieve my desired outcome. However, I now face a new chal ...

Angular: Effective communication between components through routing and Observable binding ultimately results in the advancement of ngtsc(233

I designed an Angular Component named "crear-pedido" that exhibits a catalog of items (using row of products) and my aim is for the user to have the ability to click on the values in the ID column and navigate the application to a subordinate component kno ...

What is the best way to implement horizontal scrolling in a div with the "inertia" style?

I recently added horizontal scrolling to my website wikiprop.org, following a tutorial from another website. However, I noticed that my scroll does not have the same inertia/momentum effect where it continues scrolling after a swipe and gradually slows dow ...

The module '@angular/compiler-cli/ngcc' is missing and cannot be located while trying to run ng serve

Out of the blue, I started encountering this error. It seems to be related to a version issue with angular-cli, but I'm unable to pinpoint the exact problem. Any assistance would be greatly appreciated! npm i displays some warnings and one compiler e ...

Create a file object using content with the help of JavaScript

I am working with a file containing specific data const ics = 'BEGIN:VCALENDAR\n' + 'VERSION:2.0\n' + 'CALSCALE:GREGORIAN\n' + 'METHOD:PUBLISH\n' + 'END:VCALENDAR\n'; I am trying t ...

Error message: "The function app.functions is not a valid function in Angular Fire Functions

Currently, I am utilizing Angular v16 alongside Angular Fire v16 and Firebase v9. Following the instructions, I completed all the necessary setup steps including executing firebase login, firebase init, and converting the functions to typescript. Next, wi ...

Can one validate a single route parameter on its own?

Imagine a scenario where the route is structured as follows: companies/{companyId}/departments/{departmentId}/employees How can we validate each of the resource ids (companyId, departmentId) separately? I attempted the following approach, but unfortunate ...

Get the socket identification from ngx-socket-io

After incorporating ngx-socket-io into my project, I encountered a hurdle while attempting to obtain the socket id. Is there anyone who has knowledge on how this can be accomplished? (I am utilizing service initialization instead of the one in the app Mo ...

Angular Material 2: Sidenav does not come with a backdrop

I'm encountering an issue with the SideNav component while developing a website using Angular 2. The SideNav has 3 modes, none of which seem to affect what happens when I open it. I am trying to make the backdrop display after opening. Even though t ...

React's Material-UI ToggleButtonGroup offers a seamless way

I'm having trouble getting the ToggleButton selected property from material ui to function properly with ToggleButton. I followed the Material Ui documentation and created a StyledToggleButton as shown below: const StyledToggleButton = withStyles({ ...

The concept of a singleton design pattern is like a hidden treasure waiting to be

My approach to implementing the singleton pattern in a typescript ( version 2.1.6 ) class is as follows: export class NotificationsViewModel { private _myService: NotificationService; private _myArray: []; private static _instance: Notificatio ...