Hardhat Testing – TypeError: Cannot Read Properties of Undefined ‘Place’

blockchainethers.jshardhattesting

I am developing a hardhat project, in which I was writing tests for smart contracts, and tried to run a function which recieves a bunch of arguments with different data types including struct as given below:

function createNGO(
        RegDetails memory reg_details,
        string memory reg_cert,
        string memory act_name,
        address registered_with,
        string memory type_of_NGO,
        string memory name_of_NGO,
        SectorDetails memory sector,
        FCRADetails memory FCRA,
        string memory achievements,
        ContactDetails memory contact_details,
        string memory website_url
    ) external;

For testing this function, I've written a test as follows:

it("Create NGO", async () => {
    const [ owner ] = await ethers.getSigners();
    let args = [
        [{
            id: owner.address,
            uid: "uid",
            reg_no: "reg_no",
            reg_date: 123,
            pan_card: "pan_card",
            addr: [{
                place: "place",
                city: "city",
                state: "state",
                pin_code: 302031
            }],
            is_verified: false,
            is_active: true
        }],
        "reg_cert",
        "act_name",
        owner.address,
        "type_of_NGO",
        "name",
        [{
            key_issues: "key_issues",
            addr: [{
                place: "place",
                city: "city",
                state: "state",
                pin_code: 302031
            }]
        }],
        [{
            is_available: true,
            reg_no: 123
        }],
        "achievements",
        [{
            addr: [{
                place: "place",
                city: "city",
                state: "state",
                pin_code: 302031
            }],
            phone_number: [{
                code: 91,
                phone_number: 1234567890
            }],
            alt_phone_number: [{
                code: 91,
                phone_number: 1234567890
            }],
            email: "mail.com",
            last_modified: 123
        }],
        "mywebsite.com"
    ]
    await this.NGOContract.createNGO(...args);
    console.log(await this.NGOContract.NGOs[owner]);
});

While running this test I encountered an unrelevant error, given below:

1) NGOContract
       Create NGO:
     TypeError: Cannot read properties of undefined (reading 'place')
      at E:\Projects\Personal Projects\Charitier\server\node_modules\@ethersproject\contracts\src.ts\index.ts:152:62
      at Array.map (<anonymous>)
      at E:\Projects\Personal Projects\Charitier\server\node_modules\@ethersproject\contracts\src.ts\index.ts:149:44
      at step (node_modules\@ethersproject\contracts\lib\index.js:48:23)
      at Object.next (node_modules\@ethersproject\contracts\lib\index.js:29:53)  
      at E:\Projects\Personal Projects\Charitier\server\node_modules\@ethersproject\contracts\lib\index.js:23:71
      at new Promise (<anonymous>)
      at __awaiter (node_modules\@ethersproject\contracts\lib\index.js:19:12)    
      at resolveAddresses (node_modules\@ethersproject\contracts\lib\index.js:119:12)
      at E:\Projects\Personal Projects\Charitier\server\node_modules\@ethersproject\contracts\src.ts\index.ts:163:22
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

I tried searching it on stackexchange but found nothing.
I am using [email protected], [email protected], VSCode and localhost network for development.
Suggestions are appreciated and Thanks in Advance!

Best Answer

As I saw many posts on internet telling that we can pass struct in only private and internal as given here, is a myth. We can pass struct to a function with public and external visibility as well. If you're getting error for TypeError: Cannot read properties of undefined (reading 'length') or this one I mentioned above, then the issue is you're passing struct in wrong format in your function. Format to pass params is as follows:

let args = [
    {
        id: this.owner.address,
        uid: "uid",
        reg_no: "reg_no",
        reg_date: 123,
        pan_card: "pan_card",
        addr: {
            place: "place",
            city: "city",
            state: "state",
            pin_code: 302031,
        },
        is_verified: false,
        is_active: true,
    },
    "reg_cert",
    "act_name",
    this.owner.address,
    "type_of_NGO",
    "name",
    {
        key_issues: "key_issues",
        addr: {
            place: "place",
            city: "city",
            state: "state",
            pin_code: 302031,
        },
    },
    {
        is_available: true,
        reg_no: 123,
    },
    "achievements",
    {
        addr: {
            place: "place",
            city: "city",
            state: "state",
            pin_code: 302031,
        },
        phone_number: {
            code: 91,
            phone_number: 1234567890,
        },
        alt_phone_number: {
            code: 91,
            phone_number: 1234567890,
        },
        email: "mail.com",
        last_modified: 123,
    },
    "mywebsite.com",
];
await this.NGOContract.createNGO(...args);

For passing struct we need to create an object with all the keys resembling to struct created in contract. I hope this helps everyone!

Related Topic