I'm trying to invoke the drizzle useCacheCall() hook of a React Component from two different places. This is the invoked React component
const FamilyContainer = ({ member }) => {
console.log("inside family container, member: ", member);
const { useCacheCall } = drizzleReactHooks.useDrizzle();
const organization = useCacheCall("MyContract", "getOrganization", member);
console.log("organization: ", organization && organization);
const maxLevel = useCacheCall("MyContract", "levels");
console.log("maxLevel: ", maxLevel && typeof maxLevel);
if (!isLoaded(organization) || !isLoaded(maxLevel)) {
return "loading...";
}
if (isEmpty(organization) || isEmpty(maxLevel)) return <PageNotFound />;
return (
<FamilySection
organization={organization}
maxLevel={parseInt(maxLevel, 10)}
/>
);
};
export default FamilyContainer;
I'm invoking the above mentioned React Component from the first location by copy pasting the url to the browser address bar: http://localhost:3000/#/invited/7434DC1BF0, which is successfully executing. this is the invocation code:
const InviteReceived = ({ playerAccount, inviterData }) => {
const useStyles = makeStyles((theme) => ({
root: {
flexGrow: 1,
},
}));
const classes = useStyles();
const history = useHistory();
return (
<Grid container spacing={0}>
<Grid item xs={12} sm={12} md={12} lg={5}>
<Box
display="flex"
flexDirection="column"
justifyContent="center"
p={1}
m={0}
bgcolor="black"
>
<InviteReceivedSection
playerAccount={playerAccount}
inviterAccount={inviterData.ID}
/>
<PayTributeSection playerAccount={playerAccount} />
</Box>
</Grid>
<Grid item xs={12} sm={12} md={12} lg={7}>
<FamilyContainer member={inviterData.ID} />
</Grid>
</Grid>
);
};
export default InviteReceived;
The invocation from second location of the exact same React Component, by copy pasting the url to the browser address bar: http://localhost:3000/#/member/0x16Aa59291f0C27586B87CDcF48630cB721Dcd0cC , keeps repeatedly failing with the error message: TypeError: Cannot read property 'methods' of undefined. But if I run the first invocation first and then invoke the second component (using URLs), then error doesnt happen (weird).
const MemberComponent = ({ playerAccount }) => {
console.log("Inside member component, playeraccount ", playerAccount);
const useStyles = makeStyles((theme) => ({
root: {
flexGrow: 1,
},
}));
const classes = useStyles();
const history = useHistory();
return (
<Grid container spacing={0}>
<Grid item xs={12} sm={12} md={12} lg={5}>
<Box
display="flex"
flexDirection="column"
justifyContent="center"
p={1}
m={0}
bgcolor="black"
>
<ProfileDetailsSection playerAccount={playerAccount} />
<RecruitSection playerAccount={playerAccount} />
</Box>
</Grid>
<Grid item xs={12} sm={12} md={12} lg={7}>
<FamilyContainer member={playerAccount} />
</Grid>
</Grid>
);
};
export default MemberComponent;
This is the Error Trace:
TypeError: Cannot read property 'methods' of undefined
current
C:/src/hooks/create-use-cache-call.js:19
16 | {}
17 | )
18 | } else {
> 19 | const instance = drizzle.contracts[contractNameOrNames]
| ^ 20 | const cacheKey = instance.methods[methodNameOrFunction].cacheCall(...args)
21 | const cache =
22 | drizzleState.contracts[contractNameOrNames][methodNameOrFunction][
View compiled
e.useDrizzleState
C:/src/hooks/index.js:36
33 |
34 | // This is the escape hatch mentioned above. We keep a ref to `args` and whenever they change, we immediately update the state just like in the subscription.
35 | // This won't have any effect if `args` is undefined.
> 36 | const argsRef = useRef(args)
| ^ 37 | const [state, setState] = useState(
38 | mapStateRef.current(drizzle.store.getState())
39 | )
View compiled
(anonymous function)
C:/src/hooks/create-use-cache-call.js:8
5 | methodNameOrFunction,
6 | ...args
7 | ) => {
> 8 | const isFunction = typeof methodNameOrFunction === 'function'
9 | const drizzleState = useDrizzleState(drizzleState => {
10 | if (isFunction) {
11 | return contractNameOrNames.reduce(
View compiled
FamilyContainer
C:/code/MyContract/codebase/client/src/containers/FamilyContainer.js:10
7 | const FamilyContainer = ({ member }) => {
8 | console.log("inside family container, member: ", member);
9 | const { useCacheCall } = drizzleReactHooks.useDrizzle();
> 10 | const organization = useCacheCall("MyContract", "getOrganization", member);
11 | console.log("organization: ", organization && organization);
12 |
13 | const maxLevel = useCacheCall("MyContract", "levels");
View compiled
▶ 16 stack frames were collapsed.
Module../src/index.js
C:/code/MyContract/codebase/client/src/index.js:100
97 | const drizzle = new Drizzle(drizzleOptions, reduxStore);
98 | console.log("Drizzle: ", drizzle, " reduxStore: ", reduxStore);
99 |
> 100 | ReactDOM.render(
101 | <React.StrictMode>
102 | <ThemeProvider theme={theme}>
103 | <drizzleReactHooks.DrizzleProvider drizzle={drizzle}>
View compiled
__webpack_require__
C:/code/MyContract/codebase/client/webpack/bootstrap:784
781 | };
782 |
783 | // Execute the module function
> 784 | modules[moduleId].call(module.exports, module, module.exports, hotCreateRequire(moduleId));
| ^ 785 |
786 | // Flag the module as loaded
787 | module.l = true;
View compiled
fn
C:/code/MyContract/codebase/client/webpack/bootstrap:150
147 | );
148 | hotCurrentParents = [];
149 | }
> 150 | return __webpack_require__(request);
| ^ 151 | };
152 | var ObjectFactory = function ObjectFactory(name) {
153 | return {
View compiled
1
http://localhost:3000/static/js/main.chunk.js:7398:18
__webpack_require__
C:/code/MyContract/codebase/client/webpack/bootstrap:784
781 | };
782 |
783 | // Execute the module function
> 784 | modules[moduleId].call(module.exports, module, module.exports, hotCreateRequire(moduleId));
| ^ 785 |
786 | // Flag the module as loaded
787 | module.l = true;
View compiled
checkDeferredModules
C:/code/MyContract/codebase/client/webpack/bootstrap:45
42 | }
43 | if(fulfilled) {
44 | deferredModules.splice(i--, 1);
> 45 | result = __webpack_require__(__webpack_require__.s = deferredModule[0]);
| ^ 46 | }
47 | }
48 |
View compiled
Array.webpackJsonpCallback [as push]
http://localhost:3000/static/js/bundle.js:33:19
30 | /******/ deferredModules.push.apply(deferredModules, executeModules || []);
31 | /******/
32 | /******/ // run deferred modules when all chunks ready
> 33 | /******/ return checkDeferredModules();
| ^ 34 | /******/ };
35 | /******/ function checkDeferredModules() {
36 | /******/ var result;
View source
UPDATE: also, I have discovered that the problem only happens when i post the link directly in the address bar. but if the component is traversed internally from some other component, then the error doesnt happen. any idea as to why? Any ideas what could be causing a prob only in one invocation?
finally found the issue. since I was using the URL directly, the second invocation (the one throwing error) was executing the useCacheCall() even before the drizzle has initialized properly and setup the connection to ethereum. Putting a </drizzleReactHooks.Initializer> component on my < App / > solved the issue:
<drizzleReactHooks.Initializer
error="There was an error."
loadingContractsAndAccounts="loading contracts & accounts..."
loadingWeb3="loading web3..."
>
<App/>
</drizzleReactHooks.Initializer>