Pass a JSON as a Prop between two React.js Components

I have been trying to pass a JSON object obtained by hitting a REST api after a form submit+ user input. I am able to pass the data obtained to another Component in the same file (this second component is trying to loop over the JSON and render it as a HTML table) but when I try to apply the map function over it, it fails. Thanks in advance. Please find the error and the code below:

ERROR:

TypeError: this.props.rocks.map is not a function

Code:

import React, {Component} from 'react'
import './App.css'
import axios from 'axios'

class FooBar extends Component {
    constructor(props) {
        super(props);
    }

     render() {
        console.log(this.props.rocks);
        this.props.rocks.map(function (i, j) {
            console.log(i)
        })
        return <h1>HEY</h1>
    }
}

class App extends Component {
    weekDays = ["Sunday", "Monday"]
    meals = ["BreakFast"]

    constructor(props) {
        super(props);
        this.state = {
            recipeList: [],
            selectedRecipes: [],
            fetchedJson: {},
            fooBar: false
        }
  }

  renderTableHeader() {
    return this.meals.map((key, mealIndex) => {
      return <th key={mealIndex}>{key.toUpperCase()}</th>
    })
  }

  componentDidMount() {
    axios.get(`http://localhost:8080/recipe/all`)
        .then(res => {
          this.setState({ recipeList: res.data });
          // todo: line here will work before lines outside the axios.get
        })
  }

  handleChange(event){
    event.preventDefault();
    console.log(event.target.value);
    this.state.selectedRecipes.push(event.target.value);
  }

  renderTableData() {
    return this.weekDays.map(function (day, dayIndex) {
      return (
          <tr key={dayIndex}>
            <td>{day}</td>
              {
                this.meals.map(function (meal, mealIndex) {
                  return (
                      <td key={mealIndex}>
                        {
                          <select key={meal} onChange={this.handleChange.bind(this)}>
                              <option key="blankOption">Choose Item to Cook</option>
                            {
                              this.state.recipeList.map(function (recipe, recipeIndex) {
                                return <option key={recipeIndex}>{recipe}</option>
                              })
                            }
                          </select>
                        }
                      </td>
                  );
                }.bind(this))
              }
          </tr>
      );
    }.bind(this)) // todo: how does bind work
  }

  handleSubmit(event){
      event.preventDefault();
      console.log(this.state.recipeList);
      let url = 'http://localhost:8080/ingredients/?recipes=' + this.state.selectedRecipes.join(',')
    axios.get(url)
        .then(res => {
          console.log(res.data);
          this.setState({
              fetchedJson: res.data,
              fooBar: true
          })
        })
      this.setState({
          selectedRecipes: []
      })
  }

  render() {
      return (
          <div>
              <form onSubmit={this.handleSubmit.bind(this)}>
                  <table id='students' border="1">
                      <tbody>
                      <tr>
                          <td><b>WeekDay</b></td>
                          {
                              this.renderTableHeader()
                          }
                      </tr>
                      {this.renderTableData()}
                      </tbody>
                  </table>
                  <input type="submit" value="Submit"/>

              </form>
              {this.state.fooBar && <FooBar rocks={this.state.fetchedJson}/>}
          </div>
    )
  }
}
export default App

Upvotes: 0

Views: 3007

Answers (2)

PrakashT
PrakashT

Reputation: 901

Error is very clear. Map function works for only array.I think you passed props as object type instead of array.That's why it's giving error.

Step 1: Change line to fetchedJson: [] instead of fetchedJson: {},

Step 2: Also check res.data should be an array type not an object.('http://localhost:8080/ingredients/?recipes=')

Upvotes: 1

Gunnabathula Mounika
Gunnabathula Mounika

Reputation: 11

We can apply map function to array only. But you declared fetchedJson as object in App Component. First change object {} to array []. Next check this.props.rocks is giving array with data or not. Then you can apply map function.

Upvotes: 1

Related Questions