4

I have one wire method in JS, when it finishes processing it sets this.showSpinner = false, everything is working as expected.

@track showSpinner = true;

@wire(getApexStudyData, { objectId: '$objId' })
imperativeStudyWiring(result) {
  this.wiredStudyResult = result;

  if (result.data) {
      // assign values here 
      this.showSpinner = false

  }
}

sometimes instead of entering data on the page user enter data through data loader or x author of apttus cpq and then refreshes the page to see if the page has updated data or not.

Now instead of refreshing the page we need to create a button which will just refreshes the data to achieve the same I have created an HTML button and upon clicking it executes below method and it works as expected if the data has changed in the data base then upon clicking below button it updates the data on the page.

refreshData() {
    if (this.wiredStudyResult) {
        refreshApex(this.wiredStudyResult);
    }
}

Till now everything is coming as expected but sometimes above method takes 3 to 5 seconds to show refreshed data so while it is refreshing data we need to display a spinner just like when page renders first time, a spinner appears and once data is loaded it went off, I have tried below approaches to achieve the same.

1st approach: it refreshes the data but spinner doesn't appear.

refreshData() {
    if (this.wiredStudyResult) {
        this.showSpinner = true;
        refreshApex(this.wiredStudyResult);
        this.showSpinner = false;
    }
}

2nd approach: sometime adding timeout does the trick but here it didn't work.

 refreshData() {
        if (this.wiredStudyResult) {
            this.showSpinner = true;
            setTimeout(() => {
               refreshApex(this.wiredStudyResult);
               this.showSpinner = false;
             }, 100)
        }
    }

3rd approach: here I am not setting the this.showSpinner = false and I changed the data in the database and clicked this button and it worked as expected spinner rendered and once the refreshApex finished it went off (as showSpinner field is setting false inside the wire method), now the problem with this approach is when I don't change any thing in the database and page has updated data then upon clicking refresh button ideally it should do nothing but spinner will appear and remains there forever. in other words if page has updated data then showSpinner = false inside the wire method doesn't work or wire method doesn't execute at all.

refreshData() {
        if (this.wiredStudyResult) {
            this.showSpinner = true;
            refreshApex(this.wiredStudyResult);
        }
    }

Can someone please help me how can I manage this.showSpinner variable accordingly with refresh apex.

please excuse if I have made any syntax error while copying and pasting the code, but trust me I have tried and tested above all the approaches in real time :).

2
  • in approach why spinner doesn't appear? is it in component markup, is there any other markup that can hide spinner componet?? Commented Apr 21, 2020 at 8:29
  • Thank you for your response Pranay, this.showSpinner = false is only at one place which is inside the wire method and its one component.
    – gs650x
    Commented Apr 21, 2020 at 8:54

1 Answer 1

4

The first method "does nothing" because the call is asynchronous, so from the browser's point of view, the flag effectively never changed.

The second method doesn't work for the same reason; refreshApex is still running when you set the flag back to false.

The third method fails because, as you said, the wire method only updates if there's actually new data.

The solution...

It appears that refreshApex returns a Promise, so the following code should work:

refreshData() {
    this.showSpinner = true;
    refreshApex(this.wiredStudyResult)
      .then(() => this.showSpinner = false)
      .catch(() => this.showSpinner = false);
}
5
  • and it worked like a magic, thank you Brian
    – gs650x
    Commented Apr 21, 2020 at 13:30
  • @sfdcfox I am trying t do something similar here, refresh() { this.notifyLoading(true); console.log('refreshapex started') refreshApex(this.boats) .then(() => { this.notifyLoading(false); console.log('refresh apex complete'); }).catch(() => this.notifyLoading(false)); } but it doesn't seem to be working. execution never completes the refreshApex call. Do you see any obvious mistake here?
    – Yogesh D
    Commented Aug 5, 2020 at 14:06
  • 1
    @YogeshD That should work, assuming boats is the wire/callback result. Note that it must be the entire result, not just the data attribute.
    – sfdcfox
    Commented Aug 5, 2020 at 14:13
  • @sfdcfox worked like charm. The way I had wired method defined was wrong. I was assigning just the data attribute to this.boats. Thanks for the help. I had posted this as a separate question here to which I submitted your comment as answer and have mentioned your above comment in the answer which helped me understand the issue.
    – Yogesh D
    Commented Aug 5, 2020 at 14:40
  • @sfdcfox marvelous solution! adding showSpinner = false in a finally block is nice.
    – Raul
    Commented Feb 15, 2021 at 11:54

You must log in to answer this question.

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