trufflesuite / drizzle-react-components-legacy

A set of useful components for common dapp UI elements.
95 stars 70 forks source link

ContractData fails using internal variables + getter functions #109

Closed ijxy closed 5 years ago

ijxy commented 5 years ago

After making the below changes to the 'test-app':

pragma solidity >=0.4.21 <0.6.0;

contract SimpleStorage {
    event StorageSet(string _message);

    uint internal storedData; // changed from public
    bool internal storedBool; // changed from public

    function set(uint x) public {
        storedData = x;

        emit StorageSet("Data stored successfully!");
    }

    function setBool(bool x) public {
        storedBool = x;

        emit StorageSet("Boolean stored successfully!");
    }

    function get() public returns (uint) { return storedData; } // added
    function getBool() public returns (bool) { return storedBool; } // added
}
            <h2>SimpleStorage</h2>
            <p>
              This shows a simple ContractData component with no arguments,
              along with a form to set its value.
            </p>
            <p>
              <strong>Stored Value: </strong>
              <ContractData
                drizzle={drizzle}
                drizzleState={drizzleState}
                contract="SimpleStorage"
                method="get" // changed from method="storedData"
              />
            </p>
            <ContractForm
              drizzle={drizzle}
              drizzleState={drizzleState}
              contract="SimpleStorage"
              method="set"
            />
            <p>
              <strong>Stored Boolean Value: </strong>
              <ContractData
                drizzle={drizzle}
                drizzleState={drizzleState}
                contract="SimpleStorage"
                method="getBool" // changed from method="storedBool"
              />
            </p>
            <ContractForm
              drizzle={drizzle}
              drizzleState={drizzleState}
              contract="SimpleStorage"
              method="setBool"
            />
            ...

launching the frontend causes an error:

image

(text version in full below)

drizzle-react-components.js:390 Uncaught TypeError: this.contracts[this.props.contract].methods[this.props.method].cacheCall is not a function
    at new o (drizzle-react-components.js:390)
    at constructClassInstance (react-dom.development.js:11786)
    at updateClassComponent (react-dom.development.js:15264)
    at beginWork (react-dom.development.js:16262)
    at performUnitOfWork (react-dom.development.js:20279)
    at workLoop (react-dom.development.js:20320)
    at HTMLUnknownElement.callCallback (react-dom.development.js:147)
    at Object.invokeGuardedCallbackDev (react-dom.development.js:196)
    at invokeGuardedCallback (react-dom.development.js:250)
    at replayUnitOfWork (react-dom.development.js:19503)
    at renderRoot (react-dom.development.js:20433)
    at performWorkOnRoot (react-dom.development.js:21357)
    at performWork (react-dom.development.js:21267)
    at performSyncWork (react-dom.development.js:21241)
    at requestWork (react-dom.development.js:21096)
    at scheduleWork (react-dom.development.js:20909)
    at Object.enqueueSetState (react-dom.development.js:11595)
    at Provider.push../node_modules/react/cjs/react.development.js.Component.setState (react.development.js:336)
    at drizzle-react.js:1116
    at dispatch (redux.js:214)
    at middleware.js:72
    at dispatch (redux.js:613)
    at utils.js:282
    at proc.js:557
    at exec (scheduler.js:20)
    at flush (scheduler.js:63)
    at asap (scheduler.js:35)
    at runPutEffect (proc.js:553)
    at runEffect (proc.js:496)
    at next (proc.js:366)
    at currCb (proc.js:449)
