I am working on an e-commerce app who's front-end is made in Angular 13.
I use a CartService
service to add products to the cart (app\services\cart.service.ts
):
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';
import { Product } from '../models/product';
@Injectable({
providedIn: 'root'
})
export class CartService {
subject = new Subject();
product: Product | undefined;
constructor() { }
sendProductTocart(product: Product) {
this.subject.next(product);
}
}
In app\components\product-item\product-item.component.ts
I have:
import { Component, OnInit, InputDecorator, Input } from '@angular/core';
import { Product } from '../../models/product';
import { CartService } from '../../services/cart.service';
@Component({
selector: 'app-product-item',
templateUrl: './product-item.component.html',
styleUrls: ['./product-item.component.css']
})
export class ProductItemComponent implements OnInit {
@Input() product!: Product;
@Input() handleAddToCart!: (args: any) => void;
constructor(private cartService: CartService) { }
addToCart(product: Product) {
console.log(this.cartService.product);
}
ngOnInit(): void {
}
}
In app\components\add-to-cart\add-to-cart.component.ts
I have:
import { Component, OnInit, InputDecorator, Input } from '@angular/core';
import { Product } from '../../models/product';
import { listenerCount } from 'process'
@Component({
selector: 'app-add-to-cart',
templateUrl: './add-to-cart.component.html',
styleUrls: ['./add-to-cart.component.css']
})
export class AddToCartComponent implements OnInit {
@Input() product!: Product;
@Input() handleAddToCart!: (args: any) => void;
constructor() { }
ngOnInit(): void {
}
}
In app\components\add-to-cart\add-to-cart.component.html
:
<button (click)="handleAddToCart(product)">Add</button>
Stackblitz
See Stackblitz demo here.
The problem
For a reason I have not been able to find out, when I click the "Add to cart" button in the product list, I get this error in the Ghrome console:
Cannot read properties of undefined
Where is my mistake?
CodePudding user response:
You need to add the product:
now:
<div >
<app-add-to-cart [handleAddToCart]="addToCart"></app-add-to-cart>
</div>
should be:
<div >
<app-add-to-cart [handleAddToCart]="addToCart"
[product]="product"></app-add-to-cart>
</div>
CodePudding user response:
You're doing this, passing function down to child
<div >
<app-add-to-cart [handleAddToCart]="addToCart"></app-add-to-cart>
</div>
But in your child component
@Component({
selector: 'app-add-to-cart',
templateUrl: './add-to-cart.component.html',
styleUrls: ['./add-to-cart.component.css']
})
export class AddToCartComponent implements OnInit {
@Input() product!: Product;
@Input() handleAddToCart!: (args: any) => void;
constructor() { }
ngOnInit(): void {
}
}
the service cartService
doesn't exist. So it's throwing error
ERROR Error: this.cartService is undefined
(in firefox)
Alternative
Use an event emitter to pass the data up and handle event in parent.
export class AddToCartComponent {
@Input() product!: Product;
@Output() productAdded: EventEmitter<Product> = new EventEmitter();
constructor() { }
ngOnInit(): void {
}
handleAddToCart(product: Product) {
this.productAdded.emit(product)
}
}
<app-add-to-cart (productAdded)="addToCart($event)"></app-add-to-cart>