Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to fix "TypeError: items.map is not a function" when working with React and APIs?

I'm new to React and am trying to pull in some information from an API, but keep getting this error when using the .map function to pass the retrieved data into an array:

TypeError: items.map is not a function.

I'm not too familiar with JavaScript, so I don't fully understand what's going on here. I've included my code:

import React, { Component } from "react";
import "./App.css";

class App extends Component {
  constructor() {
    super();
    this.state = {
      items: [],
      isLoaded: true
    };
  }

  componentDidMount() {
    fetch("http://www.colr.org/json/colors/random/7")
      .then(res => res.json())
      .then(json => {
        this.setState({
          isLoaded: true,
          items: json
        });
      });
  }

  render() {
    var { items, isLoaded } = this.state;
    var itemInfo = items.map(item => (
      <div key={item.colors.id}>Hex:{item.colors.hex}</div>
    ));

    if (!isLoaded) {
      return <div>{itemInfo}</div>;
    } else {
      return <div className="App">{itemInfo}</div>;
    }
  }
}

export default App;
like image 457
Laurel Link Avatar asked Oct 18 '25 06:10

Laurel Link


2 Answers

Since the items array in state is initially an empty array, you get this error when you change items to something that is not an array.

Looking at the response from the API in your question, you will get an object from your JSON after you parse it. The array you want to use in the response is under the colors property, and each element in this array has id and hex properties.

class App extends Component {
  // ...

  componentDidMount() {
    fetch("http://www.colr.org/json/colors/random/7")
      .then(res => res.json())
      .then(res => {
        this.setState({
          isLoaded: true,
          items: res.colors
        });
      });
  }

  render() {
    var { items, isLoaded } = this.state;
    var itemInfo = items.map(item => <div key={item.id}>Hex:{item.hex}</div>);

    // ...
  }
}
like image 87
Tholle Avatar answered Oct 20 '25 19:10

Tholle


Since you do not specify types for anything and it is not really clear (not even for a human-reader) that items is an Array, you should explicitly tell TypeScript to use it as an array.

You use Type Assertion for that purpose. Should be something like:

(items as Array<YourArrayElementType>).map(/* .. */);

However, as a good practice you should always explicitly specify the type of anything you declare. In this way anything within you codebase will be statically typed. For anything coming from the outside (such as API requests) you should cast the information to interfaces you define.

like image 29
Victor Avatar answered Oct 20 '25 18:10

Victor



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!