3

I am trying to build a cart where I add products to it and can then remove them. However on remove I receive the error ['set' on proxy: trap returned falsish for property '0'].

In my component ParentComponent, I select the products and add to an array cartItems. For each cart item a child component called cartRowItem is instantiated. See code below:

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 (updated as per Rahul comment):

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;
    }
}

When pressing Remove button in cartRowItem I will receive the error ['set' on proxy: trap returned falsish for property '0'] with the number at the end changing depending on what item in the array I am trying to remove.

2

The property set by parent product is immutable, mean's you can't modify that. You need to use the getter setter for the public property.

_cartItems;
...

@api
get cartItems(){
    return this._cartItems;
}

set cartItems(value){
    this._cartItems = JSON.parse(JSON.stringify(value));
}

Note that I have created new private property with different name i.e. _cartItems.

Now you can perform all the operations and update the _cartItems. To send updated data into parent, you need to dispatch a custom event from child.

6
  • 1
    @LukeBray please update your code in the question. – Rahul Gawale Aug 18 '20 at 14:44
  • thanks Rahul, have updated question. – Luke Bray Aug 18 '20 at 15:02
  • @LukeBray are you still getting the same issue? or this is something else now? – Rahul Gawale Aug 18 '20 at 15:05
  • It's the same issue – Luke Bray Aug 18 '20 at 15:07
  • 1
    Thank you @RahulGawale, this worked. – Luke Bray Aug 18 '20 at 16:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.