当我从购物车中删除所有产品时,主页中没有显示任何产品,并且浏览器控制台显示错误 ERROR TypeError:无法读取null的属性'items'。
shopping-cart.service.ts
export class ShoppingCartService {
constructor(private db: AngularFireDatabase) {}
private create() {
return this.db.list('/shopping-carts').push({
dateCreated: new Date().getTime()
});
}
async getCart(): Promise<Observable<ShoppingCart>> {
let cartId = await this.getOrCreateCartId();
return this.db
.object('/shopping-carts/' + cartId)
.snapshotChanges()
.pipe(map((x) => new ShoppingCart(x.payload.exportVal().items //ERROR TypeError: Cannot read property 'items' of null
)));
}
private getItem(cartId: string, productId: string) {
return this.db.object('/shopping-carts/' + cartId + '/items/' + productId);
}
private async getOrCreateCartId(): Promise<string> {
let cartId = localStorage.getItem('cartId');
if (cartId) return cartId;
let result = await this.create();
localStorage.setItem('cartId', result.key);
return result.key;
}
async addToCart(product: Product) {
this.updateItem(product, 1);
}
async clearCart() {
let cartId = await this.getOrCreateCartId();
this.db.object('/shopping-carts/' + cartId + '/items').remove();
}
async removeFromCart(product: Product) {
this.updateItem(product, -1);
}
private async updateItem(product: Product, change: number) {
let cartId = await this.getOrCreateCartId();
let item$ = this.getItem(cartId, product.key);
item$.snapshotChanges().pipe(take(1)).subscribe((item) => {
if (item.payload.exists()) {
let quantity = item.payload.exportVal().quantity + change;
if (quantity === 0) item$.remove();
else
item$.update({
product: product,
quantity: quantity
});
} else {
item$.set({ product: product, quantity: 1 });
}
});
}
}
在models文件夹中 shopping-cart.ts
import { ShoppingCartItem } from './shopping-cart-item';
import { Product } from './product';
export class ShoppingCart {
items: ShoppingCartItem[] = [];
constructor(private itemsMap: { [productId: string]: ShoppingCartItem }) {
this.itemsMap = itemsMap || {};
for (let productId in itemsMap) {
let item = itemsMap[productId];
this.items.push(new ShoppingCartItem(item.product, item.quantity));
}
}
getQuantity(product: Product) {
let item = this.itemsMap[product.key];
return item ? item.quantity : 0;
}
get totalPrice() {
let sum = 0;
for (let productId in this.items) {
sum += this.items[productId].totalPrice;
}
return sum;
}
get totalItemsCount() {
let count = 0;
for (let productId in this.itemsMap) count += this.itemsMap[productId].quantity;
return count;
}
}
shopping-cart-item.ts
import { Product } from './product';
export class ShoppingCartItem {
key: string;
title: string;
imageUrl: string;
price: number;
constructor(public product: Product, public quantity: number) {}
get totalPrice() {
return this.product.price * this.quantity;
}
}
shopping-cart.component.ts
export class ShoppingCartComponent implements OnInit {
cart$: Observable<ShoppingCart>;
constructor(private shoppingCartService: ShoppingCartService) {}
async ngOnInit() {
this.cart$ = await this.shoppingCartService.getCart();
}
clearCart() {
this.shoppingCartService.clearCart();
}
}
shopping-cart.component.html
<ng-container *ngIf="cart$ | async as cart">
<table class="table">
<tbody>
<tr *ngFor="let item of cart.items">
<td>
<img
[src]="item.product.imageUrl"
class="thumbnail"
alt=""
>
</td>
<td>{{ item.product.title }}</td>
<td>
${{item.product.price}} X {{ item.quantity }}
</td>
<td>
<app-product-quantity
[product]="item.product"
[shopping-cart]="cart"
></app-product-quantity>
</td>
<td>
{{ item.totalPrice | currency: 'USD':true}}
</td>
</tr>
</tbody>
<tfoot>
<tr>
<th></th>
<th></th>
<th></th>
<th></th>
<th>
{{ cart.totalPrice | currency:'USD':true}}
</th>
</tr>
</tfoot>
</table>
<button
*ngIf="cart.items.length"
type="button"
(click)="clearCart()"
class="btn btn-light btn-block"
>
Clear Shopping Cart
</button>
</ng-container>
我要从购物车中删除所有产品后,在浏览器的主页上将显示所有产品。
答案 0 :(得分:0)
async getCart(): Promise<Observable<ShoppingCart>> {
let cartId = await this.getOrCreateCartId();
return this.db
.object('/shopping-carts/' + cartId)
.valueChanges()
.pipe(map((x)=> (x) ? new ShoppingCart(( x as any).items): (x as any)
));
}