In Daml, a party is represented by an object with three fields: identifier
, displayName
, and the islocal
flag.
In the introductory examples it’s totally fine to use the party identifier in the UI as the representation of Daml parties. The UI template itself uses the identifier
field of the Daml party as Party
type.
In other cases the party identifier might be too clumsy to display and submit on the demo UI. E.g. in the Daml Hub or Canton, where party identifiers are forced to be long strings.
So with the help of @Stephen, @Gary_Verhaegen, @Mate_Varga and @cocreature, I wrote a custom hook which queries the list of known parties from the ledger, and computes the display name from the party id, and vice versa. We can use these functions to display the display names on the UI, and submit commands using the display name.
As @cocreature pointed out, there is an even more effective way, when the UI doesn’t have to recompute at different levels the same data, using Context. I will come back to this approach some time later, when I have more experience with React.
So this is the code of the custom hook and the way you can use it:
// Usage in components:
// import {useKnownParties} from '../UseKnownParties'
// Within the component:
// const {displayName, partyIdentifier} = useKnownParties ()
import React, { useEffect } from 'react';
import { useLedger, useParty } from '@daml/react';
import Ledger, { PartyInfo } from '@daml/ledger';
export function useKnownParties () {
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]);
return {
displayName : (id: string | undefined): (string | undefined) => {
if (id === undefined) {
return id;
} else {
return knownParties.filter(x => x.identifier === id)[0]?.displayName
}},
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
}
}
}}
An example from the Create React App for displaying the display name rather the the party id in the MainView
component:
import {useKnownParties} from '../UseKnownParties'
...
const {displayName, partyIdentifier} = useKnownParties ()
...
<Header as='h1' size='huge' color='blue' textAlign='center' style={{padding: '1ex 0em 0ex 0em'}}>
{myUser ? `Welcome, ${displayName(myUser.username)}!` : 'Loading...'}
</Header>
An example for submitting the display name on the UI for exercising the Follow
choice, in the PartyListEdit
component:
const addParty = async (event?: React.FormEvent) => {
if (event) {
event.preventDefault();
}
setIsSubmitting(true);
const success = await onAddParty(partyIdentifier(newParty)); // MODIFIED FOR USING DISPLAY NAME
setIsSubmitting(false);
if (success) {
setNewParty('');
}
}