2

I am trying to render data from http://www.colr.org/json/color/random.

I use axios to GET data from API. When I receive data, i cannot render it trhough the map (because it is obviously an array inside object) so it throws error: TypeError: this.props.colors.map is not a function. Do I need to use JSON.parse() or what can I do ?

//App.js

import React, { Component } from 'react';
import logo from './logo.svg';
import Color from './components/Color';
import './App.css';
import axios from 'axios';

class App extends Component {
  state = {
    colors: []
  };

componentDidMount() {
  axios.get('http://www.colr.org/json/colors/random/2')
  .then(res => this.setState({
    colors: res.data }))
}

  render() {
    console.log(this.state.colors);
    return (
      <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <Color 
            colors={this.state.colors}
          />
        </header>
      </div>
    );
  }
}
export default App;

//Color component:

import React, { Component } from 'react';


 class Color extends Component {

  render() {
       return this.props.colors.map((color) => (
        <h1
          key={color.id}
        >
          Color{color.id}: {color.hex}
        </h1>
      ))
  }
}

export default Color;
2
  • 1
    What is printed in console for this.state.colors ? Isn't this.state.colors.colors.map working? Commented Mar 30, 2019 at 13:43
  • how does the response object look like Commented Mar 30, 2019 at 13:44

2 Answers 2

1

You're almost there. The data coming back from Colr.org isn't in the format you expected. Use console.log(this.state) to see what was retrieved. You mapped over the root data object returned. However, the colors you want are nested in the data.data.colors array.

Also, take a look at the Async/Await pattern to make sure your JSON data is back from the API before you try to render it.

This should work:

import React, { Component } from "react";
import logo from "./logo.svg";
import Color from "./components/Color";
import "./App.css";
import axios from "axios";

class App extends Component {
  state = {
    colors: []
  };

  async componentDidMount() {
    const apiResults = await axios.get("http://www.colr.org/json/colors/random/2");
    this.setState({
      colors: apiResults.data.colors
    });
  }

  render() {
    console.log(this.state);
    return (
      <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <Color colors={this.state.colors} />
        </header>
      </div>
    );
  }
}
export default App;
Sign up to request clarification or add additional context in comments.

3 Comments

Yes, it worked. Wen I get response form API, I get an object with arrays. Does "data" refer to that object, and then what does data.data refers to? to "data" variable ?
That was poor variable naming on my part. I set data equal to the response from the API. It turns out, the API returned a colors object, which contained a data object, which contained a colors array, which contained your results. Basically, your data was nested in the API results. We had to dig down to the data you wanted (the colors array) using dot notation.
I just edited my response with better variable naming.
0

you can use JSON.stringify it will convert it into string or you can use util library it works for me i worked on the same issue last day

1 Comment

a bit of explaining on en example would be helpful.

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.