Found a way to use display names on React UI, there might be a better way

I have found the following way to use display names instead of party identifiers on the React UI:

I copy into every component where I want either to display party display names or submit commands submitting party display names, the following code snippet:

// DISPLAYNAME_DEPENDENCIES_START
import {  useEffect } from 'react';
import { useLedger, useParty } from '@daml/react';
import Ledger, { PartyInfo } from '@daml/ledger';
// DISPLAYNAME_DEPENDENCIES_END

 // DISPLAYNAME_START
const [knownParties, setKnownParties] = React.useState<PartyInfo[]>([]);
const partyId = useParty();
const ledger: Ledger = useLedger();

useEffect(() => {
  const getKnownParties = async () => {
    let lst = await ledger.listKnownParties();
    setKnownParties(lst);
  } ;
  getKnownParties()
}, [ledger]);

function displayName (id: string | undefined): (string | undefined) {

    if (id === undefined) {
      return id;
    } else {
      return knownParties.filter(x => x.identifier === id)[0]?.displayName
    }}

function partyIdentifier (displayName: string | undefined): string {
  let filterResult = knownParties.filter(x => x.displayName === displayName)
  if (filterResult === []) {
    throw new Error("Party display name doesn't exist")
  } else {
    return filterResult[0].identifier
  }
  
}
// DISPLAYNAME_END

In the Create Daml App this means I have to copy this into four components.

I can imagine that I could do something similar once in the code on the top level. Is there a way to do that?

1 Like

You can wrap the useState and useEffect hooks along with the displayName and partyIdentifier functions into a function in a separate file and just make them available by exporting the wrapper function. You can then import this custom hook in the files you want to use it and just use it as any other hook.

I think this is the example use case for custom hooks on the React docs: https://reactjs.org/docs/hooks-custom.htm

3 Likes

Thanks, sound good.

1 Like

Depending on what exactly you want, you could also do it at the top-level and then pass it down via a context and get access via useContext. There isn’t really any point in recomputing this in every component.

2 Likes

Yes, that’s exactly what I was thinking about, not having to recompute the list of known parties at different levels. Will check it out. I also need that the list is always up-to-date, so that if another user joins in the background I can refer to them by their user names.

1 Like

Elm, for instance, handles the whole application state in the global Model, and doesn’t have this trickling down of state through the component hierarchy like React.

1 Like