1

I am trying to put together a search for Hacker News. I got it to work in the console, by just doing a console.log(res.data.hits). If you type "apple" into the search you'll see a bunch of comments pop up in the console with the word apple in them, so that part works. I am wondering how to get this to display in the DOM though. I have been trying to add the data into an array in State but it doesn't seem to like it. It's very strange because I executed another API call the exact same way in another project and that one worked and it looks like the data structure for this API is the same. Below I will recount the different blocks of code. The first is a different project where I made a call to the Random User API in the exact same way I tried to make a call to the HN API.

Random User API: (works)

  componentDidMount = () => {
    axios.get('https://randomuser.me/api?results=25')
    .then(res => {
  this.setState({
    data: res.data.results
        })
    })

}

HN API: (works when I type console.log(res.data.hits) but not when I try to add that array to State.)

getbyComment = (e) => {
  e.preventDefault()
    axios.get(`http://hn.algolia.com/api/v1/search?query=${this.state.term}&tags=comment`)
    .then(res => {
    console.log(res.data.hits)})

}

Doesn't work:

getbyComment = (e) => {
  e.preventDefault()
    axios.get(`http://hn.algolia.com/api/v1/search?query=${this.state.term}&tags=comment`)
    .then(res => 
       { this.setState({data: res.data.hits}) 
    } 
    )
}

Hopefully now you can see this could cause confusion for somebody new to React. My best guess is that there is something in the data structure of the HN API that I'm not catching. When I console log it the res.data.hits seems to be an array in [{...},{...}] form, as was the Random User one. Below is the error message I get when I try to retrieve from the HN API and add it to State.

Error: Objects are not valid as a React child (found: object with keys {created_at, title, url, author, points, story_text, comment_text, num_comments, story_id, story_title, story_url, parent_id, created_at_i, relevancy_score, _tags, objectID, _highlightResult}). If you meant to render a collection of children, use an array instead.
    in div (at App.js:42)
    in App (at src/index.js:9)
    in StrictMode (at src/index.js:8)

And with that, below I leave the code for the rest of the Document in case that is helpful with answering the question. If more info is needed please let me know.

    import React from 'react';
    import './App.css';
    import axios from 'axios';

    class App extends React.Component {
      state = {
        term: '',
        option: 'story',
        data: []
      }

      handleChange = (event) => {
        const query = event.target.value
        this.setState({ term: query })
        // console.log(this.state)
      }


    //res.data.hits
    getbyComment = (e) => {
      e.preventDefault()
        axios.get(`http://hn.algolia.com/api/v1/search?query=${this.state.term}&tags=comment`)
        .then(res => 
           { this.setState({data: res.data.hits}) 
        })

    }

      render(){
        return(
          <div>
            <form onSubmit={this.getbyComment}>
            <input placeholder="search for" onChange={this.handleChange} value={this.state.term} />
            <input type="submit" value="Submit" />

            </form>
            {this.state.data}
          </div>
        )
        }
    }

    export default App;
Lennholm
  • 7,205
  • 1
  • 21
  • 30
Alex
  • 29
  • 4
  • 1
    Does this answer your question? [Objects are not valid as a React child. If you meant to render a collection of children, use an array instead](https://stackoverflow.com/questions/52428879/objects-are-not-valid-as-a-react-child-if-you-meant-to-render-a-collection-of-c) – Shane Creedon Mar 29 '20 at 18:39

1 Answers1

0

You seem to have concluded that your hits array holds objects ("[{...},{...}]"). React doesn't support rendering of generic objects, you have to parse it into something React can render, such as a React element or a string.

To parse the object into a string, you can simply use JSON.stringify():

{ this.state.data.map(item => JSON.stringify(item)) }

You probably want to do something more elaborate with the data though but the point is you need to know the structure of the data and write your own parser for it.

Lennholm
  • 7,205
  • 1
  • 21
  • 30