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

Prevent selection of past dates and times in ng-bootstrap calendar in Angular 7

HTML <ngb-datepicker (select)="onDateSelect($event)" [(ngModel)]="datePickerModel"></ngb-datepicker> <ngb-timepicker [meridian]="meridian" [(ngModel)]="time" class="fromTimePick"> </ngb-timepicker> Is it possible to restrict the ...

Understanding the tsconfig.json file in an Angular project

I encountered the following error in my tsconfig.ts file: 'No inputs were found in config file 'c:/Projects/Angular2//src/tsconfig.json'. Specified 'include' paths were '["src/**/*.ts"]' and 'exclude' paths ...

TypeScript struggling to recognize specified types when using a type that encompasses various types

I have a defined type structure that looks like this: export type MediaProps = ImageMediaProps | OembedProps; Following that, the types it references are defined as shown below: type SharedMediaProps = { /** Type of media */ type: "image" | "oembed"; ...

Upon being redirected to a different route, it immediately navigates back to the previous page

Whenever we redirect to a route using an anchor tag with [routerLink], or through the code using: router.navigate(['/path']) For example, if we redirect to the extractedData page from the result page, it initially shows the extractedData page b ...

Reducing image file sizes in Ionic 3

I have been struggling to compress an image client-side using Ionic 3 for the past couple of days. I have experimented with: ng2-img-max - encountered an error when utilizing the blue-imp-canvas-to-blob canvas.toBlob() method (which is a dependency of ng2 ...

Encountered an error when creating my own AngularJS module: Unable to instantiate

Attempting to dive into TypeScript and AngularJS, I encountered a perplexing error after following a tutorial for just a few lines. It appears that there may be an issue with my mydModule? angular.js:68 Uncaught Error: [$injector:modulerr] Failed to inst ...

steps to authenticate with dynamic database information instead of hard-coded data

After following a tutorial, I successfully created my first register login system in dot net and angular. The issue I encountered is that the author used static data in the tutorial's code example. However, I want to implement my own database data. As ...

Troubleshooting Tips: Investigating a Service Call in AngularJS 2 using ES6 Syntax

MY DILEMMA: I have recently started learning Angular2 and found myself wanting to debug a service call. The service appears to have been properly called, as evidenced by the view display. However, when trying to log the content of the variable holding t ...

Navigating session discrepancies: Combining various social media platforms using Next.js and NextAuth

Recently, I ran into a problem where, upon logging in with Google, I found myself needing access tokens for Twitter and LinkedIn to send out API requests. The issue came about when NextAuth modified my session data to be from either Twitter or LinkedIn ins ...

Rx.js struggles to access historical values

Seeking assistance with retrieving the last 3 values emitted. Despite using the provided code to populate uiOrder and invoking cancelOrderItem() multiple times, I am unable to access the last 3 revisions of the order via getHistory(). Instead, I receive th ...

Issues with the linear-gradient feature in Ionic3 are preventing it from properly functioning

I'm currently experimenting with creating a unique gradient color in my Ionic3 variable.sass file. $colors: ( primary: #4471C1, secondary: #32db64, danger: #f53d3d, light: #f4f4f4, dark: #222, newcolor: linear-gradient( ...

Exploring the dynamics of parent and child components in Angular

I'm currently working on an Angular2 project and I've hit a roadblock with the parent/child component interaction. My goal is to have a "Producer" entity that can have multiple "Products". Ultimately, I aim to retrieve lists of products associat ...

Using ngrx to automatically update data upon subscription

Background The technology stack I am using for my application includes Angular 4.x, ngrx 4.x, and rxjs 5.4.x. Data is retrieved from a websocket as well as a RESTful API in order to share it between multiple components through ngrx. Currently, data is ref ...

There seems to be an issue with the type error regarding the return of the mysql2/promise

As I delve into using the mysql2/promise library with Typescript, I've encountered a puzzling issue regarding the return type of the query method. Despite my best efforts, I can't seem to resolve an error in my code. Here is a snippet from my c ...

Can anyone provide guidance on setting up systemjs to identify an app path specific to the environment?

I recently developed a web application using Angular and angular-cli. It works perfectly fine when running it with ng serve. Now, I have the task of deploying it on Tomcat. The catch is that it needs to be accessible through a different path because my We ...

Upon successfully maneuvering vendors who fail to load the NEXT.JS Link

Here is an image that is not displaying properly. The navbar's responsiveness seems to be causing the issue. return ( <Link key={index} href={'/'+item.id} > <li className="nav-item dropdown position-stati ...

Intercepting HTTP requests on specific routes with Angular 4+ using an HTTP Interceptor

I've developed an HTTP_INTERCEPTOR that needs to function on certain routes while excluding others. Initially, it was included in the main app module file. However, after removing it from there and adding it to specific modules, the interceptor conti ...

Utilize an exported class as a type within a .d.ts file

I have two classes, ./class1.ts and ./class2.ts, with the following structure: export class Class1{ ... } and export class Class2{ ... } In my file ./run.ts, there is a function that accepts a class input function doSomething(klass: ClassType){ l ...

Transforming JavaScript code with Liquid inline(s) in Shopify to make it less readable and harder to understand

Today, I discovered that reducing JavaScript in the js.liquid file can be quite challenging. I'm using gulp and typescript for my project: This is a function call from my main TypeScript file that includes inline liquid code: ajaxLoader("{{ &ap ...

Angular Material Dropdown with Option to Add New Item

Currently, I am utilizing Angular material to create a select dropdown for Religion. However, the available options may not encompass all the religions practiced worldwide. In order to account for this limitation, I aim to incorporate an "other option" tha ...