btholt/complete-intro-to-react-v5

How to handle API Errors with Detail Component

cujojp opened this issue · 2 comments

I just started the course and want to say thank you so much, I've really been able to pick up the basics pretty quick.

However, within the API, some of the animals return as 404's Example. I've been doing some digging around within the course, and you go into detail about Error Boundaries. However it seems ErrorBoundaries run on render(?) and it doesn't seem to catch when on componentDidMount(). I tried catching an error using the Promise provided from the @FrontendMasters pet.animal() method, but even that doesn't seem to work with the Error Boundary.

   componentDidMount() {
    pet
      .animal(this.props.id)
      .then(({ animal }) => {
        this.setState({
          name: animal.name,
          animal: animal.type,
          location: `${animal.contact.address.city}, 
          ${animal.contact.address.state}`,
          description: animal.description,
          media: animal.photos,
          breed: animal.breeds.primary,
          loading: false
        });
      })
      .catch(err => {
        this.setState({
          error: err
        });
      });
  }

Am I just doing this wrong? Or did was it not mentioned how to handle API 404's bad requests etc.

I encountered this too, and solved it by adding a new state property error that is set when an error is caught in the promise of the API which will be rethrown in the render method of the component (courtesy of some stackoverflow answer)

My component looks like this then

class Details extends React.Component {
  // Adding error state
  state = { loading: true, error: null };

  componentDidMount() {
    const { id } = this.props;
    pet
      .animal(+id)
      .then((data) => {
        const { animal } = data;
        if (animal === undefined) {
          // The API returns a data object with error details, without the animal, so catch it like this
          return Promise.reject(new Error('Unable to load animal details'));
        }
        this.setState({...});
        return Promise.resolve();
      })
      .catch((error) => {
        // Catching promise errors, setting state
        this.setState({ error });
      });
  }

  render() {
    const { loading, error } = this.state;
    // Check for error and rethrow
    if (error) {
      throw error;
    }
    if (loading) {
      return <h1>loading ...</h1>;
    }
    return (
      <div className="details">...</div>
    );
  }
}

I have the same doubt, in my case none of the code mentioned here and in the lecture video I got, not working. Here is the code I've written,...

import React from "react";
import pet from "@frontendmasters/pet";

class Details extends React.Component {
constructor(props) {
super(props);

this.state = {
  loading: true,
};

}

componentDidMount() {
pet.animal(this.props.id).then(({ animal }) => {
this.setState({
name: animal.name,
animal: animal.type,
location: ${animal.contact.address.city}, ${animal.contact.address.state},
description: animal.description,
media: animal.photos,
breed: animal.breeds.primary,
loading: false,
});
}, console.error);
}

render() {
if (this.state.loading) {
return

loading ...

;
}

const { animal, breed, location, description, name } = this.state;

return (
  <div className="details">
    <div>
      <h1>{name}</h1>
      <h2>{`${animal}- ${breed}- ${location}`}</h2>
      <button>Adopt {name}</button>
      <p>{description}</p>
    </div>
  </div>
);

}
}

export default Details;

this code is not shoing the details of the pet. Plz help me out.
Thank you.