3

I created a Kanban following that tutorial. I manage to do pretty evertything, the only thing that I am stucked on is that when the user drag and DROP the card it should refresh the Apex method in order to display the card in the right column.

However it does not seems to work .. when I drag the card it showed a success notification but the card stay in the same column. If I reload I will see it in the right one Look at the gif .. enter image description here

In my updpateHandler method i am using return refreshApex(this.retrieveOpportunities); but not working ;( Here is my code:

import { LightningElement, wire, api } from 'lwc';
import { getListUi } from 'lightning/uiListApi';
import { updateRecord } from 'lightning/uiRecordApi';
import { refreshApex } from '@salesforce/apex';
import { getPicklistValues, getObjectInfo } from 'lightning/uiObjectInfoApi';
import OPPORTUNITY_OBJECT from '@salesforce/schema/Opportunity';
import STAGE_FIELD from '@salesforce/schema/Opportunity.StageName';
import ID_FIELD from '@salesforce/schema/Opportunity.Id'
import { ShowToastEvent } from 'lightning/platformShowToastEvent'; 
import propertiesFromMarket from '@salesforce/apex/PicklistHelper.propertiesFromMarketBis';
import OpportunitiesFromMarket from '@salesforce/apex/PicklistHelper.OpportunitiesFromMarket';

export default class DragAndDropLwc extends LightningElement {
    records
    pickVals
    recordId
    @api selectedMarket

    /*** Fetching Property Data from apex */
    @wire(propertiesFromMarket, {MarketId: '$selectedMarket'})
    retrieveProperties({error, data}){
     
        if(data){
            console.log("propData", data)
            //this.records = data
 
            }
            if(error){
                console.error(error)
            }
        }


    /*** Fetching Property Data from apex */
    @wire(OpportunitiesFromMarket, {MarketId: '$selectedMarket'})
    retrieveOpportunities({error, data}){
 
        if(data){
            console.log("OppData", data)
            this.records = data
            }
            if(error){
                console.error(error)
            }
        }



    /*** Fetching Opportunity Data */
    // @wire(getListUi, {
    //     objectApiName: OPPORTUNITY_OBJECT,
    //     listViewApiName:'AllOpportunities'
    // })wiredListView({error, data}){
    //     if(data){
    //         console.log("getListUi", data)
    //         this.records  = data.records.records.map(item => {
    //             let field = item.fields
    //             return{ 'Id': field.Id.value, 'Name': field.Name.value, 'StageName':field.StageName.value}
    //             })
            
    //    }
    //     if(error){
    //         console.error(error)
    //     }
    // }
    

    /** Fetch metadata abaout the opportunity object**/
    @wire(getObjectInfo, {objectApiName:OPPORTUNITY_OBJECT})
    objectInfo

    /*** Fetching Stages picklist */
    @wire(getPicklistValues, {
        recordTypeId:'$objectInfo.data.defaultRecordTypeId',
        fieldApiName:STAGE_FIELD
    })stagePicklistValues({ data, error}){
        if(data){
            console.log("Stage Picklist", data)
            this.pickVals = data.values.map(item => item.value)
        }
        if(error){
            console.error(error)
        }
    }

    /*** getter to caluclate the width dynamically */
    get calcWidth(){
        let len = this.pickVals.length 
        return `width: calc(100vw/ ${len})`
    }

    handleListItemDrag(event){
        this.recordId = event.detail
        //console.log("OnDrag", recordId)
    }

    handleItemDrop(event){
        let stage = event.detail
        // this.records = this.records.map(item=>{
        //     return item.Id === this.recordId ? {...item, StageName:stage}:{...item}
        // })
        this.updateHandler(stage)
    }
    updateHandler(stage){
        const fields = {};
        fields[ID_FIELD.fieldApiName] = this.recordId;
        fields[STAGE_FIELD.fieldApiName] = stage;
        const recordInput ={fields}
        updateRecord(recordInput)
        .then(()=>{
            console.log("Updated Successfully")
            this.showToast()
            return refreshApex(this.records);

        }).catch(error=>{
            console.error(error)
        })
    }

    showToast(){
        this.dispatchEvent(
            new ShowToastEvent({
                title:'Success',
                message:'Stage updated Successfully',
                variant:'success'
            })
        )
    }

}

2 Answers 2

17

The documentation is a bit confusing, so a lot of people get this wrong, but basically, you need to store the entire wire response and call refreshApex on that, instead. The destructuring method is normally shown for a wire method, but you actually need to store the original parameter to use refreshApex.

_wiredMarketData;
@wire(OpportunitiesFromMarket, { MarketId: '$selectedMarket' })
retrieveOpportunities(wireResult){
    const { data, error } = wireResult;
    this._wiredMarketData = wireResult;
    if(data){
        console.log("OppData", data)
        this.records = data
    }
    if(error) {
        console.error(error)
    }
}

Then, when you want to refresh:

return refreshApex(this._wiredMarketData);

This will call the server, then call your wire handler again.

2
  • 1
    Thx you ;) working yes a bit confusing ;)
    – Ben2pop
    Mar 14, 2021 at 13:49
  • See also this previous Q&A.
    – Phil W
    Mar 15, 2021 at 8:55
1

Just fyi for what's it's worth. I've also used this approach. (I know it somewhat defeats the purpose of using a wired method but I had to take a hammer to it with the same userId and collectionDate params. enter image description here

enter image description here

1
  • You don't need both refreshApex and a cache-buster. Choose one. If you're having problems with either, that typically indicates a deeper problem with your code.
    – sfdcfox
    Aug 20 at 17:53

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .