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

16,216

Solution 1

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

    // ...
  }
}

Solution 2

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.

Share:
16,216
Laurel Link
Author by

Laurel Link

Updated on June 07, 2022

Comments

  • Laurel Link
    Laurel Link almost 2 years

    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;