Search code examples
ethereumsolidityweb3js

Access mapping of mapping of structs in web3.js


Suppose I have this data structure layout:

    struct ReviewStruct {
        string rating;
        ...
    }

    struct Restaurant {
        ...
        uint reviewCount;
        mapping(uint => ReviewStruct) reviews;
    }

    uint public restaurantCount = 0;
    mapping(uint => Restaurant) public restaurants;

Then, when I'm trying to access stuff in my JS app, it works, but not if I'm trying to access an actual review:

const restaurantCount = await review.methods.restaurantCount().call() // works
const restaurant = await review.methods.restaurants(2).call() // works
const reviewObj = await review.methods.restaurants(2).reviews(0).call() // throws an error

How do I access a mapping that is inside of a mapping (both are related to structs)?


Solution

  • On old ABI v1 encoding, structs cannot be returned by public functions, including automatically generated one for your mapping. This is simply not possible. You need to create your own accessor function that returns field values as a tuple (list of value) or use a toolchain that supports ABI v2 encoding.

    Furthermore I am not sure if accessor functions are automatically generated for mappings of mappings, so you might end up writing your own function any case.