This is a post where I document how I change UI on a successful contract function call. Keeping this here to help others who might have the same query (and save them 2 days of pain ) :
- Call a smart contract function by clicking a button “Approve My Traits” (see “before” screenshot).
- On successful txn, I deactivate the button, gray it out and change button to “Traits Approved” (see “after” screenshot).
- If user returns to the site after a while or refreshes, I use useEffect to make a function call and check if approved==false or approved==true and accordingly render the active button or grayed out button.
- If user switches accounts in metamask I trigger the above useEffect again to check and re-render button.
Hat-tip to @PatrickAlphaC whose solution here helped. Also thanks to @orangemat @_Ty for their inputs.
The code below is self explanatory. Any suggestions welcome. I have not implemented error catching so any suggestion on that is appreciated.
function SetApproval() {
//isApprovedForAll(account, operator) - function imported in our contract from OpenZeppelin IERC1155
//setApprovalForAll(operator, approved) - function imported in our contract from OpenZeppelin IERC1155
const spotTraitsContractFuji = '0xD1cebaDdf3a76CD1E628e8Ce541fC700c64Afe47';
const spotNFTContractFuji = '0x1BcaC9c748619578B8b420ff4E5536a55441fc42';
const { account } = useMoralis();
const { data: approvalData, error: approvalError,
fetch: approvalFetch, isFetching: approvalFetching,
isLoading: approvalLoading } = useWeb3ExecuteFunction({
abi: spotTraitsAbiFuji, //imported from spotTraitsAbiFuji.json
contractAddress: spotTraitsContractFuji,
functionName: "setApprovalForAll",
params: {
operator: spotNFTContractFuji,
approved: true
},
});
const { data: checkApprovedData, error: checkApprovedError,
fetch: checkApprovedFetch, isFetching: checkApprovedFetching,
isLoading: checkApprovedLoading } = useWeb3ExecuteFunction({
abi: spotTraitsAbiFuji,
contractAddress: spotTraitsContractFuji,
functionName: "isApprovedForAll",
params: {
account: account,
operator: spotNFTContractFuji
},
});
const [traitsApproved, setTraitsApproved] = useState(false)
function changeUITrue() {
setTraitsApproved(true)
}
function changeUIFalse() {
setTraitsApproved(false)
}
const handleSuccessfulApproval = async (tx) => {
await tx.wait(1)
changeUITrue()
}
useEffect(()=>{
const checkApproval = async ()=>{
const result = await checkApprovedFetch();
if (result) {
changeUITrue();
} else changeUIFalse();
}
checkApproval()
},[account])
return (
<div>
<button className={!traitsApproved?"m-2 rounded-lg px-4 py-2 border-2 border-gray-200 text-gray-200 hover:bg-gray-200 hover:text-gray-900 duration-300 font-mono font-bold text-base":"m-2 rounded-lg px-4 py-2 border-2 border-gray-200 bg-gray-500 text-gray-900 font-mono font-bold text-base"}
onClick={async()=>{
if(traitsApproved){
return;
}
await approvalFetch({
onSuccess: handleSuccessfulApproval,
})
}}>{traitsApproved?'Traits Approved':'Approve My Traits'}</button>
</div>
)
}
export default SetApproval;