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