o @ drizzle-react-components.js:390
constructClassInstance @ react-dom.development.js:11786
updateClassComponent @ react-dom.development.js:15264
beginWork @ react-dom.development.js:16262
performUnitOfWork @ react-dom.development.js:20279
workLoop @ react-dom.development.js:20320
callCallback @ react-dom.development.js:147
invokeGuardedCallbackDev @ react-dom.development.js:196
invokeGuardedCallback @ react-dom.development.js:250
replayUnitOfWork @ react-dom.development.js:19503
renderRoot @ react-dom.development.js:20433
performWorkOnRoot @ react-dom.development.js:21357
performWork @ react-dom.development.js:21267
performSyncWork @ react-dom.development.js:21241
requestWork @ react-dom.development.js:21096
scheduleWork @ react-dom.development.js:20909
enqueueSetState @ react-dom.development.js:11595
push../node_modules/react/cjs/react.development.js.Component.setState @ react.development.js:336
(anonymous) @ drizzle-react.js:1116
dispatch @ redux.js:214
(anonymous) @ middleware.js:72
dispatch @ redux.js:613
(anonymous) @ utils.js:282
(anonymous) @ proc.js:557
exec @ scheduler.js:20
flush @ scheduler.js:63
asap @ scheduler.js:35
runPutEffect @ proc.js:553
runEffect @ proc.js:496
next @ proc.js:366
currCb @ proc.js:449
Promise.then (async)
resolvePromise @ proc.js:515
runCallEffect @ proc.js:584
runEffect @ proc.js:496
next @ proc.js:366
currCb @ proc.js:449
runSelectEffect @ proc.js:784
runEffect @ proc.js:496
next @ proc.js:366
proc @ proc.js:314
resolveIterator @ proc.js:521
runCallEffect @ proc.js:584
runEffect @ proc.js:496
next @ proc.js:366
currCb @ proc.js:449
end @ proc.js:412
task.cont @ proc.js:125
next @ proc.js:372
currCb @ proc.js:449
(anonymous) @ proc.js:567
exec @ scheduler.js:20
flush @ scheduler.js:63
asap @ scheduler.js:35
runPutEffect @ proc.js:553
runEffect @ proc.js:496
next @ proc.js:366
currCb @ proc.js:449
Promise.then (async)
resolvePromise @ proc.js:515
runCallEffect @ proc.js:584
runEffect @ proc.js:496
next @ proc.js:366
proc @ proc.js:314
resolveIterator @ proc.js:521
runCallEffect @ proc.js:584
runEffect @ proc.js:496
next @ proc.js:366
currCb @ proc.js:449
end @ proc.js:412
task.cont @ proc.js:125
next @ proc.js:372
currCb @ proc.js:449
(anonymous) @ proc.js:567
exec @ scheduler.js:20
flush @ scheduler.js:63
asap @ scheduler.js:35
runPutEffect @ proc.js:553
runEffect @ proc.js:496
next @ proc.js:366
currCb @ proc.js:449
Promise.then (async)
resolvePromise @ proc.js:515
runCallEffect @ proc.js:584
runEffect @ proc.js:496
next @ proc.js:366
proc @ proc.js:314
resolveIterator @ proc.js:521
runCallEffect @ proc.js:584
runEffect @ proc.js:496
next @ proc.js:366
currCb @ proc.js:449
end @ proc.js:412
task.cont @ proc.js:125
next @ proc.js:372
currCb @ proc.js:449
(anonymous) @ proc.js:567
exec @ scheduler.js:20
flush @ scheduler.js:63
asap @ scheduler.js:35
runPutEffect @ proc.js:553
runEffect @ proc.js:496
next @ proc.js:366
currCb @ proc.js:449
Promise.then (async)
resolvePromise @ proc.js:515
runCallEffect @ proc.js:584
runEffect @ proc.js:496
next @ proc.js:366
proc @ proc.js:314
resolveIterator @ proc.js:521
runCallEffect @ proc.js:584
runEffect @ proc.js:496
next @ proc.js:366
proc @ proc.js:314
runForkEffect @ proc.js:625
runEffect @ proc.js:496
next @ proc.js:366
currCb @ proc.js:449
takeCb @ proc.js:531
put @ channel.js:88
(anonymous) @ channel.js:190
(anonymous) @ channel.js:216
exec @ scheduler.js:20
flush @ scheduler.js:63
asap @ scheduler.js:35
(anonymous) @ channel.js:215
emit @ channel.js:39
(anonymous) @ middleware.js:74
(anonymous) @ drizzle.js:15815
Promise.then (async)
Drizzle @ drizzle.js:15813
./src/App.js @ App.js:10
__webpack_require__ @ bootstrap:781
fn @ bootstrap:149
./src/index.js @ index.css?f3f6:45
__webpack_require__ @ bootstrap:781
fn @ bootstrap:149
0 @ serviceWorker.js:135
__webpack_require__ @ bootstrap:781
checkDeferredModules @ bootstrap:45
webpackJsonpCallback @ bootstrap:32
(anonymous) @ main.chunk.js:1
index.js:1375 The above error occurred in the <o> component:
    in o (at MyComponent.js:67)
    in p (at MyComponent.js:65)
    in div (at MyComponent.js:59)
    in div (at MyComponent.js:24)
    in Unknown (at App.js:16)
    in Provider (at App.js:15)
    in App (at src/index.js:7)

