How to disable react button until Meteor Method finishes

Viewed 1729

I have a Meteor app with a react component that has a button that fires an async meteor method.

The method takes some time to run, and I wish to prevent it from being clicked again while waiting for the response. I can disable the button in the click handler, but once the function completes, I can't seem to re-enable it, since 'this' (being the react component) is unknown for the callback function.

Any ideas on how to modify a react element on a method callback?

2 Answers

I would create a boolean in your local state like isWaiting: false and in the function inside your event handler (your async meteor method), once that button has been clicked it should change the isWaiting value to true. And depending on what pattern you choose (async/await or promises) I would set isWaiting back to false on both success and reject. After that, have the disable attribute dependent on the isWaiting state.

You can use try-catch-finally:

const [isWaiting, setIsWaiting] = useState(false);

async function meteorMethod() {
  setIsWaiting(true)
  try {
    // await...
  } catch(err) {
    // ...
  }
  finally {
    setIsWaiting(false)
  }
}

return (
  <>
    <button disable={isWaiting} onClick={meteorMethod}>Submit</button>
  </>
)

import React, {useState} from "react"

const SampleAsync = () => {

  let [isWaiting, setWaiting ] = useState(false)

  let meteorMethod = () => {
      setWaiting(true)
      Meteor.call('insertSometing', data,(result,error) => {
        if(error) 
        console.log('erro')
        else
        setWaiting(false)
      })
  }


  // If isWaiting is true the button disable and if false unable
  // you can also do this: <button disable={isWaiting} onClick={meteorMethod}>Submit</button>
  return (
    <div>
      // you can add inline if
      <button disable={isWaiting == true ? true : false  } onClick={meteorMethod}>Submit</button>
    </div>
  )
}

export default SampleAsync

Related