I am working on a shopping cart application. I'm facing issue while displaying the user selected products in the cart.component.html, as the data is not rendering. DOM is being created every time but the data is not displaying in the cart.component.html ? can anyone suggest how to solve this problem ?
cart.component.html
`
<ng-container *ngIf="products.length !=0">
<div >
<div >
<div >
<table >
<thead>
<tr>
<th>Sr.No</th>
<th>Product Name</th>
<th>Product Image</th>
<th>Description</th>
<th>Price</th>
<th>Quantity</th>
<th>Total</th>
<!-- <th>Action</th> -->
</tr>
</thead>
<tbody>
<tr *ngFor="let item of products; let i = index">
<td>{{ i 1 }}</td>
<td>{{ item.title }}</td>
<td>
<img style="width: 120px" src="{{ item.image }}" alt="" />
</td>
<td style="width: 25%">{{ item.description }}</td>
<th style="width: 12%">{{ item.price }}</th>
<td style="width: 12%">{{ item.quantity }}</td>
<td style="width: 12%">{{ item.total }}</td>
<td>
<!-- <button (click)="removeItem(item)" ><i ></i></button> -->
<!-- </td> -->
</td>
</tr>
<tr>
<td colspan="4"></td>
<!-- <td><button (click)="emptycart()" >Empty Cart</button></td> -->
<td>
<button routerLink="/products" >
Shop More
</button>
</td>
<!-- <td><button >Checkout</button></td> -->
<td>
<strong>Grand Total : ${{ grandTotal }}</strong>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</ng-container>
<ng-container *ngIf="products.length == 0">
<div >
<div >
<h5 >My Cart</h5>
</div>
<div >
<img
src="https://rukminim1.flixcart.com/www/800/800/promos/16/05/2019/d438a32e-765a-4d8b-b4a6-520b560971e8.png?q=90"
alt=""
/>
<h4>Your cart is empty!</h4>
<h6>Add item to it now</h6>
<button routerLink="/products" >Shop Now</button>
</div>
</div>
</ng-container>
cart.component.ts
`
import { Component, OnInit } from '@angular/core';
import { NavbarserviceService } from 'src/app/navbarservice.service';
import { CartService } from 'src/app/service/cart.service';
@Component({
selector: 'app-cart',
templateUrl: './cart.component.html',
styleUrls: ['./cart.component.css']
})
export class CartComponent implements OnInit {
public products : any = [];
public grandTotal !: number;
constructor(private cartService : CartService, public nav: NavbarserviceService) { }
ngOnInit(): void {
this.nav.show();
this.cartService.getProducts()
.subscribe(res=>{
this.products = res;
this.grandTotal = this.cartService.getTotalPrice();
});
}
// removeItem(item: any){
// this.cartService.removeCartItem(item);
// }
// emptycart(){
// this.cartService.removeAllCart();
// }
}
cart.service.ts
`
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
import { HttpClient } from '@angular/common/http';
import { LoginService } from '../component/login/login.service';
import { UserCart } from './cart';
import { item } from './product';
@Injectable({
providedIn: 'root'
})
export class CartService {
public cartItemList: any = []
public productList = new BehaviorSubject<any>([]);
public search = new BehaviorSubject<string>("");
constructor(private http: HttpClient, private login: LoginService) {
console.log ("constrcutor called")
}
populateDataFromBackend() {
console.log ("populateDataFromBackend called")
var cartItemListLocal: any = []
//return this.productList.asObservable();
//Return data from backend
var apiRequest: string = "http://localhost:3000/userCart?emailId=" this.login.loggedInUserID;
this.http.get<UserCart[]>(apiRequest)
.subscribe(res => {
console.log(res);
res.forEach(element => {
console.log(element.emailId, element.productId);
var getProductAPI: string = "http://localhost:3000/products?id=" element.productId;
this.http.get<item>(getProductAPI).subscribe(res => {
//
console.log(res);
cartItemListLocal.push(res);
// this.productList.next (res);
// productListNew.next (cartItemListLocal);
})
});
}
)
console.log("cartItemsLocal\n");
console.log(cartItemListLocal);
this.productList.next(cartItemListLocal);
}
getProducts() {
this.populateDataFromBackend();
return this.productList.asObservable();
}
setProduct(product: any) {
this.cartItemList.push(...product);
this.productList.next(product);
}
addtoCart(product: any) {
var cartItem = new UserCart(this.login.loggedInUserID, product.id);
console.log(cartItem, "cartItem");
this.http.post("http://localhost:3000/userCart", cartItem).subscribe(
(data) => {
console.log("Datasent to cart ", data);
}
)
/*
this.cartItemList.push(cartItem);
this.productList.next(this.cartItemList);
this.getTotalPrice();
console.log(this.cartItemList,"this.cartItemlist")
this.http.post("http://localhost:3000/userCart",this.cartItemList).subscribe(
(data) => {
console.log("Datasent to cart ",data);
}
)
*/
}
getTotalPrice(): number {
let grandTotal = 0;
this.cartItemList.map((a: any) => {
grandTotal = a.total;
})
return grandTotal;
}
// removeCartItem(product: any){
// this.cartItemList.map((a:any, index:any)=>{
// if(product.id=== a.id){
// this.cartItemList.splice(index,1);
// }
// })
// this.productList.next(this.cartItemList);
// }
// removeAllCart(){
// this.cartItemList = []
// this.productList.next(this.cartItemList);
// }
}
product.ts
export class item {
id!: number;
title!: string;
price!: number;
description!: string;
category!: string;
image!: string;
/*
"rating": {
"rate": 3.9,
"count": 120
}*/
}
CodePudding user response:
Can you try calling the http request in the constructor and doing the assignment there?
{{ item?.description }}and others arrange table cells like this
CodePudding user response:
There are few things I would improve:
First, your interface (or model) product.ts is called item, but you are not using it anywhere. Try to do this:
export class Product {
id: number;
title: string;
price: number;
description: string;
category: string;
image: string;
}
Doing that, you can import it in your component.ts use it when you instantiate a product object, like this:
products : Product[] = [];
Try to do this every time it is possible since we are working with Angular (and TypeScript) and we must avoid using any.
As other people mentioned in the comments, the rest looks good, so try to do that and update the question.