I have a form where I am asking the user to fill out information about a grocery item threy want to add to their cart. Then they hit the add button item.
From my app.component.html
<form (ngSubmit)="addItem()">
<label for="newItemName">Item Name:</label>
<input type="text" [(ngModel)]="newItemName" id="newItemName" required>
<label for="newItemPrice">Price:</label>
<input type="number" [(ngModel)]="newItemPrice" id="newItemPrice" required>
<label for="newItemQuantity">Quantity:</label>
<input type="number" [(ngModel)]="newItemQuantity" id="newItemQuantity" required>
<button type="submit">Add Item</button>
</form>
I also have it so they can remove items from the shopping cart.
From my app.component.html
<tbody>
<tr *ngFor="let item of cartItems">
<td>{{item.name}}</td>
<td>{{item.price | currency}}</td>
<td>
<input type="number" [(ngModel)]="item.quantity" (change)="updateQuantity(item)" min="1">
</td>
<td>{{item.total | currency}}</td>
<td>
<button (click)="removeItem(item)">Remove</button>
</td>
</tr>
</tbody>
When hitting submit, nothing happens and no errors show up in the console.
My app.component.ts:
import { Component } from '@angular/core';
interface CartItem {
name: string;
price: number;
quantity: number;
total: number;
}
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
cartItems: CartItem[] = [];
newItemName: string = '';
newItemPrice: number = 0;
newItemQuantity: number = 0;
addItem() {
if (this.newItemName && this.newItemPrice && this.newItemQuantity) {
const newItem: CartItem = {
name: this.newItemName,
price: this.newItemPrice,
quantity: this.newItemQuantity,
total: this.newItemPrice * this.newItemQuantity
};
this.cartItems.push(newItem);
this.newItemName = '';
this.newItemPrice = 0;
this.newItemQuantity = 0;
}
}
updateQuantity(item: CartItem) {
item.total = item.price * item.quantity;
}
removeItem(item: CartItem) {
const index = this.cartItems.indexOf(item);
if (index !== -1) {
this.cartItems.splice(index, 1);
}
}
calculateGrandTotal() {
let grandTotal = 0;
for (const item of this.cartItems) {
grandTotal += item.total;
}
return grandTotal;
}
}
My app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms'; // Import FormsModule for form handling
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
FormsModule, // Add FormsModule for form handling
AppRoutingModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
The items added to the cart should show up.
Now, just the template is showing, not the value of the items added.
2
Answers
I have the feeling that the
push
array function, doesn’t trigger any changes into your template HTML, it doesn’t react…I suggest you do the following:
For removing an item, I think you will not have a problem since
splice
does affect the original array, in this casecarItems
On reproducing this with v15.1.2 I got the following error on component init:
and the component properties were not bound to the form control. ie. they never changed from their default values – making the condition in
addItem()
always evaluate tofalse
.Following the directions fixed the issue. ie. either add a
name
attribute or[ngModelOptions]="{standalone: true}"
to each form control.Note that a value of
0
in either of the numeric inputs will cause the condition to evaluate tofalse
, and therefore nothing will happen.Live example: https://stackblitz.com/edit/angular-cynoqr?file=src/main.html