0

Please I don't know the reason why I'm getting '"URL of undefined" when accessing data in an API call? Presently, I'm working with an API in a react project and I needed to access an image URL in the data, Every other data I'm accessing works perfectly except the image URL.

codeSaandbox

Here is my working code except for the Image URL.

import React, { Component } from "react";
import axios from "axios";

export default class Cat extends Component {
  state = {
    data: [],
    CatWeight: "",
    CatMetric: ""
  };

  componentDidMount() {
    this.fetchCountryData();
  }

  fetchCountryData = async () => {
    const url = "https://api.thecatapi.com/v1/breeds";
    try {
      const response = await axios.get(url);
      const data = await response.data;
      this.setState({
        data
      });

      const [CatWeight, CatMetric] = this.statistics();
      this.setState({
        CatWeight,
        CatMetric
      });
    } catch (error) {
      console.log(error);
    }
  };

  render() {
    return (
      <div>
        <h2>Cat Assignmaent</h2>
        {console.log(this.state.data)}
        {this.state.data.map((item, id) => {
          return (
            <div key={id}>
              {/* <img src={item.image.url} alt=""/> Please why is this giving url undefined ? */}

              <h2> {item.name}</h2>
              <h3> {item.origin}</h3>
              <h2>{item.temperament}</h2>
              <h2>{item.life_span} kg</h2>
              <p>{item.description}</p>
            </div>
          );
        })}
      </div>
    );
  }
}


0

4 Answers 4

1

simply because you are trying to access URL property at the moment your data does not exist yet. and as you know Javascript is Synchronous, you could fix it by using Optional chaining

              <img src={item?.image?.url} alt=""/> 

check this https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining

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

Comments

0

While the explanation in the answer of @Swarup is correct, I would rather use this:

render() {
  return (
    <div>
      <h2>Cat Assignmaent</h2>
      {this.state.data.map((item, id) => {
        return (
          <div key={id}>
            {
              item.image
                ? <img src={item.image.url} alt={item.name} />
                : 'No image, sorry'
            }

            <h2>{item.name}</h2>
            <h3>{item.origin}</h3>
            <h2>{item.temperament}</h2>
            <h2>{item.life_span} kg</h2>
            <p>{item.description}</p>
          </div>
        );
      })}
    </div>
  );
}

Comments

0

Seems like this is an issue with the API. Some records don't image key in them. To verify this, add following lines after receiving response.

      const filtered = data.filter(item => !item.image);
      console.log(filtered);

To avoid this you can add a check before displaying an image.

   {item?.image?.url && <><img src={item.image.url} alt=""/></> }

Comments

0

You are trying to access state data which is not exist yet, You must have initial state data that contains default URL for image, until you get image data from the API response, so by that you can avoid this problem,

and one thing i may suggest you need to have type safety for the response, so that you would know already what type of data you are going to get from the API response.

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.