I created an Angular 16 front-end with C# WebAPI backend which pulls from a MySQL database. I recently added a Cart function to add items from the menu (which pulls from MySQL) into your cart. I am receiving an error that the properties are undefined when trying to add the menu item to the cart.
This is just a demo app for myself.
Thank you in advance!!
Error:
core.mjs:10920 ERROR TypeError: Cannot read properties of undefined (reading 'itemDesc') (cart-page.component.html)
Console logs in Chrome DevTools:
Angular is running in development mode.
cart.service.ts:24 Order: undefined
menu.component.ts:25 From Menu.Comp: undefined
cart-page.component.html:
<div *ngIf="cart && cart.items.length > 0" class="container">
<ul>
<li *ngFor="let product of cart.items">
<div>
<span>{{product.order.itemDesc}}</span>
</div>
</li>
</ul>
</div>
cart-page.component.ts (likely unneeded information, but just in case):
export class CartPageComponent implements OnInit {
cart!:Cart;
constructor(private cartService:CartService) {
this.setCart();
}
ngOnInit(): void {
}
setCart() {
this.cart = this.cartService.getCart();
}
removeFromCart(cartItem:CartItem) {
this.cartService.removeFromCart(cartItem.order.itemId);
this.setCart();
}
changeQuantity(cartItem:CartItem, quantityInString:string) {
const quantity = parseInt(quantityInString);
this.cartService.changeQuantity(cartItem.order.itemId, quantity);
this.setCart();
}
}
cart.service.ts (This service is logged in Chrome devtools above):
export class CartService {
private cart:Cart = new Cart();
constructor() {
}
addToCart(order:ItemDetail):void {
let cartItem = this.cart.items.find(item => item.order.itemId === order.itemId);
if(cartItem) {
this.changeQuantity(order.itemId, cartItem.quantity + 1);
return;
}
this.cart.items.push(new CartItem(order));
console.log("Order: " + order)
}
removeFromCart(itemId:number):void {
this.cart.items = this.cart.items.filter(item=>item.order.itemId != itemId);
}
changeQuantity(itemId:number, quantity:number) {
let cartItem = this.cart.items.find(item => item.order.itemId === itemId);
if(!cartItem) {
return;
}
cartItem.quantity = quantity;
}
getCart():Cart {
return this.cart;
}
menu.component.ts (This service is logged in Chrome devtools above)
export class MenuComponent {
constructor(private activatedRoute:ActivatedRoute, public service:MenuService, private cartService:CartService, private router:Router) { }
// appetizers:ItemDetail[] = [];
item!:ItemDetail;
ngOnInit(): void {
this.service.getAll();
}
addToCart() {
this.cartService.addToCart(this.item);
console.log("From Menu.Comp: " + this.item);
}
}
menu.component.html (this is where I add the item to the cart):
<tbody>
<tr *ngFor="let item of service.list">
<td>{{item.itemName}}</td>
<td>{{item.itemDesc}}</td>
<td>{{item.itemPrice }}</td>
<td><button (click)="addToCart()">Add To Order</button></td>
</tr>
</tbody>
items.model.ts:
export class ItemDetail {
itemId:number = 0;
itemName:string = '';
itemDesc:string = '';
itemPrice:number = 0;
}
I retraced all the functions and added the console.log's to give me an idea of what was trying to be added to the cart. I tried changing itemName to itemDesc so I know it's not just one variable that's causing the issue.
It looks like the implementation of "addToCart" inside MenuComponent is not doing what you want.
That method should be passing the clicked element to the cart, but it's not actually passing the item, you're using an undefined variable.
Luckily it's a super small change, menu.component.html should look something like this:
<tbody>
<tr *ngFor="let item of service.list">
<td>{{item.itemName}}</td>
<td>{{item.itemDesc}}</td>
<td>{{item.itemPrice }}</td>
<td><button (click)="addToCart(item)">Add To Order</button></td>
</tr>
</tbody>
And menu.component.ts should be:
export class MenuComponent {
constructor(private activatedRoute:ActivatedRoute, public service:MenuService, private cartService:CartService, private router:Router) {
}
ngOnInit(): void {
this.service.getAll();
}
addToCart(item:ItemDetail) {
this.cartService.addToCart(item);
}
}