web3js gives null as output for a valid smart contract function

54 Views Asked by At

I am watching a yt tutorial on building dapps from dapp university and followed along his video until i got this problem. He was trying to build a social media site where users can post and tippers can tip cryptocurrency.

This is the solidity code:

pragma solidity ^0.5.0;

contract SocialNetwork{
    string public name;
    uint public postCount = 0;
    mapping(uint => Post) public posts;

    struct Post{
        uint id;
        string content;
        uint tipAmount;
        address payable author;
    }

    event PostCreated(
        uint id,
        string content,
        uint tipAmount,
        address payable author
    );
    event PostTipped(
        uint id,
        string content,
        uint tipAmount,
        address payable author
    );

    constructor() public {
        name = "My network";
    } 

    function createPost(string memory _content) public{

        require(bytes(_content).length > 0);

        postCount++;
        posts[postCount] = Post(postCount,_content,0,msg.sender);
        emit PostCreated(postCount, _content,0, msg.sender);
    }

    function tipPost(uint _id) public payable{
        
        require(_id>0 && _id<=postCount);

        Post memory _post = posts[_id];
        address payable _author = _post.author;
        address(_author).transfer(msg.value);
        _post.tipAmount = _post.tipAmount+ msg.value;
        posts[_id] = _post;

        emit PostTipped(postCount, _post.content, _post.tipAmount, _author);
    }
}

This is the client side react code:

class App extends Component {

  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 eth browser");
        console.log('Non-Ethereum browser detected. You should consider trying MetaMask!');
    }
  }

  async loadBLockCHainData(){
    const web3 = window.web3
    const accounts = await web3.eth.getAccounts();
    console.log(accounts)
    this.setState({account:accounts[0]});

    const networkId = await web3.eth.net.getId();
    console.log(networkId)
    const networkData = SocialNetwork.networks[networkId]
    if(networkData){
      const socialNetwork = web3.eth.Contract(SocialNetwork.abi, networkData.address)
      this.setState({socialNetwork})
      const postCount = await socialNetwork.methods.postCount().call();
      console.log(postCount)
      this.setState({ postCount: postCount});
    }
    else{
      window.alert('Social Network not deployed to block chain')
    }
  }

  constructor(props){
    super(props);
    this.state={
      account :'',
      socialNetwork:null,
      postCount:0,
    }
  }
}

The problem is console.log(postCount) prints null for me while for him it prints BN(2) as he created 2 posts. Even I have created 2 posts from the truffle terminal.

I tried calling the postCount from truffle terminal and works as expected but doesn't work as expected in the client side web3js reactjs code.

1

There are 1 best solutions below

0
Akeel Ahmed Qureshi On

One thing which i observed in your code is that you may not be initialising the contract properly.

const socialNetwork = web3.eth.Contract(SocialNetwork.abi, networkData.address)

You should initialise the contract with the help of new keyword. For example:

const socialNetwork = new web3.eth.Contract(SocialNetwork.abi, networkData.address)

For more details you can refer the official docs of web3.js for initializing the new contract. https://web3js.readthedocs.io/en/v1.2.11/web3-eth-contract.html#new-contract

One more thing is that please ensure that the contract address in your React app networkData.address matches the deployed contract address on the Sepolia testnet.