Moralis useApiContract hook is not working in production

In short, the useApiContract hook works good, when my React dapp is run on the localhost through yarn start, but when the production build is uploaded to IPFS, it doesn’t.

Observed production behaviour:

  • I call useApiContract hook, passing funcitonName, address, abi, chain parameters.
  • I call the runContractFunction inside the useEffect hook, which is obtained through the step above.
  • Both data and error variables returned by the useApiContact hook are null.
  • Both isFetching and isLoading variables are going false->true->false.
  • There is no request to the runContractFunction in devtools.

Expected production behaviour:

  • I expect the hook to work without errors or at least return an error.

In production I see this:

Deployed version is available here https://ipfs.moralis.io:2053/ipfs/QmVzug46jSxrBYj8rRPKuscEpkjXkNJ9UJaWaLzow9hoAT/index.html

Observed localhost behaviour:

  • Everything works. The data contains the result of the contract call, the error is null, the app requests runContractFunction

On the localhost i see this:

What exactly I am doing:

Please help me solve this issue or suggest, what am i doing wrong :pray:t2:.

Ooops, I have fixed it myself. I have added Moralis.start() in the src/index.tsx so it looks like this:

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import {MoralisProvider} from 'react-moralis'
import AppThemeProvider from './theme/app-theme-provider';
import {AuthModalContextProvider} from './components/web3/Account/auth-modal-context';
import Moralis from 'moralis';

const APP_ID = process.env.REACT_APP_MORALIS_APPLICATION_ID;
const SERVER_URL = process.env.REACT_APP_MORALIS_SERVER_URL;

const root = ReactDOM.createRoot(
  document.getElementById('root') as HTMLElement
);

Moralis.start({
  appId: APP_ID,
  serverUrl: SERVER_URL
}).then(() => {
  root.render(
    <React.StrictMode>
      {
        APP_ID && SERVER_URL && (
          <MoralisProvider
            appId={APP_ID}
            serverUrl={SERVER_URL}
          >
            <AppThemeProvider>
              <AuthModalContextProvider>
                <App/>
              </AuthModalContextProvider>
            </AppThemeProvider>
          </MoralisProvider>
        )
      }
    </React.StrictMode>
  );
  reportWebVitals();
})

But the issue is not completely solved:

I don’t think that you really need to call Moralis.start in react like that, it should work without that.

It can also depend on how you import Moralis SDK later in other code.

Totally agree with you, but it is not working without Moralis.start. That’s an issue.

In the code which calls contract, I don’t import Moralis directly. I just import single hook like this:

import {useApiContract} from 'react-moralis';

export default function TripleText(): JSX.Element | null {
const {runContractFunction, data, error, isLoading, isFetching} = useApiContract({
functionName: 'getTokenParams',
address: daoContractAddress,
abi: daoAbi.abi,
chain: defaultChainId as any,
})
useEffect(() => {
console.log('run getTokenParams contract function', 'contract', daoContractAddress, 'abi', daoAbi.abi, 'chain', defaultChainId)
runContractFunction().then() // then() to prevent warning
// eslint-disable-next-line
}, [])
// ... some other code to render the result
}

The complete code is here https://github.com/custom-app/DAO-Art.eth-access-token/blob/89a0316284ec1072630aee12fbd235d43500a720/mint-landing/src/pages/main-page/triple-text.tsx#L34

To make sure you’re doing it after moralis.start, you can rather use isInitialized from useMoralis as a checker to be sure if Moralis.start is completed rather, such like

useEffect(() => {
  console.log('run getTokenParams contract function', 'contract', daoContractAddress, 'abi', daoAbi.abi, 'chain', defaultChainId)
  !!isInitialized && runContractFunction().then() // then() to prevent warning
  // eslint-disable-next-line
}, [isInitialized])
1 Like

Thank you!
Please, add this to the official docs, or make MoralisProvider hide children, when it is not initialized.