Skip to content
Advertisement

In React.js, how can you check if prop exists before mapping it?

I have an app getting data from a websocket connection that is really fast and is causing errors with the data in state. I’m. passing an array of just 15 items into a child component, however it is an array of tuples. When I map it, I need to deconstruct each tuple to render each item. However, every 30 seconds or so the component is receiving data that is corrupted and causing the erorr:

TypeError: Cannot read properties of undefined (reading ‘0’)

At the line item[0] because item is undefined. I have tried several types of logic to make this mapping conditional based on the contents of the property. Below is Array.isArray(topAsks[0]), i have also tried topAsks.length > 2. However it is still going past and trying to map the undefined array.

Is there a better way to do this? That is being able to check that it is not undefined before mapping?

Also above commented out I was thinking of doing this with a for loop and then mapping each single array (bypassing the need to access an inner array), seems weird, but perhaps that is an effective way of doing this?

import React from 'react';


function Orderbook({topAsks, topBids}) {
  // let askQuant = [];
  // let askPrice = [];
  // let rBids = [];
  // for(let i = 0; i <= 15; i++) {
  //   for(let j = 0; j < 1; j++) {
  //     rAsks.push(topAsks[i][j])
  //   }
  // }
  // console.log(topAsks)
  return (
    <div className="ob-cont">
      <div className="ob-title-cont">
        <div className="ob-title-marketsize"></div>
        <div className="ob-title-price"></div>
      </div>
       <div className="ob-sell-cont">
       {Array.isArray(topAsks[0]) 
       ?
         topAsks.map((item, index) => (
           <div key={index} className="ob-sell-tile"> 
            <div className="ob-sell-tile">{item[0]} </div>
            <div className="ob-sell-tile">{item[1]} </div>
           </div>
          ))
          : <div className="ob-sell-tile"> </div> }
       </div>

    </div>
  );
}

export default Orderbook;

Advertisement

Answer

The error you’re facing is about reading item[0] when item is undefined.

A simple solution could be filter the truthy values inside topAsks

For instance do something like:

topAsks.filter(Boolean).map((item, index) => (
           <div key={index} className="ob-sell-tile"> 
            <div className="ob-sell-tile">{item[0]} </div>
            <div className="ob-sell-tile">{item[1]} </div>
           </div>
          ))

Otherwise you could filter the elements which are array with at least 2 elements:

topAsks.filter(a => Array.isArray(a) && a.length >= 2)

Once again you could check with the optional chaining when item[0] or item[1] exists, if they don’t you could provide a default fallback case with the nullish coalescing operator :

 topAsks.map((item, index) => (
           <div key={index} className="ob-sell-tile"> 
            <div className="ob-sell-tile">{item?.[0] ?? 'default item[0]'} </div>
            <div className="ob-sell-tile">{item?.[1] ?? 'default item[1]'} </div>
           </div>
          ))
Advertisement