-1

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')

1
  • Tangential, but why not check for media presence before rendering? All you really need to do is determine the URL, which can be a local const. It'll make the JSX much cleaner. Commented Feb 17, 2023 at 17:39

3 Answers 3

0

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>
Sign up to request clarification or add additional context in comments.

Comments

0

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> 

Comments

0

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"}

Comments

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.