Error del componente web Lightning: ['establecido' en el proxy: la captura devuelta falsa para la propiedad '0']
Estoy tratando de construir un carrito donde agrego productos y luego puedo eliminarlos. Sin embargo, al eliminar, recibo el error ['set' on proxy: trap returned falsish for property '0']
.
En mi componente ParentComponent
, selecciono los productos y los agrego a una matriz cartItems
. Para cada artículo del carrito, se crea una cartRowItem
instancia de un componente secundario llamado . Ver código a continuación:
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 (actualizado según el comentario 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;
}
}
Al presionar el botón Eliminar en cartRowItem, recibiré el error ['set' on proxy: trap returned falsish for property '0']
con el número al final cambiando según el elemento de la matriz que estoy tratando de eliminar.
Respuestas
La propiedad establecida por el producto principal es inmutable, lo que significa que no se puede modificar. Necesita usar el setter getter para la propiedad pública.
_cartItems;
...
@api
get cartItems(){
return this._cartItems;
}
set cartItems(value){
this._cartItems = JSON.parse(JSON.stringify(value));
}
Tenga en cuenta que he creado una nueva propiedad privada con un nombre diferente, es decir _cartItems
.
Ahora puede realizar todas las operaciones y actualizar el _cartItems
. Para enviar datos actualizados al padre, debe enviar un evento personalizado del hijo.