0

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

3 Answers 3

1

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.

Sign up to request clarification or add additional context in comments.

Comments

1

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.

1 Comment

Also, how can a server give back a JSX element, which is frontend code? Is this due to server-side rendering?
0

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>

3 Comments

Answer references another quesiton. Also, to avoid 'falsy' bugs could use the nullish coalescing operator (??), or optional chaining (.?) for brevity.
I think you can use optional chaining, but on the other hand, what I wrote is simply just more readable for me.
{{appointment.name?.content?.props?.children ?? appointment.name}}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.