0

I'm relatively new to ReactJS and still kind of getting to grips with it. I'm not by trade a front end developer so the below issue I'm having may be common knowledge amongst fellow React developers, but I can't find any other questions directly answering the issue I have here.

I have an API which displays the following category which are pulled from a database:

[{
    "category_id": 85,
    "name": "STARTERS",
    "description": "Served with salad & mint sauce",
    "priority": 1
}, {
    "category_id": 86,
    "name": "TANDOORI DISHES",
    "description": "Tandoori dishes are individually marinated in tandoori spices, herbs & yoghurt sauce & cooked in charcoal oven emerging crisp, fragrant & golden red. Served with salad & mint sauce",
    "priority": 2
}, {
    "category_id": 87,
    "name": "TANDOORI MASALA",
    "description": "Special Tandoori Masala",
    "priority": 3
}]

I'm trying to make a call to this API via a ReactJS project:

import React, { Component } from 'react';

class Api extends React.Component {
constructor(props) {
    super(props);
    this.state = {
      error: null,
      isLoaded: false,
      items: []
    };
  }

  componentDidMount() {
    fetch("https://my-api.com/category")
      .then(res => res.json())
      .then(
        (result) => {
          this.setState({
            isLoaded: true,
            items: result.items
          });
        },
        // Note: it's important to handle errors here
        // instead of a catch() block so that we don't swallow
        // exceptions from actual bugs in components.
        (error) => {
          this.setState({
            isLoaded: true,
            error
          });
        }
      )
  }

  render() {
    const { error, isLoaded, items } = this.state;
    if (error) {
      return <div>Error: {error.message}</div>;
    } else if (!isLoaded) {
      return <div>Loading...</div>;
    } else {
      return (
        <ul>
          {items.map(item => (
            <li key={item.category_id}>
              {item.name} {item.description}
            </li>
          ))}
        </ul>
      );
    }
  }
}

export default Api;

The error I'm getting is as follows:

Unhandled Rejection (TypeError): Cannot read property 'map' of undefined

and then it points to the following line from above in the render method:

{item.name} {item.description}

Can anybody point out where I'm going wrong here?

Thanks

4
  • Are you sure items actually exists and has a valid value? The error indicates that items is undefined. I can see two possible problems, the first one is that the asynchronous call to the API is not returning the items object in time for the render, and the second one is that the call is not working. Commented Feb 20, 2019 at 12:43
  • Try to move your componentDidMount code to the other lifecycle method componentWillMount, does it work? Commented Feb 20, 2019 at 12:43
  • It might be that result is the array of items, and not result.items. You could try this.setState({ isLoaded: true, items: result }); Commented Feb 20, 2019 at 12:46
  • have you tried to write this.state.items.map(.. Commented Feb 20, 2019 at 12:47

2 Answers 2

1

Try to change items: result.items to just items.result in

(result) => {
  this.setState({
    isLoaded: true,
    items: result.items
  });
},

mean to say

it should be like

(result) => {
  this.setState({
    isLoaded: true,
    items: result
  });
},
Sign up to request clarification or add additional context in comments.

Comments

0

the fetch in componentDidMount is an async call and you are not waiting for the response to completely get resolved.

async componentDidMount() {
  const response = await fetch("https://my-api.com/category");
  const json = await response.json();
   this.setState({ items: json });
}

1 Comment

async/await is not needed. OP's way of handling the promise returned from fetch works as well.

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.