# Using @daml/ledger with React Class Components

**URL:** <https://forum.canton.network/t/using-daml-ledger-with-react-class-components/895>\
**Category:** App Development\
**Created:** [July 22, 2020, 1:16pm UTC](https://forum.canton.network/t/using-daml-ledger-with-react-class-components/895 "2020-07-22T13:16:44Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![alex\_m](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/alex_m/32/550_2.png) [@alex\_m](https://forum.canton.network/u/alex_m)\
**Post date:** [July 22, 2020, 1:16pm UTC](https://forum.canton.network/t/using-daml-ledger-with-react-class-components/895/1 "2020-07-22T13:16:44Z")

</div>

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?

---

<div class="post-metadata">

**Author:** ![drsk](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/drsk/32/43_2.png) [@drsk](https://forum.canton.network/u/drsk)\
**Post date:** [July 22, 2020, 3:20pm UTC](https://forum.canton.network/t/using-daml-ledger-with-react-class-components/895/2 "2020-07-22T15:20:34Z")

</div>

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](https://github.com/digital-asset/daml/blob/8b4f73983bde1ad6c15d3ac482af6436ae14770f/language-support/ts/daml-react/createLedgerContext.ts#L151) as a class component. In that piece of code you also see how `ledger.streamQuery` is used.

I hope that helps!

---

<div class="post-metadata">

**Author:** ![alex\_m](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/alex_m/32/550_2.png) [@alex\_m](https://forum.canton.network/u/alex_m)\
**Post date:** [July 22, 2020, 3:24pm UTC](https://forum.canton.network/t/using-daml-ledger-with-react-class-components/895/3 "2020-07-22T15:24:07Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![alex\_m](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/alex_m/32/550_2.png) [@alex\_m](https://forum.canton.network/u/alex_m)\
**Post date:** [July 22, 2020, 3:45pm UTC](https://forum.canton.network/t/using-daml-ledger-with-react-class-components/895/4 "2020-07-22T15:45:49Z")

</div>

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`

---

<div class="post-metadata">

**Author:** ![alex\_m](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/alex_m/32/550_2.png) [@alex\_m](https://forum.canton.network/u/alex_m)\
**Post date:** [July 22, 2020, 5:05pm UTC](https://forum.canton.network/t/using-daml-ledger-with-react-class-components/895/5 "2020-07-22T17:05:46Z")

</div>

Solved my problem with:  
`const getStream = (ledger: Ledger) => ledger.streamQuery(TransportationRecord);`  
…  
`private stream: ReturnType<typeof getStream> | undefined = undefined;`

---

<div class="post-metadata">

**Author:** ![drsk](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/drsk/32/43_2.png) [@drsk](https://forum.canton.network/u/drsk)\
**Post date:** [July 23, 2020, 9:18am UTC](https://forum.canton.network/t/using-daml-ledger-with-react-class-components/895/6 "2020-07-23T09:18:37Z")

</div>

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`.

---

<div class="post-metadata">

**Author:** ![alex\_m](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/alex_m/32/550_2.png) [@alex\_m](https://forum.canton.network/u/alex_m)\
**Post date:** [July 23, 2020, 10:13am UTC](https://forum.canton.network/t/using-daml-ledger-with-react-class-components/895/7 "2020-07-23T10:13:38Z")

</div>

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?

---

<div class="post-metadata">

**Author:** ![SamirTalwar](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/samirtalwar/32/374_2.png) [@SamirTalwar](https://forum.canton.network/u/SamirTalwar)\
**Post date:** [July 23, 2020, 12:33pm UTC](https://forum.canton.network/t/using-daml-ledger-with-react-class-components/895/8 "2020-07-23T12:33:48Z")

</div>

I think you want to hook into two of the [React lifecycle methods](https://reactjs.org/docs/state-and-lifecycle.html#adding-lifecycle-methods-to-a-class), namely `componentDidMount` and `componentWillUnmount`. Subscribe in the former, unsubscribe in the latter.

---

<div class="post-metadata">

**Author:** ![drsk](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/drsk/32/43_2.png) [@drsk](https://forum.canton.network/u/drsk)\
**Post date:** [July 23, 2020, 7:22pm UTC](https://forum.canton.network/t/using-daml-ledger-with-react-class-components/895/9 "2020-07-23T19:22:13Z")

</div>

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