I have a payload that looks like this :
{
age: 35,
comments: "Walk in appointments",
dateTime: {
content: {
$$typeof: Symbol(react.element),
key: null,
props: {
children: "30-Aug-2021, 03:35 PM",
className: "-esm-appointments__appointments-table__statusContainer___RFuGX"
},
ref: null,
type: "span",
},
dob: "03 — Apr — 1986",
gender: "M",
id: "7cd38a6d-377e-491b-8284-b04cf8b8c6d8",
location: "HIV Clinic",
name: {
content: {
$$typeof: Symbol(react.element),
key: null,
props: {
children: "John Wilson",
to: "${openmrsSpaBase}/patient/8673ee4f-e2ab-4077-ba55-4980f408773e/chart"
},
ref: null,
type: ƒ ConfigurableLink(_param),
_self: null,
patientUuid: "8673ee4f-e2ab-4077-ba55-4980f408773e",
phoneNumber: "0700000000",
provider: "Dr James Cook",
visitType: "HIV Clinic"
}
It contains data from table rows , which are formatted like this :
const tableRows = useMemo(() => {
return appointments?.map((appointment) => ({
...appointment,
name: {
content: (
<ConfigurableLink to={`\${openmrsSpaBase}/patient/${appointment.patientUuid}/chart`}>
{appointment.name}
</ConfigurableLink>
),
},
}, [appointments]);
I am trying to create an interface for appointments data, which should handle data from different sources, some are JSX elements and some are strings.
I am having a hard time creating an interface that can handle either a JSX.Element or string :
export interface MappedAppointment {
id: string;
name: { content: JSX.Element } | string;
age: string;
gender: string;
phoneNumber: string;
dob: string;
patientUuid: string;
dateTime: { content: JSX.Element } | string;
serviceType: { content: JSX.Element } | string;
}
I keep getting the error Property 'content' does not exist on type 'string | { content: Element; }'.Property 'content' does not exist on type 'string'.
.
This is my view :
<span className={styles.label}>{appointment.name.content.props.children}</span> <br></br>
Any advise will be appreciated. Thanks
CodePudding user response:
You can check the typeof
of name property before accessing the property of it. If is not string type then access the content property on it.
typeof appointment.name === "string" ? appointment.name : appointment.name.content.props.children
Full code:
<span className={styles.label}>
{typeof appointment.name === "string" ? appointment.name : appointment.name.content.props.children}
</span>
<br></br>
You can read about type guarding using various patterns at this Typescript documentation.
CodePudding user response:
Similar to the previous answer. You can try an Elvis operator and check that the property exists.
Like:
<span className={styles.label}>
{(appointment.name.content && appointment.name.content.props && appointment.name.content.props.children) ?
appointment.name.content.props.children :
appointment.name
}
</span>
<br></br>
CodePudding user response:
name.content
is an object, not a JSX element. What you mean to type is
name: {
content: {
$$typeof: JSX.Element | string;
...other properties
}
};
That said, this response data looks tricky to me due to object keys/value such as type: ƒ ConfigurableLink(_param)
, _self
and $$typeof
. I'd recommend not using such keys as javascript may have issues reading them.