Consider adding an error boundary to your tree to customize error handling behavior.
Visit https://fb.me/react-error-boundaries to learn more about error boundaries.
console.<computed> @ index.js:1375
logCapturedError @ react-dom.development.js:17874
logError @ react-dom.development.js:17910
update.callback @ react-dom.development.js:18933
callCallback @ react-dom.development.js:17101
commitUpdateEffects @ react-dom.development.js:17141
commitUpdateQueue @ react-dom.development.js:17131
commitLifeCycles @ react-dom.development.js:18166
commitAllLifeCycles @ react-dom.development.js:19668
callCallback @ react-dom.development.js:147
invokeGuardedCallbackDev @ react-dom.development.js:196
invokeGuardedCallback @ react-dom.development.js:250
commitRoot @ react-dom.development.js:19892
(anonymous) @ react-dom.development.js:21440
unstable_runWithPriority @ scheduler.development.js:255
completeRoot @ react-dom.development.js:21439
performWorkOnRoot @ react-dom.development.js:21362
performWork @ react-dom.development.js:21267
performSyncWork @ react-dom.development.js:21241
requestWork @ react-dom.development.js:21096
scheduleWork @ react-dom.development.js:20909
enqueueSetState @ react-dom.development.js:11595
push../node_modules/react/cjs/react.development.js.Component.setState @ react.development.js:336
(anonymous) @ drizzle-react.js:1116
dispatch @ redux.js:214
(anonymous) @ middleware.js:72
dispatch @ redux.js:613
(anonymous) @ utils.js:282
(anonymous) @ proc.js:557
exec @ scheduler.js:20
flush @ scheduler.js:63
asap @ scheduler.js:35
runPutEffect @ proc.js:553
runEffect @ proc.js:496
next @ proc.js:366
currCb @ proc.js:449
Promise.then (async)
resolvePromise @ proc.js:515
runCallEffect @ proc.js:584
runEffect @ proc.js:496
next @ proc.js:366
currCb @ proc.js:449
runSelectEffect @ proc.js:784
runEffect @ proc.js:496
next @ proc.js:366
proc @ proc.js:314
resolveIterator @ proc.js:521
runCallEffect @ proc.js:584
runEffect @ proc.js:496
next @ proc.js:366
currCb @ proc.js:449
end @ proc.js:412
task.cont @ proc.js:125
next @ proc.js:372
currCb @ proc.js:449
(anonymous) @ proc.js:567
exec @ scheduler.js:20
flush @ scheduler.js:63
asap @ scheduler.js:35
runPutEffect @ proc.js:553
runEffect @ proc.js:496
next @ proc.js:366
currCb @ proc.js:449
Promise.then (async)
resolvePromise @ proc.js:515
runCallEffect @ proc.js:584
runEffect @ proc.js:496
next @ proc.js:366
proc @ proc.js:314
resolveIterator @ proc.js:521
runCallEffect @ proc.js:584
runEffect @ proc.js:496
next @ proc.js:366
currCb @ proc.js:449
end @ proc.js:412
task.cont @ proc.js:125
next @ proc.js:372
currCb @ proc.js:449
(anonymous) @ proc.js:567
exec @ scheduler.js:20
flush @ scheduler.js:63
asap @ scheduler.js:35
runPutEffect @ proc.js:553
runEffect @ proc.js:496
next @ proc.js:366
currCb @ proc.js:449
Promise.then (async)
resolvePromise @ proc.js:515
runCallEffect @ proc.js:584
runEffect @ proc.js:496
next @ proc.js:366
proc @ proc.js:314
resolveIterator @ proc.js:521
runCallEffect @ proc.js:584
runEffect @ proc.js:496
next @ proc.js:366
currCb @ proc.js:449
end @ proc.js:412
task.cont @ proc.js:125
next @ proc.js:372
currCb @ proc.js:449
(anonymous) @ proc.js:567
exec @ scheduler.js:20
flush @ scheduler.js:63
asap @ scheduler.js:35
runPutEffect @ proc.js:553
runEffect @ proc.js:496
next @ proc.js:366
currCb @ proc.js:449
Promise.then (async)
resolvePromise @ proc.js:515
runCallEffect @ proc.js:584
runEffect @ proc.js:496
next @ proc.js:366
proc @ proc.js:314
resolveIterator @ proc.js:521
runCallEffect @ proc.js:584
runEffect @ proc.js:496
next @ proc.js:366
proc @ proc.js:314
runForkEffect @ proc.js:625
runEffect @ proc.js:496
next @ proc.js:366
currCb @ proc.js:449
takeCb @ proc.js:531
put @ channel.js:88
(anonymous) @ channel.js:190
(anonymous) @ channel.js:216
exec @ scheduler.js:20
flush @ scheduler.js:63
asap @ scheduler.js:35
(anonymous) @ channel.js:215
emit @ channel.js:39
(anonymous) @ middleware.js:74
(anonymous) @ drizzle.js:15815
Promise.then (async)
Drizzle @ drizzle.js:15813
./src/App.js @ App.js:10
__webpack_require__ @ bootstrap:781
fn @ bootstrap:149
./src/index.js @ index.css?f3f6:45
__webpack_require__ @ bootstrap:781
fn @ bootstrap:149
0 @ serviceWorker.js:135
__webpack_require__ @ bootstrap:781
checkDeferredModules @ bootstrap:45
webpackJsonpCallback @ bootstrap:32
(anonymous) @ main.chunk.js:1
Show 6 more frames
index.js:1375 The above error occurred in the <o> component:
    in o (at MyComponent.js:82)
    in p (at MyComponent.js:80)
    in div (at MyComponent.js:59)
    in div (at MyComponent.js:24)
    in Unknown (at App.js:16)
    in Provider (at App.js:15)
    in App (at src/index.js:7)

