Search code examples
javascriptreactjsethereumblockchainweb3js

TypeError: Cannot read property 'methods' of null


I am working on a very basic erc721 token minting dapp using react and web3. I created an arrow function to mint the tokens but I keep getting an error that the methods is not defined when I try to mint a new token... I am still a beginner so I apologize if there are any rookie mistakes.

my react code

import React, { Component } from "react";
import AsycentTokenContract from "./contracts/AsycentToken.json";

import Web3 from "web3";

import "./App.css";

class App extends Component {
  state = {account: '', contract: null, totalSupply:0, colors: []};

  async componentWillMount() {
    await this.loadWeb3()
    await this.loadBlockchainData()
  }

  async loadWeb3() {
    if(window.ethereum) {
      window.web3 = new Web3(window.ethereum)
      await window.ethereum.enable()
    }
    else if (window.web3) {
      window.web3 = new Web3(window.web3.currentProvider)
    }
    else {
      window.alert('non Ethereum browser detected. Dowload Metamask')
    }
  }

  async loadBlockchainData() {
    const web3 = window.web3
    //load accounts
    const accounts = await web3.eth.getAccounts()
    this.setState({account: accounts[0]})
    //load contract
    const networkId = await web3.eth.net.getId()
    const networkData =  AsycentTokenContract.networks[networkId]
    if(networkData) {
      const abi = AsycentTokenContract.abi
      const address = networkData.address
      console.log(address)
      const contract = new web3.eth.Contract(abi, address)
      console.log(contract)
      const totalSupply = await contract.methods.totalSupply().call()
      this.setState({totalSupply})
      //Load Colors
      for(var i = 1; i <= totalSupply; i++) {
        const color = await contract.methods.colors(i - 1).call()
        this.setState({
          colors: [...this.state.colors, color]
        })
        console.log(this.state.colors)
      }
    } else{
      window.alert('Smart contract not deployed to detected network')
    }

  }

  mint = (color) => {
    console.log(color)
    this.state.contract.methods.mint(color).send({from: this.state.account})
    .once('receipt', (receipt) => {
      this.setState({
        colors: [...this.state.colors, color]
      })
    })
  }




  render() {
    return (
      <div className="App">
        <h1>{this.state.account}</h1>
        <div>
          <h1>Issue Token</h1>
          <form onSubmit={(e) => {
            e.preventDefault()
            const color = this.color.value
            this.mint(color)
          }}>
            <input 
              type="text"
              placeholder='ex #FFFFFF'
              ref={(input) => {
                this.color = input
              }}
            />
            <input type="submit"
            value="MINT"
            />
          </form>
        </div>
        <div>{this.state.colors.map((color, key) =>{
         return(
            <div key={key}>
              <div className='token' style={{backgroundColor: color}}></div>
              <div>{color}</div>
          </div>)
        })}</div>
      </div>
    );
  }
}

export default App;

smart contract code

pragma solidity >=0.4.21 <0.7.0;

import "../node_modules/@openzeppelin/contracts/token/ERC721/ERC721.sol";

contract AsycentToken is ERC721 {

    string[] public colors;
    mapping(string => bool) _colorExists;

    string public _name = "AsycentToken";
    string public _symbol = "AT";

    constructor () ERC721(_name, _symbol) public {
    }

    function mint(string memory _color) public {
        require(!_colorExists[_color], 'color already exists');
        colors.push(_color);
        uint _id = colors.length;
        _mint(msg.sender, _id);
        _colorExists[_color] = true;
    }
}

the error

TypeError: Cannot read property 'methods' of null App.mint

C:/Users/Shawn/react-nft-minter/client/src/App.js:62
  59 | mint = (color) => {
  60 |   console.log(color)
  61 |   const web3 = window.web3
> 62 |   this.state.contract.methods.mint(color).send({from: this.state.account})
     | ^  63 |   .once('receipt', (receipt) => {
  64 |     this.setState({
  65 |       colors: [...this.state.colors, color]

View compiled

onSubmit

C:/Users/Shawn/react-nft-minter/client/src/App.js:82
  79 | <form onSubmit={(e) => {
  80 |   e.preventDefault()
  81 |   const color = this.color.value
> 82 |   this.mint(color)
     | ^  83 | }}>
  84 |   <input 
  85 |     type="text"

View compiled ▶ 22 stack frames were collapsed. This screen is visible only in development. It will not appear if the app crashes in production. Open your browser’s developer console to further inspect this error.


Solution

  • First : your initial state of this.state.contract is null, so first check if it's not null

    if(this.state.contract) {
       this.state.contract.methods....
    

    Second : In your code there is no such code that is setting up this.state.contract , please check that also