What is the best location to upload a contract in order to avoid errors from undefined methods when accessing

Attempting to execute a method from my smart contract on the ropsten test network has led me to an error within my getBalance() function:

Unhandled Runtime Error TypeError: Cannot read properties of undefined (reading 'methods')

  46 |     async function getBalance() {
> 47 |       const tempBal = await window.contract.methods.balanceOf(account.data).call()
     |                                            ^
  48 |       setBalance(tempBal)
  49 |     }

Establishing connection with my contract:

export default function ConnectContract() {
    

    async function loadWeb3() {
        if (window.ethereum) {
          window.web3 = new Web3(window.ethereum)
          window.ethereum.enable()
        }
      }
  
      async function loadContract() {
        const tempContract = await new window.web3.eth.Contract(ABI, ContractAddress)
        return tempContract
      }
  
      async function load() {
        await loadWeb3();
        window.contract = await loadContract();
      }

      load();

}

The functions are currently being invoked as follows:

 export default function Page() {
    ConnectContract();
    getBalance();
 }

Previously, I successfully avoided the undefined error by using an onClick function within a button to trigger getBalance:

 <div><button onClick={() => getBalance}>Get Balance</button></div>

It seems that the way I am calling them causes the getBalance function to be executed before the contract is connected to the website. Despite the current code working after a page refresh, I have yet to find a solution to ensure the contract is loaded so that the method is defined when getBalance is called.

I have attempted using onLoad and window.load() functions without success. I also tried calling my ConnectContract function in the _app.js file to load it upon website launch, but that did not yield successful results either.

Answer №1

To ensure the proper functioning of your component, it is essential to call the loadWeb3 function within the useEffect hook. The useEffect hook is responsible for preparing the state of the component upon mounting, and for maintaining the state, the useState hook is utilized.

const [web3,setWeb3]=useState('')
const [contract,setContract]=useState('')

async function loadWeb3() {
        if (window.ethereum) {
          window.ethereum.enable()
          setWeb3(new Web3(window.ethereum))         
        }
      }

// The empty [] array specifies that this useEffect code should only run when the component is rerendered
// Since loadWeb3 is an async function, it should be called within a try/catch block
useEffect(()=>{loadWeb3()},[])

Additionally, you must also prepare the contract in a similar manner.

async function loadContract() {
        const tempContract = await new web3.eth.Contract(ABI, ContractAddress)
        setContract(tempContract)
      }

This function should also be called within a useEffect, but with different dependencies. The dependency in this case is the web3 object, as obtaining the contract relies on it.

// Since loadContract is an async function, it should be called within a try/catch block
useEffect(()=>{loadContract},[web3])

Upon rendering the component, the first useEffect will trigger and set the web3 object. Subsequently, as the web3 object changes, the component will rerender, resulting in the execution of the useEffect once more. Therefore, upon mounting the component, both the web3 object and the contract will be established and ready for use.

Answer №2

The root of the issue lies within this snippet of code:

  46 |     async function getBalance() {
> 47 |       const tempBal = await window.contract.methods.balanceOf(account.data).call()
     |                                            ^
  48 |       setBalance(tempBal)
  49 |     }

It seems likely that the window.contract is either not defined or not being loaded before this function is invoked. It's possible that it's being executed in a server-side context where the window object is not available. You may want to wrap it within an if statement to ensure that it exists before making the call.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

EJS failing to render HTML within script tags

Here is some code that I'm working with: <% // accessing content from a cdn api cloudinary.api.resources( { type: 'upload', prefix: '' }, (error, result) => { const assets = result.r ...

Can dynamic attributes be used with ternary operators in Angular?

I attempted to alter the id of a div using Angular and implemented the following code: <div [id]="'item_' + (itemName !== undefined ? itemName.replace(' ', '-').toLowerCase() : '')"> However, when I run my te ...

How to assign a global variable in Angular 2 from within a promise

I have encountered a strange issue while trying to assign a response to a global variable inside an observable. Here's the logic of my program: Fetch the latest playlists IDs from elastic search (using a type definition file for elastic search). T ...

Add-on or code snippet for Node.js that allows for optional regex groups

Strings in Sequence line 1 = [A B C] line 2 = [A C] line 3 = [B C] Regular Expression /\[?(?<groupA>[A])?(?:[ ]*)?(?<groupB>[B])?(?:[ ]*)?(?<groupC>[C])\]/gm Is there a way to achieve the desired output using a plugin or spe ...

