Erreur du composant Web Lightning: ['set' on proxy: trap renvoyé falsish pour la propriété '0']
J'essaie de créer un panier dans lequel j'ajoute des produits et je peux ensuite les supprimer. Cependant, lors de la suppression, je reçois l'erreur ['set' on proxy: trap returned falsish for property '0']
.
Dans mon composant ParentComponent
, je sélectionne les produits et les ajoute à un tableau cartItems
. Pour chaque article du panier, un composant enfant appelé cartRowItem
est instancié. Voir le code ci-dessous:
parentComponent.html:
<template>
<div class="slds-grid slds-gutters">
<lightning-card class="slds-col slds-size_1-of-3" title="Product Search">
<div class="slds-grid slds-gutters">
<div class="slds-col slds-size_2-of-3 slds-var-m-left_small">
<lightning-input type="text" placeholder="Search for a product" value={productSearchKey} onchange={handleSearchKeyChange}></lightning-input>
</div>
<div class="slds-col slds-size_1-of-3">
<button class="slds-button slds-button_brand slds-button_stretch slds-var-m-right_small" onclick={doSearch}>Search</button>
</div>
</div>
<template if:true={products}>
<lightning-datatable
key-field="id"
data={products}
columns={columns}
onrowaction={addToCart}
hide-checkbox-column>
</lightning-datatable>
</template>
</lightning-card>
<lightning-card class="slds-col slds-size_2-of-3" title="Product Cart">
<template for:each={cartItems} for:item="item">
<c-cart-row-item key={item.id} cart-item={item} cart-items={cartItems} oncartitemremove={handleRemove}></c-cart-row-item>
</template>
</lightning-card>
</div>
</template>
parentComponent.js:
import { LightningElement, api, track } from 'lwc';
import findProducts from '@salesforce/apex/TechDocSelfServeController.findProducts';
const tableColumns = [{
label: 'Product Code',
fieldName: 'ProductCode',
type: 'text',
sortable: true
},
{
label: 'Product Name',
fieldName: 'Name',
type: 'text',
sortable: 'true'
},
{
label: 'Add to Cart',
type: 'button-icon',
typeAttributes:
{
iconName: 'utility:add',
name: 'addToCart',
title: 'addToCart',
disabled: false,
alternativeText: 'Add to Cart',
}
}];
export default class TechDocSelfServe extends LightningElement {
products;
@api cartItems = [];
columns = tableColumns;
productSearchKey = '';
error;
doSearch() {
let productSearchKey = this.productSearchKey;
findProducts({ productSearchKey })
.then((result) => {
this.products = result;
this.error = undefined;
})
.catch((error) => {
this.error = error;
this.products = undefined;
});
}
addToCart(event) {
const row = event.detail.row;
this.cartItems = [...this.cartItems, row];
const selectedEvent = new CustomEvent("cartitemadd", {
detail: this.cartItems
});
console.log('cartItems on add -> ' + JSON.stringify(this.cartItems, null, 4));
this.dispatchEvent(selectedEvent);
}
handleSearchKeyChange(event) {
this.productSearchKey = event.target.value;
}
handleRemove(event) {
this.cartItems = event.detail
}
}
cartRowItem.html:
<template>
<template if:true={displayRow}>
<div class="slds-var-m-around_xx-small slds-box">
<lightning-card>
<div class="slds-text-heading_large slds-text-align_center "><u>{cartItem.Name}</u></div>
<lightning-button variant="destructive" label="Remove Item" title="RemoveItem" onclick={handleRemove} value={cartItem} class="slds-align_absolute-center"></lightning-button>
</lightning-card>
</div>
</template>
</template>
cartRowItem.js (mis à jour selon le commentaire de Rahul):
import { LightningElement, api } from 'lwc';
export default class CartRowItem extends LightningElement {
@api cartItem;
_cartItems;
displayRow = true;
@api get cartItems() {
return this._cartItems;
}
set cartItems(value) {
this._cartItems = value;
}
handleRemove(event) {
console.log('Should remove here.')
var array = this._cartItems;
var key = event.target.value.Id;
var index = array.findIndex(function(item, i) {
return item.Id === key
});
array.splice(index, 1);
this._cartItems = array;
console.log('cartItems after remove -> ' + JSON.stringify(this._cartItems, null, 4));
const selectedEvent = new CustomEvent("cartitemremove", {
detail: this._cartItems
});
this.dispatchEvent(selectedEvent);
this.displayRow = false;
}
}
Lorsque vous appuyez sur le bouton Supprimer dans cartRowItem, je reçois l'erreur ['set' on proxy: trap returned falsish for property '0']
avec le numéro à la fin changeant en fonction de l'élément du tableau que j'essaie de supprimer.
Réponses
La propriété définie par le produit parent est immuable, ce qui signifie que vous ne pouvez pas la modifier. Vous devez utiliser le setter getter pour la propriété publique.
_cartItems;
...
@api
get cartItems(){
return this._cartItems;
}
set cartItems(value){
this._cartItems = JSON.parse(JSON.stringify(value));
}
Notez que j'ai créé une nouvelle propriété privée avec un nom différent ie _cartItems
.
Vous pouvez maintenant effectuer toutes les opérations et mettre à jour le fichier _cartItems
. Pour envoyer des données mises à jour au parent, vous devez envoyer un événement personnalisé à partir de l'enfant.