skip to Main Content

I’m working on building a very basic news app using the New York Times’ ‘top stories’ API. The API is well documented and there are plenty of examples of how to get stared online. But I’m stuck with conditionally rendering an image. Some of the objects in the API do not contain image files. In those cases, I need to render a generic "no image available" .png file. I’m really new to React and APIs so still learning the basics.

My code is throwing this error: Uncaught TypeError: Cannot read properties of undefined (reading 'media-metadata').

I’m trying to conditionally render an image using JS Optional Chaining. This is what I have so far.

   <div className="card">
                
                  
                    {title}
                    <ImageFormat className={media} component="img" src={media[0]['media-metadata'][2]?.url ?
                    `${media[0]['media-metadata'][2].url}` : 'https://upload.wikimedia.org/wikipedia/commons/e/e0/Red_Exclamation_Dot.png'
                    }/>
                    {/* <img src={media[0]['media-metadata'][2].url} />  */}
                    <div className="facet">
                    {des_facet}
                    </div>
            </div>   

My logic is this: if the object contains the img file then it will render, if not, then render the png file.

As stated above, I’ve tried using JS optional chaining (which is a very new concept for me). The error is Uncaught Type Error: Cannot read properties of undefined (reading 'reading 'media-metadata')

3

Answers


  1. while using the && operator to check if each property is defined before accessing it. This way, if any of the properties are undefined, the code won’t throw an error and will instead skip over the image rendering.

    <div className="card">
      {title}
      {media && media[0] && media[0]['media-metadata'] && (
        <ImageFormat
          className={media}
          component="img"
          src={
            media[0]['media-metadata'][2]?.url
              ? `${media[0]['media-metadata'][2].url}`
              : 'https://upload.wikimedia.org/wikipedia/commons/e/e0/Red_Exclamation_Dot.png'
          }
        />
      )}
      <div className="facet">{des_facet}</div>
    </div>
    
    Login or Signup to reply.
  2. It looks like media[0] is undefined you need to optionally chain it with ?..

       <div className="card">
          {title}
          <ImageFormat className={media} component="img" src={media?.[0]?.['media-metadata']?.[2]?.url ? `${media[0]['media-metadata'][2].url}` : 'https://upload.wikimedia.org/wikipedia/commons/e/e0/Red_Exclamation_Dot.png'}/>
          <div className="facet">
            {des_facet}
          </div>
       </div> 
    
    Login or Signup to reply.
  3. If media is initialized as an Array.
    Use this. Instead of using ternary here as it makes us to repeat same conditional statement twice,use || (OR) operator. If previous value is falsy (i.e undefined, null, 0, "") it will move forward and pick next.

    src={media[0]?.['media-metadata']?.[2]?.url || "https://upload.wikimedia.org/wikipedia/commons/e/e0/Red_Exclamation_Dot.png"}
    

    If media can be undefined or null then use this.

    src={media?.[0]?.['media-metadata']?.[2]?.url || "https://upload.wikimedia.org/wikipedia/commons/e/e0/Red_Exclamation_Dot.png"}
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search