Guide to ensuring modal box only appears once all criteria are satisfied

On my website, I have a form that requests the user's personal information. After filling out the form, a modal pops up with a "Thank you for signing up" message. The issue is that even if all fields are left blank and the button is clicked, the modal ...

Guide on altering the cell's background hue depending on its value through javascript

I'm dealing with a table that has 3 columns: field1 is a Category field2 and field3 contain Measures (specifically integers 1, 2, 3, 4, and 5). Is there a way to use Javascript to conditionally format the background color of cells in the table hol ...

Is this conditional statement accurate?

Could this be a legitimate condition? Why isn't it functioning as expected in PHP? var myString = 'hello'; if(myString == ('hello' || 'hi' || 'bonjour' || 'hallo')){ alert('Welcome'); } ...

CSS: Concealing a separate div

I am working with a parent div in my code that has 2 child divs. I am hoping to find a way to hide the second child when hovering over the first child, using only CSS or JavaScript. Take a look at my Fiddle here <div class="parrent"> <div id ...

Encountering permission issues while attempting to add `@nuxtjs/sentry` in a Docker container running Node 16.14. Installation

While attempting to add @nuxtjs/sentry to my project by running npm install @nuxtjs/sentry, I encountered some issues. Here is the error message I received: npm ERR! code 1 npm ERR! path /app/node_modules/@sentry/cli npm ERR! command failed npm ERR! comm ...

"An error stating 'Unexpected token '<', '<!DOCTYPE'... is indicating that the JSON is not valid" has been encountered while using Next.js

I'm working on a Next.js project and have implemented a password reset form like the example below: https://i.sstatic.net/dXqsr.png After users enter their email, a POST request is sent to the /api/request-password-reset route: import { NextRequest, ...

How can we ensure that the previous selection is cleared in jQgrid only if the checkbox is not clicked

I've set up a grid with the option for multiselect: true so that I can delete multiple rows at once. When the onSelectRow event is triggered, data related to the ID is loaded and shown to the user. Everything seems to be working fine in this example ...

What could be causing the issue with my hour parameter in node-cron?

Having difficulty setting up a cron job to run with node-cron every Monday at 8:30. I've tried using "30 8 * * Mon" and even "30 08 * * Mon", but it doesn't seem to work. Interestingly, "30 * * * Mon" does work and runs every hour on the 30th min ...

I'm hoping to place the image in the top left corner, but I'm unsure how to achieve this using tailwind and next

I am struggling to add my image to the top right corner, and I can't seem to figure out what's going wrong. Can someone please help me spot the error? import Image from "next/image"; function Header() { return ( {/* left */} ...

Angular with D3 - Semi-Circle Graph Color Order

Can someone assist me with setting chart colors? I am currently using d3.js in angular to create a half pie chart. I would like to divide it into 3 portions, each represented by a different color. The goal is to assign 3 specific colors to certain ranges. ...

Success/Fail Page for Form Redirect

I've been struggling to figure out how to redirect my form to a success or fail page. I've scoured the internet for solutions, looking into traditional form redirects and even JavaScript onClick redirects. Can someone guide me on adding a redirec ...

The Chrome extension is unable to add text to the existing window

Lately, I've been attempting to develop an extension that will automatically add a div to the beginning of the current page. I've been following the guide provided on this https://developer.chrome.com/extensions/activeTab page. The code from the ...

The ReactJS code encountered an error when attempting to access the 'location' property of an undefined or null reference

My Reactapp is encountering an error due to a specific file. import React from 'react'; import { Router, Route } from 'react-router'; import App from './components/App'; import About from './components/About'; im ...

unable to add browse-sync to Ubuntu 16.04

I recently installed nodejs and npm and attempted to install browser-sync using the command npm install -g browser-sync. However, I encountered an error. npm install -g browser-sync npm ERR! Linux 4.15.0-101-generic npm ERR! argv "/usr/bin/nodejs" "/ ...

Stop mega menu items from disappearing when hovered over

I'm currently working on a web page that features a mega menu. When I hover over the mega menu, it displays its items. However, when I try to hover over the items, they disappear. Here is the HTML code snippet: <li class="dropdown mega-dropdown m ...

What is causing my tooltips to flicker in Firefox but not in Chrome?

When I tried viewing the provided fiddle in Firefox (version 5.0.1 on a Mac), I noticed that when hovering over a day in the calendar and placing the mouse pointer inside the tooltip, the tooltip would flash on and off. Interestingly, this issue did not oc ...