Angular. Удаление элемента с корзины LocalStorage
Сделал корзину на сайте, через *ngFor="let item of product; let productId = index" добавляю новые div с товаром. Кнопка есть в каждом товаре "удалить" ей задано:
basket.service.ts:
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
@Injectable({ providedIn: 'root' })
export class BasketService {
basket = new BehaviorSubject([]);
basketCount = new BehaviorSubject(0);
constructor() {
this.setToLocalStorage();
}
setToBasket(product): void {
this.setToLocalStorage(product);
console.log(product);
}
private setToLocalStorage(product?): void {
if (!localStorage.getItem("basket")) {
localStorage.setItem("basket", JSON.stringify([]));
} else {
this.basket.next(JSON.parse(localStorage.getItem("basket")));
this.basketCount.next(JSON.parse(localStorage.getItem("basket")).length);
}
if (!product) {
return
}
const basket = JSON.parse(localStorage.getItem("basket"));
basket.push(product);
localStorage.setItem("basket", JSON.stringify(basket));
this.basket.next(basket);
this.basketCount.next(basket.length)
}
}
basket.component.ts
import {Component, OnInit, OnDestroy} from '@angular/core';
import {BasketService} from 'src/app/core/services/basket/basket.service';
import {Subject} from 'rxjs';
import {takeUntil} from 'rxjs/operators';
@Component({
selector: 'app-basket',
templateUrl: './basket.component.html',
styleUrls: ['./basket.component.css']
})
export class BasketComponent implements OnInit, OnDestroy {
basketList;
product;
basket;
productIndex: number;
id: number;
private unsubscribe = new Subject();
constructor(
private basketService: BasketService
) {}
ngOnInit(): void {
this.getBasketList();
}
ngOnDestroy() {
this.unsubscribe.next();
this.unsubscribe.complete();
}
getBasketList(): void {
this.basketService.basket.pipe(takeUntil(this.unsubscribe))
.subscribe(
data => {
console.log(data);
this.product = data;
});
}
clearBasket(): void {
localStorage.clear()
}
// deleteBasketItem(): void {
// var basket = JSON.parse(localStorage.getItem("basket"));
// this.basket.splice("this.basket", JSON.stringify(this.id), 1);
// localStorage.setItem("basket", JSON.stringify(basket));
// console.log(this.id)
// }
deleteBasketItem(productId) {
var basket = JSON.parse(localStorage.getItem("basket"));
var index = basket.findIndex(x => x == productId);
basket.splice(index, 1);
localStorage.setItem("basket", JSON.stringify(basket));
}
}
basket.component.html:
<div class="container mt-5">
<div class="col-12 title">
<h2>Корзина</h2>
</div>
<div class="col-12 clear">
<button class="buttonDeleteAll" (click)="clearBasket()">Очистить</button>
</div>
<div class="mt-4 basketItem" *ngFor="let item of product; let productId = index">
<div class="row">
<div class="col-3 d-flex justify-content-center align-items-center pictureOfItemDiv">
<img [src]="item.picture" class="mt-1 itemPictureOnBasket" alt="...">
</div>
<div class="col-8">
<div class="col-12 row mt-3 headerOfItem">
<div class="col-5">
<p>Название</p>
</div>
<div class="col-3">
<p>Код товара</p>
</div>
<div class="col-2">
<p>Цена</p>
</div>
<div class="col-2">
<p>К-во</p>
</div>
</div>
<div class="col-12 row mt-3 footerOfItem">
<div class="col-5">
<p>{{item.name}}</p>
</div>
<div class="col-3">
<p>{{item.id}}</p>
</div>
<div class="col-2">
<p>{{item.price}}</p>
</div>
<div class="col-2">
<p>{{item.count}}</p>
</div>
<div class="col-1"></div>
</div>
</div>
<div class="col-1 d-flex align-items-center">
<button class="deleteItemButton" (click)="deleteBasketItem(productId)" value="{{productId}}">
<span class="text-danger material-icons md-40 deleteItemIcon">
delete
</span>
</button>
</div>
</div>
</div>
<div class="col-12 mt-5 d-flex justify-content-end">
<div>
<p><b>Сумма: ---</b></p>
</div>
</div>
<div class="col-12 mt-5 ">
<button class="buttonDeleteAll" (click)="clearBasket()">
Подтвердить
</button>
</div>
</div>
Понимаю что productId не так считывается. Подскажите, как правильно реализовать это?
Ответы (2 шт):
https://stackblitz.com/edit/localstorage-stackoverflow
<div class="mt-4 basketItem" *ngFor="let item of product; let i = index">
<!-- i - это индекс элемента массива, id - это идентификатор продукта -->
<div class="row">
<div class="col-3 d-flex justify-content-center align-items-center pictureOfItemDiv">
<img [src]="item.picture" class="mt-1 itemPictureOnBasket" alt="...">
</div>
<div class="col-8" style="display: flex;">
<div class="col-12 row mt-3 headerOfItem">
<div class="col-5" style=" margin-right:20px">
<p>Название</p>
</div>
<div class="col-5" style=" margin-right:20px">
<p>ID</p>
</div>
<div class="col-3">
<p>Код товара</p>
</div>
<div class="col-2">
<p>Цена</p>
</div>
<div class="col-2">
<p>К-во</p>
</div>
</div>
<div class="col-12 row mt-3 footerOfItem">
<div class="col-5">
<p>{{item.id}}</p>
</div>
<div class="col-5">
<p>{{item.name}}</p>
</div>
<div class="col-3">
<p>{{item.code}}</p>
</div>
<div class="col-2">
<p>{{item.price}}</p>
</div>
<div class="col-2">
<p>{{item.count}}</p>
</div>
<div class="col-1"></div>
</div>
</div>
<div class="col-1 d-flex align-items-center">
<!-- зачем в button нужно value? -->
<button class="deleteItemButton" (click)="deleteBasketItem(item.id)" value="{{item.id}}">
<span class="text-danger material-icons md-40 deleteItemIcon">
delete
</span>
</button>
</div>
</div>
</div>
component.ts:
...
clearBasket(): void {
localStorage.clear()
this.product = [] // очищаем this.product тоже
}
deleteBasketItem(productId: number) {
this.basketService.removeFromLocalstorage(productId);
var index = this.product.findIndex(x => x.id == productId);
this.product.splice(index, 1); // удаляем с this.product тоже
}
basket.service:
basket = new BehaviorSubject([]);
products = [];
basketCount = new BehaviorSubject(0);
constructor() {
this.fillBasket();
}
fillBasket() {
if (!localStorage.getItem("basket"))
return
var basket = JSON.parse(localStorage.getItem("basket"));
this.products = basket;
this.basket.next(this.products );
}
setToBasket(product): void {
this.products.push(product);
this.basket.next(this.products);
this.setToLocalStorage(product);
}
private setToLocalStorage(product?): void {
if (!localStorage.getItem("basket")) {
localStorage.setItem("basket", JSON.stringify([]));
} else {
localStorage.setItem("basket", JSON.stringify(this.products));
this.basket.next(JSON.parse(localStorage.getItem("basket")));
}
if (!product) {
return
}
}
removeFromLocalstorage(id) {
var basket = JSON.parse(localStorage.getItem("basket"));
var index = basket.findIndex(x => x.id == id);
basket.splice(index, 1); // удаляем с локалсторедж
localStorage.setItem("basket", JSON.stringify(basket));
}
Вы создали сервис чтобы получать данные - это хорошее решение, но при этом удаляете и очищаете через компонент - это плохое решение.
Ваш метод deleteBasketItem получает на вход index внутри массива baskets, но ищите вы его неверно. У вас в принципе уже есть индекс и дополнительно искать ничего не нужно.
Как вариант можете воспользоваться функцией splice или filter
// удалить только один элемент (исходный массив изменится)
basket.splice(productId, 1)
// или отфильтровать и создать новый массив
basket = basket.filter((item,index) => index === productId);