Unable to fetch contracts in the UI

Hello,

I am unable to return contracts from my ledger pls see code below:
http://localhost:3000/#/app/default is returned successfully by no data.
Am I missing something?
SDK 1.3
daml 1.2


  if (moduleName && entityName) {

    return contract.templateId.moduleName === moduleName && contract.templateId.entityName === entityName;

  } else if (moduleName) {

    return contract.templateId.moduleName === moduleName;

  } else if (entityName) {

    return contract.templateId.entityName === entityName;

  }

  return true;

}

export function getContracts(state, moduleName, entityName) {

  return state.contracts.filter(c => templateFilter(c, moduleName, entityName));

}

export function getContract(state, moduleName, entityName) {

  return state.contracts.find(c => templateFilter(c, moduleName, entityName));

}


export async function fetchContracts(dispatch, token, setIsFetching, setError) {

  setError(false);

  setIsFetching(true);

  if (!!token) {

    dispatch({ type: "CONTRACT_REQUEST"});

    try {

      const options = { method: 'GET', headers: { "Authorization": "Bearer " + token }};

     // const body = JSON.stringify({"templateIds" : ["Main:Transfer"]})

      const response = await fetch("http://localhost:7575/v1/query", options);

      

      const json = await response.json();

      if (json.status !== 200) throw new Error(json.errors);

      const contracts = [].concat.apply([], json.result);

      dispatch({ type: "CONTRACT_RESPONSE", contracts });

      setIsFetching(false);

    }

    catch (error) {

      console.log(error)

      dispatch({ type: "CONTRACT_ERROR", error });

      setError(true);

      setIsFetching(false);

    }

  } else {

    console.log("No token found")

    dispatch({ type: "CONTRACT_ERROR", error: "No token found" });

    setError(true);

    setIsFetching(false);

  }

}

Hi @KsarCapital,
I recommend using the network tab in your browser’s developer tools to see what exactly is failing.

I suspect that the issue is coming from the Same-origin policy. Specifically, it looks like your UI is running on localhost:3000 while you have the JSON API running on localhost:7575. Browsers will block these requests by default as a security measure.

For development, you can use the webpack proxy similar to the setup used in the Getting Started Guide. In a production setup, you would usually use something like NGINX as a reverse proxy to make sure that your UI and the JSON API run on the same host and port.

thank you @cocreature. but I have already added “proxy”: “http://localhost:7575” in my ui\package.json? I should have been redirected to `http://localhost:3000/#/app/default?
Thanks,

Network log file as below:

log.js:24 [HMR] Waiting for update signal from WDS...
react-dom.development.js:24994 Download the React DevTools for a better development experience: https://fb.me/react-devtools
index.js:14 It looks like there are several instances of `@material-ui/styles` initialized in this application.
This may cause theme propagation issues, broken class names, specificity issues, and makes your application bigger without a good reason.

See https://material-ui.com/r/styles-instance-warning for more info.
D:\demo\ui\node_modules\@material-ui\core\node_modules\@material-ui\styles\esm\index.js @ index.js:14
__webpack_require__ @ bootstrap:784
fn @ bootstrap:150
D:\demo\ui\node_modules\@material-ui\core\esm\styles\createStyles.js @ createStyles.js:1
__webpack_require__ @ bootstrap:784
fn @ bootstrap:150
D:\demo\ui\node_modules\@material-ui\core\esm\styles\index.js @ index.js:1
__webpack_require__ @ bootstrap:784
fn @ bootstrap:150
D:\demo\ui\node_modules\@material-ui\core\esm\index.js @ index.js:1
__webpack_require__ @ bootstrap:784
fn @ bootstrap:150
D:\demo\ui\src\index.js @ UserContext.js:88
__webpack_require__ @ bootstrap:784
fn @ bootstrap:150
1 @ main.chunk.js:12
__webpack_require__ @ bootstrap:784
checkDeferredModules @ bootstrap:45
webpackJsonpCallback @ bootstrap:32
(anonymous) @ main.chunk.js:1
:3000/#/app/default:1 Unchecked runtime.lastError: The message port closed before a response was received.
:3000/#/app/default:1 Access to fetch at 'http://localhost:7575/v1/query' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
LedgerContext.js:103 GET http://localhost:7575/v1/query net::ERR_FAILED
fetchContracts @ LedgerContext.js:103
(anonymous) @ App.js:17
commitHookEffectListMount @ react-dom.development.js:19731
commitPassiveHookEffects @ react-dom.development.js:19769
callCallback @ react-dom.development.js:188
invokeGuardedCallbackDev @ react-dom.development.js:237
invokeGuardedCallback @ react-dom.development.js:292
flushPassiveEffectsImpl @ react-dom.development.js:22853
unstable_runWithPriority @ scheduler.development.js:653
runWithPriority$1 @ react-dom.development.js:11039
flushPassiveEffects @ react-dom.development.js:22820
(anonymous) @ react-dom.development.js:22699
workLoop @ scheduler.development.js:597
flushWork @ scheduler.development.js:552
performWorkUntilDeadline @ scheduler.development.js:164
LedgerContext.js:112 TypeError: Failed to fetch

