There are two types for parties:
The Party type is a string, and stands for the party identifier.
The PartyInfo type is an object, which has the following fields:
/**
* Full information about a Party.
*
*/
export type PartyInfo = {
identifier: Party;
displayName?: string;
isLocal: boolean;
}
In @daml/react I could only find the useParty hook, which returns the party identifier:
/**
* React hook to get the party currently connected to the ledger.
*/
export declare function useParty(): Party;
/**
* The counterpart of Daml's `Party` type.
*
* We represent `Party`s as strings matching the regular expression `[A-Za-z0-9:_\- ]+`.
*/
export declare type Party = string;
Is there a way to use the PartyInfo type in the React UI?
1 Like
The getParties function returns a Promise, so the challenge is to extract a string out of the Promise. Functional languages handle this elegantly with the Result monad and pattern matching.
I couldn’t find the right way for this yet.
This is a way how I tried it, it seems to be correct from a type perspective, the problem is that the useEffect hook doesn’t refresh the state.
import Ledger from '@daml/ledger'
const MainScreen: React.FC<Props> = ({onLogout}) => {
const [displayName, setDisplayName] = React.useState("abrakadabra");
const partyId = useParty();
useEffect(() => {
const getDisplayName = async (partyId : string) => {
let [pInfo, ...rest] = await Ledger.prototype.getParties([partyId]);
const dName = pInfo?.displayName || partyId;
setDisplayName(dName);
} ;
getDisplayName(partyId)
}, []);
return (
<>
<Menu icon borderless>
<Menu.Item>
<Image
as='a'
href='https://www.daml.com/'
target='_blank'
src='/daml.svg'
alt='DAML Logo'
size='mini'
/>
</Menu.Item>
<Menu.Menu position='right' className='test-select-main-menu'>
<Menu.Item position='right'>
You are logged in as {displayName}.
</Menu.Item>
<Menu.Item
position='right'
active={false}
className='test-select-log-out'
onClick={onLogout}
icon='log out'
/>
</Menu.Menu>
</Menu>
<MainView/>
</>
);
};
1 Like
Have you tried adding a console.log statement in your hook?
useEffect(() => {
const getDisplayName = async (partyId : string) => {
let [pInfo, ...rest] = await Ledger.prototype.getParties([partyId]);
console.log(JSON.stringify(pInfo));
const dName = pInfo?.displayName || partyId;
setDisplayName(dName);
} ;
getDisplayName(partyId)
}, []);
I can’t see any issue with the code at first glance, but adding that log will answer two important questions:
- Does the hook run at all? If not, there’s definitely something wrong somewhere and we need to dig more.
- Is the state not refreshing simply due to the value not changing? With
displayName being optional, and given the definition of dName, it’s not impossible that you just end up with the party identifier again.
1 Like
It seems that the getParties request doesn’t work, investigating why.
Oh, sorry I missed this yesterday: you’re not supposed to access the prototype directly, you’re supposed to first create a Ledger object and then call getParties on that.
In a React context you probably want to go through the @daml/react library, so initialization would look something like:
import DamlLedger from @daml/react
const App: React.FC = () => {
<DamlLedger
token: <your authentication token>
httpBaseUrl?: <optional http base url>
wsBaseUrl?: <optional websocket base url>
reconnectThreshold?: <optional delay in ms>
party: <the logged in party>
>
<MainScreen />
</DamlLedger>
};
then you can use the useLedger hook to get your hands on a properly initialized Ledger object:
const ledger = useLedger();
useEffect(() => {
const getDisplayName = async (partyId : string) => {
// Note here we're using the ledger object, not the
// prototype from the class
let [pInfo, ...rest] = await ledger.getParties([partyId]);
console.log(JSON.stringify(pInfo));
const dName = pInfo?.displayName || partyId;
setDisplayName(dName);
} ;
getDisplayName(partyId)
}, []);
1 Like