useStreamFetchByKeys is missing closeHandler argument

The documentation for DAML react says that useStreamFetchByKeys can take an extra parameter:

"@param closeHandler A callback that will be called if the underlying
 *        WebSocket connection fails in an unrecoverable way."

However the code does not reflect this, no such parameter can be passed in. Sometimes the websocket connection fails and I need a way to handle this.

Note this is with version 1.11.1

2 Likes

Thanks for reporting this, seems like the whole docstring for that function contains a few issues, probably due to some copy-paste.

1 Like

I created a PR to fix this here.

1 Like

And @Gary_Verhaegen actually fixed the issue by adding the closeHandler back here.

1 Like

Hi @huw,

This is an oversight on my end. Sorry about it!

The functionality is there, but not exposed by the default ledger methods. This will be fixed (probably in 1.14, as the 1.13 release process has already started),

I unfortunately don’t have a good workaround to recommend in the meantime.

1 Like

Thanks guys. For now I plan to use useQuery instead of useStreamFetchByKeys.

1 Like

Sorry I should mention this. When I use useStreamFetchByKeys I was consistently getting websocket connection failures. That is why I was looking for a handler for this error. However, when I use uesQuery I have never noticed any websocket failures. Note: I’m using the sandbox - spinning up everything with the daml start command. Don’t know if this is a separate issue.

1 Like

Hi @huw,

This does sound like a separate issue. As far as I understand they both go through the same code paths so I would not expect any difference in behaviour there, but then again most bugs are things developers would not expect. Can you give us any more information on how to reproduce this issue? Would it be possible for you to produce and share a minimal project that shows the problem?

1 Like

Hi @Gary_Verhaegen , when useStreamFetchByKeys should return an empty result (no keys match the provided keys), then it returns (as expected) no contracts. If there are contracts matching then it results in websocket failures immediately.

1 Like

Hi @huw,

I am going to need a little bit more help in order to reproduce the issue, as I cannot seem to get it to fail. Here is what I’ve done.

  1. Run daml new --template=create-daml-app t, then cd t
  2. Open up daml/User.daml and add:
template Counter with
    owner: Party
    count: Int
  where
    signatory owner
    key owner : Party
    maintainer key
    preconsuming choice Increment: ContractId Counter with
      controller owner
      do
        create this with count = count + 1
  1. Create a new file ui/src/component/Counter.tsx with:
import React from 'react'
import { List, ListItem } from 'semantic-ui-react';
import { User } from '@daml.js/t';
import { useStreamFetchByKeys, useParty } from '@daml/react';

const Counter: React.FC = () => {
  const me = useParty();
  const result = useStreamFetchByKeys(User.Counter, () => [me], []);

  return (
    <List relaxed>
      {result.contracts.map(message => {
        return (
          <ListItem
            className='test-select-message-item'
            key={1}>
            <strong>{message ? message.payload.count : "not found"}</strong>
          </ListItem>
        );
      })}
    </List>
  );
};

export default Counter;
  1. Open ui/src/components/MainView.tsx and add import Counter from './Counter'; at the top, then
            <Segment>
              <Counter />
            </Segment>

just before </Grid.Column> near the end of the file.

  1. Run daml start, and then in another terminal, in the ui folder, npm install followed by npm start.

Log in as alice and you should see a websocket connection for the counter. You can create the counter with:

curl 'http://localhost:3000/v1/create' \
  -H 'authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJodHRwczovL2RhbWwuY29tL2xlZGdlci1hcGkiOnsibGVkZ2VySWQiOiJ0LXNhbmRib3giLCJhcHBsaWNhdGlvbklk
IjoidCIsImFjdEFzIjpbImFsaWNlIl19fQ.y7x_iLwmFSn9m3RdWSBQWndjxI0zttWhc8ESNWRNymM' \
  -H 'content-type: application/json' \
  --data-raw '{"templateId":"User:Counter","payload":{"owner":"alice","count":0}}'

and increment it with:

curl 'http://localhost:3000/v1/exercise' \
  -H 'authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJodHRwczovL2RhbWwuY29tL2xlZGdlci1hcGkiOnsibGVkZ2VySWQiOiJ0LXNhbmRib3giLCJhcHBsaWNhdGlvbklkIjoidCIsImFjdEFzIjpbImFsaWNlIl19fQ.y7x_iLwmFSn9m3RdWSBQWndjxI0zttWhc8ESNWRNymM' \
  -H 'content-type: application/json' \
  --data-raw '{"templateId":"User:Counter","key":"alice","choice":"Increment","argument":{}}' 

and, at least for me, this all works as expected and I can see the counter incrementing “in real time”.

Could you please:

  • Try to follow the above steps and report whether that works as expected for you?
  • If it does, try to come up with a similarly detailed account of how to reproduce the failure you see in your application?
1 Like

@Gary_Verhaegen apologies I haven’t had a chance to get back to you. I’ll take a look into your example and hopefully I can tweak it in order to reproduce the problem I was experiencing.