1 Like

Small note the way to do code blocks is via ```, not '''. I’ve adjusted the above posts.

1 Like

Try replacing

const response = await fetch("http://localhost:7575/v1/query", options);

by

const response = await fetch("http://localhost:3000/v1/query", options);

Your UI is hosted at localhost:3000 so this complies with the Same Origin Policy. The proxy will then redirect the request to localhost:7575.

1 Like

No it is still not fetching data. I can see my contracts via navigator (port 4000) but no luck with UI(port 3000). Please advise.

Which error do you see in the network tab now?


I am suspecting that passing moduleName and entityName are not filtering my contracts (getContracts(state, moduleName, entityName) -> const transfers = getContracts(ledger, "Main","Transfer");
)?

It looks like message port closed before a response was received often comes from Browser extension, e.g., see Chrome: "The message port closed before a response was received." · Issue #130 · mozilla/webextension-polyfill · GitHub.

However, I don’t expect that this is causing the issue here. I recommend looking at the network tab in your browser’s dev tools (your screenshot is from the console). If you see the request and the response contains the contracts you expect, then you can be sure that the issue is somewhere in the filtering you do afterwards.

Looking at your code, it seems like you might be running into a similar issue as in How to successfully create a contract using python request lib?. templateId is a string of the form packageid:modulename:entityname. So if you want to get the module name you’ll have to do something like contract.templateId.split(":")[1] and contract.templateId.split(":")[2] for the entity name (ideally only split once).

thank you @cocreature, my apologies here is the network message:


looks like my contracts have been fetched successfully. I need to investigate further the following code why my data is not showing on the screen? btw i didn’t change the filter (previous code seem to work).

return (

    <>

      <Contracts

        contracts={transfers}

        columns={[

          ["ContractId", "contractId"],

          ["Identifier", "argument.event.eventIdentifier.0.assignedIdentifier.0.identifier.value"],

          ["Version", "argument.event.eventIdentifier.0.assignedIdentifier.0.version"],

          ["Amount", "argument.event.primitive.transfer.0.cashTransfer.0.amount.amount"],

          ["Ccy", "argument.event.primitive.transfer.0.cashTransfer.0.amount.currency.value"],

          ["Payer", "argument.event.primitive.transfer.0.cashTransfer.0.payerReceiver.payerPartyReference.externalReference"],

          ["Receiver", "argument.event.primitive.transfer.0.cashTransfer.0.payerReceiver.receiverPartyReference.externalReference"],

        ]}

thanks for your help.

1 Like

It looks like you’re working with an older version of the DAML UI Template and CDM. It’s possible that something goes wrong with those path expressions (eg. trying to read a None optional or an empty list) and for some reason the error is not surfaced in the console.

To help narrow down the problem, you can try to remove all columns except for the ContractId one, to exclude the possibility that the problem is with those path expressions.

2 Likes

Agreed. I need to get the UI working prior to upgrade my CDM. how can I get latest version of DAML UI template? Thanks

You can find the latest version of the UI template at GitHub - digital-asset/daml-ui-template.