'I am trying to connect Lottery Contract to React Application using Metamask, But when I call manager() method on the contract I get an empty array

Account array is being logged perfectly fine and Metamask is running correctly, Ethereum is being used properly but every time I call manager() I just receive an empty array,

I am following a Udemy course of Stephen Grider

 // SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.5.0 <0.9.0;

contract Lottery {
    address public manager;
    address payable[] public players;

    constructor(){
       manager = msg.sender;
    }

    function enter() public payable{
        require(msg.value > 0.01 ether);
        players.push(payable(msg.sender));
    }

    function random() private view returns (uint){
        return uint256(
                keccak256(
                    abi.encodePacked(block.difficulty, block.number, players)
                )
            );
    }

    function pickWinner() public restricted {
        uint index = random() % players.length;
        address contractAddress = address(this);
        players[index].transfer(contractAddress.balance);
        players = new address payable[](0);
    }

    modifier restricted() {
        require(msg.sender == manager);
        _;
    }

    function getPlayers() public view returns(address payable[] memory){
        return players;
    }
 }

Frontend React Web3 initiation

import Web3 from "web3";

const web3 = new Web3(window.ethereum);

export default web3;

Frontend React Contract Creation

import web3 from "./web3";

const contractAddress = "0x0C04a9a1587524dA1F2c65561Ca157f582242FC8";

const abi = [
  {
    inputs: [],
    stateMutability: "nonpayable",
    type: "constructor",
    constant: undefined,
    payable: undefined,
    signature: "constructor",
  },
  {
    inputs: [],
    name: "enter",
    outputs: [],
    stateMutability: "payable",
    type: "function",
    constant: undefined,
    payable: true,
    signature: "0xe97dcb62",
  },
  {
    inputs: [],
    name: "getPlayers",
    outputs: [[Object]],
    stateMutability: "view",
    type: "function",
    constant: true,
    payable: undefined,
    signature: "0x8b5b9ccc",
  },
  {
    inputs: [],
    name: "manager",
    outputs: [[Object]],
    stateMutability: "view",
    type: "function",
    constant: true,
    payable: undefined,
    signature: "0x481c6a75",
  },
  {
    inputs: [],
    name: "pickWinner",
    outputs: [],
    stateMutability: "nonpayable",
    type: "function",
    constant: undefined,
    payable: undefined,
    signature: "0x5d495aea",
  },
  {
    inputs: [[Object]],
    name: "players",
    outputs: [[Object]],
    stateMutability: "view",
    type: "function",
    constant: true,
    payable: undefined,
    signature: "0xf71d96cb",
  },
];

const lottery = new web3.eth.Contract(abi, contractAddress);

export default lottery;

Calling Contract Methods in App.js:

import React, { useEffect, useRef, useState } from "react";
import web3 from "./web3";
import lottery from "./lottery";
const { ethereum } = window;

function App() {
  useEffect(() => {
    //Calling Manager
    async function getManager() {
      const account = await ethereum.request({ method: "eth_requestAccounts" });
      console.log(account);

      const manager = await lottery.methods.manager().call({
        from: account[0],
      });
      console.log(manager);
    }

    getManager();
  }, []);

  return (
    <div>
      <h2>Lottery Contract</h2>
      <p>This Contract is managed by</p>
    </div>
  );
}

export default App;


Solution 1:[1]

I run your code and got this issue:

constructor(){
       manager = msg.sender;
    }

msg.sender should be payable. as far as I know, you do not need to explicitly declare that it is payable but since in enter function you have this line:

players.push(payable(msg.sender));

In typed strict languages, types should match. I run your solidity code and got this error:

enter image description here

if you change constructor to this :

 constructor (){
        manager = payable(msg.sender);
    }

Now it works

Solution 2:[2]

I am new to solidity and react so I am not 100% sure. But it seems manager is a variable of type address not an array. And since you are just calling it in react, would it not be:

const manager = await lottery.methods.manager().call();

Since you are only calling/getting the managers address, I do not think there is a need to set/send any values.

Solution 3:[3]

Copy the abi from remix, not from the console.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Yilmaz
Solution 2 Victor Luna
Solution 3 Priyanshu