Mark
Mark

Reputation: 852

How to conditional render in react within a loop in a functional component

I know this question has been asked many times, I've looked through many stackoverflow posts but I can't seem to find the exact problem I'm facing. Below is the code:

<tbody>
        {ratioMetrics && Object.entries(metrics).map(([metric, metricReadable]) => (
          <tr key={metric}>
            <td>{ metricReadable }</td>
            {Object.entries(ratioMetrics).map(([key,value]) => (
              <td key={value[metric]}>{ value[metric] }</td>
              // <td key={value[metric]}>{ Intl.NumberFormat('en', { notation: 'compact' }).format(value[metric].toPrecision(4)) }</td>
            ))}
          </tr>
        ))}
</tbody>

Sometimes value[metric] can be null and so the line commented fails as I can't call toPrecision on something that is null. I therefore only want the commented line to render when value[metric] is not null and if it is null render the line above it instead. ie:

if not null:

<td key={value[metric]}>{ Intl.NumberFormat('en', { notation: 'compact' }).format(value[metric].toPrecision(4)) }</td>

if null:

<td key={value[metric]}>{ value[metric] }</td>

I tried the following but I don't think react likes the syntax because the loop already contains {}.

{Object.entries(ratioMetrics).map(([key,value]) => (
      {!value[metric] && <td key={value[metric]}> "" </td>}
      {value[metric] && <td key={value[metric]}>{ Intl.NumberFormat('en', { notation: 'compact' }).format(value[metric].toPrecision(4)) }</td>}
))}

So my question is how do I go about fixing this? Thank you.

Upvotes: 1

Views: 44

Answers (2)

Rizwan
Rizwan

Reputation: 441

You can use Nullish coalescing operator ??.

It returns the right-hand side of the operator if the left-hand side is null or undefined

For example.

const foo = null ?? 'default string';

So, you can do like this

{Object.entries(ratioMetrics).map(([key, value]) => (
  <td key={value[metric]}>
    {!value[metric] ??
      Intl.NumberFormat("en", { notation: "compact" }).format(
        value[metric].toPrecision(4)
      )}
  </td>
))}

Like this, you don't need a ternary operator, just ?? can do this

Complete code:

<tbody>
  {ratioMetrics &&
    Object.entries(metrics).map(([metric, metricReadable]) => (
      <tr key={metric}>
        <td>{metricReadable}</td>
        {Object.entries(ratioMetrics).map(([key, value]) => (
          <td key={value[metric]}>
            {!value[metric] ??
              Intl.NumberFormat("en", { notation: "compact" }).format(
                value[metric].toPrecision(4)
              )}
          </td>
        ))}
      </tr>
    ))}
</tbody>

Upvotes: 1

Prasanna Dubey
Prasanna Dubey

Reputation: 91

Please try like this

{Object.entries(ratioMetrics).map((key,value) => (!value[metric] ? <td key={value[metric]}> "" </td> : <td key={value[metric]}>{ Intl.NumberFormat('en', { notation: 'compact' }).format(value[metric].toPrecision(4)) }</td>)}

Upvotes: 2

Related Questions