Skip to content
Discussions/App Development/Using @daml/ledger with React Class ComponentsForum ↗

Using @daml/ledger with React Class Components

App Development9 posts638 views2 likesLast activity Jul 2020
AL
alex_mOP
Jul 2020

I prefer React class-based components and so am migrating my app (currently based on daml-ui-template) to use class-based components. I hence cannot use hooks. i was wondering if there were any examples of the usage of ledger.streamQuery such that it behaved similarly to useStreamQuery. Thanks!

For example, from the daml-ui-template

export default function Report() {
  const classes = useStyles();
  const party = useParty();
  const ledger = useLedger();
  const assets = useStreamQuery(Asset).contracts;
...
        <TableBody>
          {assets.map((a, i) => (
            <TableRow key={i} className={classes.tableRow}>
...

How could I do this same thing without hooks, and with class components?

DR
drsk
Jul 2020

Hi @alex_m,
I think you would have to write a class that maintains its own ledger object and also the state of the stream. Basically you would have to re-implement the useStreamQuery function like here as a class component. In that piece of code you also see how ledger.streamQuery is used.

I hope that helps!

AL
alex_m
Jul 2020

Looks promising! I’ll have a mess around and let you know.

AL
alex_m
Jul 2020

I think I would in fact have to maintain a Stream object. The problem I am encountering is that Stream is a generic type and the actual type signature of the Stream (as returned from my ledger.streamQuery(TransportationRecord) is very ugly. Something like:
Stream<TransportationRecord, undefined, "827c178267266bb80711c560783b5391b5a3a45035176e251689366b6ce2ee85:Records:TransportationRecord", readonly CreateEvent<TransportationRecord, undefined, "827c178267266bb80711c560783b5391b5a3a45035176e251689366b6ce2ee85:Records:TransportationRecord">[]>.
I’d rather not refer to it as any.

I am thinking of setting stream.on(...) stuff in componentDidMount and then closing the stream on componountWillUnmount

AL
alex_m
Jul 2020

Solved my problem with:
const getStream = (ledger: Ledger) => ledger.streamQuery(TransportationRecord);

private stream: ReturnType<typeof getStream> | undefined = undefined;

DR
drsk
Jul 2020

Are you sure you need to maintain a stream object in your class? I would have expected that you maintain a QueryResult object in your class and issue a ledger.streamQuery on creation of the class instance. You then get a stream back where you register your callbacks to update the QueryResult.

AL
alex_m
Jul 2020

Yeah I think so. Wouldn’t you need to maintain a reference to the stream such that you can call close on componentWillUnmount?

I would have expected that you maintain a QueryResult object in your class and issue a ledger.streamQuery on creation of the class instance

… So in the constructor? Can React components do fetchy things in a constructor?

SA
SamirTalwar
Jul 2020

I think you want to hook into two of the React lifecycle methods, namely componentDidMount and componentWillUnmount. Subscribe in the former, unsubscribe in the latter.

DR
drsk
Jul 2020

Not sure, otherwise you could have it as a method. I guess you need the stream object to properly close it.

← Back to Discussions