Consider adding an error boundary to your tree to customize error handling behavior.
Visit https://fb.me/react-error-boundaries to learn more about error boundaries.
console.<computed> @ index.js:1375
logCapturedError @ react-dom.development.js:17874
logError @ react-dom.development.js:17910
update.callback @ react-dom.development.js:18933
callCallback @ react-dom.development.js:17101
commitUpdateEffects @ react-dom.development.js:17141
commitUpdateQueue @ react-dom.development.js:17131
commitLifeCycles @ react-dom.development.js:18166
commitAllLifeCycles @ react-dom.development.js:19668
callCallback @ react-dom.development.js:147
invokeGuardedCallbackDev @ react-dom.development.js:196
invokeGuardedCallback @ react-dom.development.js:250
commitRoot @ react-dom.development.js:19892
(anonymous) @ react-dom.development.js:21440
unstable_runWithPriority @ scheduler.development.js:255
completeRoot @ react-dom.development.js:21439
performWorkOnRoot @ react-dom.development.js:21362
performWork @ react-dom.development.js:21267
performSyncWork @ react-dom.development.js:21241
requestWork @ react-dom.development.js:21096
scheduleWork @ react-dom.development.js:20909
enqueueSetState @ react-dom.development.js:11595
push../node_modules/react/cjs/react.development.js.Component.setState @ react.development.js:336
(anonymous) @ drizzle-react.js:1116
dispatch @ redux.js:214
(anonymous) @ middleware.js:72
dispatch @ redux.js:613
(anonymous) @ utils.js:282
(anonymous) @ proc.js:557
exec @ scheduler.js:20
flush @ scheduler.js:63
asap @ scheduler.js:35
runPutEffect @ proc.js:553
runEffect @ proc.js:496
next @ proc.js:366
currCb @ proc.js:449
Promise.then (async)
resolvePromise @ proc.js:515
runCallEffect @ proc.js:584
runEffect @ proc.js:496
next @ proc.js:366
currCb @ proc.js:449
runSelectEffect @ proc.js:784
runEffect @ proc.js:496
next @ proc.js:366
proc @ proc.js:314
resolveIterator @ proc.js:521
runCallEffect @ proc.js:584
runEffect @ proc.js:496
next @ proc.js:366
currCb @ proc.js:449
end @ proc.js:412
task.cont @ proc.js:125
next @ proc.js:372
currCb @ proc.js:449
(anonymous) @ proc.js:567
exec @ scheduler.js:20
flush @ scheduler.js:63
asap @ scheduler.js:35
runPutEffect @ proc.js:553
runEffect @ proc.js:496
next @ proc.js:366
currCb @ proc.js:449
Promise.then (async)
resolvePromise @ proc.js:515
runCallEffect @ proc.js:584
runEffect @ proc.js:496
next @ proc.js:366
proc @ proc.js:314
resolveIterator @ proc.js:521
runCallEffect @ proc.js:584
runEffect @ proc.js:496
next @ proc.js:366
currCb @ proc.js:449
end @ proc.js:412
task.cont @ proc.js:125
next @ proc.js:372
currCb @ proc.js:449
(anonymous) @ proc.js:567
exec @ scheduler.js:20
flush @ scheduler.js:63
asap @ scheduler.js:35
runPutEffect @ proc.js:553
runEffect @ proc.js:496
next @ proc.js:366
currCb @ proc.js:449
Promise.then (async)
resolvePromise @ proc.js:515
runCallEffect @ proc.js:584
runEffect @ proc.js:496
next @ proc.js:366
proc @ proc.js:314
resolveIterator @ proc.js:521
runCallEffect @ proc.js:584
runEffect @ proc.js:496
next @ proc.js:366
currCb @ proc.js:449
end @ proc.js:412
task.cont @ proc.js:125
next @ proc.js:372
currCb @ proc.js:449
(anonymous) @ proc.js:567
exec @ scheduler.js:20
flush @ scheduler.js:63
asap @ scheduler.js:35
runPutEffect @ proc.js:553
runEffect @ proc.js:496
next @ proc.js:366
currCb @ proc.js:449
Promise.then (async)
resolvePromise @ proc.js:515
runCallEffect @ proc.js:584
runEffect @ proc.js:496
next @ proc.js:366
proc @ proc.js:314
resolveIterator @ proc.js:521
runCallEffect @ proc.js:584
runEffect @ proc.js:496
next @ proc.js:366
proc @ proc.js:314
runForkEffect @ proc.js:625
runEffect @ proc.js:496
next @ proc.js:366
currCb @ proc.js:449
takeCb @ proc.js:531
put @ channel.js:88
(anonymous) @ channel.js:190
(anonymous) @ channel.js:216
exec @ scheduler.js:20
flush @ scheduler.js:63
asap @ scheduler.js:35
(anonymous) @ channel.js:215
emit @ channel.js:39
(anonymous) @ middleware.js:74
(anonymous) @ drizzle.js:15815
Promise.then (async)
Drizzle @ drizzle.js:15813
./src/App.js @ App.js:10
__webpack_require__ @ bootstrap:781
fn @ bootstrap:149
./src/index.js @ index.css?f3f6:45
__webpack_require__ @ bootstrap:781
fn @ bootstrap:149
0 @ serviceWorker.js:135
__webpack_require__ @ bootstrap:781
checkDeferredModules @ bootstrap:45
webpackJsonpCallback @ bootstrap:32
(anonymous) @ main.chunk.js:1
Show 6 more frames
index.js:1375 uncaught at initializeDrizzle TypeError: this.contracts[this.props.contract].methods[this.props.method].cacheCall is not a function
    at new o (http://localhost:3000/static/js/1.chunk.js:14638:83)
    at constructClassInstance (http://localhost:3000/static/js/1.chunk.js:72534:22)
    at updateClassComponent (http://localhost:3000/static/js/1.chunk.js:76012:9)
    at beginWork (http://localhost:3000/static/js/1.chunk.js:77010:20)
    at performUnitOfWork (http://localhost:3000/static/js/1.chunk.js:81027:16)
    at workLoop (http://localhost:3000/static/js/1.chunk.js:81068:28)
    at renderRoot (http://localhost:3000/static/js/1.chunk.js:81148:11)
    at performWorkOnRoot (http://localhost:3000/static/js/1.chunk.js:82105:11)
    at performWork (http://localhost:3000/static/js/1.chunk.js:82015:11)
    at performSyncWork (http://localhost:3000/static/js/1.chunk.js:81989:7)
    at requestWork (http://localhost:3000/static/js/1.chunk.js:81844:9)
    at scheduleWork (http://localhost:3000/static/js/1.chunk.js:81657:9)
    at Object.enqueueSetState (http://localhost:3000/static/js/1.chunk.js:72343:9)
    at Provider.push../node_modules/react/cjs/react.development.js.Component.setState (http://localhost:3000/static/js/1.chunk.js:85770:20)
    at http://localhost:3000/static/js/1.chunk.js:18713:49
    at dispatch (http://localhost:3000/static/js/1.chunk.js:92718:7)
    at http://localhost:3000/static/js/1.chunk.js:90735:22
    at dispatch (http://localhost:3000/static/js/1.chunk.js:93117:28)
    at http://localhost:3000/static/js/1.chunk.js:92414:12
    at http://localhost:3000/static/js/1.chunk.js:91331:52
    at exec (http://localhost:3000/static/js/1.chunk.js:92043:5)
    at flush (http://localhost:3000/static/js/1.chunk.js:92086:5)
    at asap (http://localhost:3000/static/js/1.chunk.js:92058:5)
    at runPutEffect (http://localhost:3000/static/js/1.chunk.js:91327:60)
    at runEffect (http://localhost:3000/static/js/1.chunk.js:91270:280)
    at next (http://localhost:3000/static/js/1.chunk.js:91140:9)
    at currCb (http://localhost:3000/static/js/1.chunk.js:91223:7)
ijxy commented 5 years ago

image

ijxy commented 5 years ago

So I don't think it has anything to do with whether storedData is public or not as I've tried it both ways and get still fails with the same error.

ijxy commented 5 years ago

I was able to get the truffle react-box (no drizzle) working with the same contract

pragma solidity ^0.5.0;

contract SimpleStorage {
  uint storedData;

  function set(uint x) public {
    storedData = x;
  }

  function get() public view returns (uint) {
    return storedData;
  }
}

so I'm definitely inclined to think that this is a drizzle issue, specifically with cacheCall.

adrianmcli commented 5 years ago

Hey thanks for reporting this issue. Do you think you can throw up a reproduction repo so we can run it ourselves and figure out he problem?

ijxy commented 5 years ago

Hey thanks for reporting this issue. Do you think you can throw up a reproduction repo so we can run it ourselves and figure out he problem?

Fortunately, after many hours, I was able to figure it out. Eventually, I realised from the JS console logs that the getter methods were becoming objects with cacheSend methods inside drizzle instead of cacheCall. It was at that point that I realised that I'd forgotten to add view to the signature. Once added, the problem was no more. Facepalm.