0

So really new to React here, and I want to make a simple search box, where the user submits a "question" and the JSON returns the values of "results".

I have a JSON with the structure of two Objects:

{
  "request": {
    "date_from": "", 
    "date_to": "", 
    "question": "User question here", 
    "section": null
  }, 
  "results": {
    "docs": [
      {
      "title": " "
      "section": " "

etc..
      ...

The request goes through and I get a response, only thing I can't find is taking the results from it and displaying them on the front end.

import React, { Component } from "react";

class Search extends Component {
  state = {
    searchValue: "",
    searchSection: "",
    results: [],
    // section: []
  };

  handleOnChange = event => {
    this.setState({ searchValue: event.target.value });
  };

  handleSearch = () => {
    this.makeApiCall(this.state.searchValue);
  };

  makeApiCall() {
    fetch("http://myapi.com", {
      method: 'POST',
      headers: {
          'Accept': 'application/json',
          'Content-Type': 'application/json'
      },
      body: JSON.stringify({
          question: (this.state.searchValue),
          section: (this.state.searchSection),
      })
  })

      .then((response) => response.json())
      .then((responseData) => {
          console.log(
            "POST Response",
            "Response Body -> " + JSON.stringify(responseData)
          )
      })
      .then(results => this.setState({results: results.value}))
  };

  render() {
    return (
      <div id="main" className="py-16">
        <label className="block uppercase tracking-wide text-gray-700 text-xs font-bold mb-2" for="grid-first-name">
            Ask a question
        </label>
        <input
          name="text"
          type="text"
          placeholder=""
          onChange={event => this.handleOnChange(event)}
          value={this.state.searchValue}
          className="shadow-sm appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
        />
        <button onClick={this.handleSearch} className="cursor-pointer mt-5 bg-white hover:bg-gray-100 text-gray-800 font-semibold py-2 px-4 border border-gray-400 rounded-full shadow">Search</button>

      //THIS IS WHERE I'M STUCK NOW
        {this.state.results ? (
          <div id="meals-container">
            {this.state.results.map((result) => (
              <div className="result">
                <h2>{result.title}</h2>
                <p>{result.sentences}</p>
              </div>
            ))}

          </div>
        ) : (
          <p>Can't find results for your question</p>
        )}
      </div>
    );
  }
}

export default Search;

I get

Unhandled Rejection (TypeError): results is undefined
1
  • 1
    You are not returning the result here: .then((responseData) => { so in the next .then result is undefined. Commented Apr 10, 2020 at 19:46

1 Answer 1

1

Inside the function where responseData is received, you are not returning anything from the function, thus 'undefined' is being set into state. To fix this you can put a return statement after your console.log:

.then((responseData) => {
          console.log(
            "POST Response",
            "Response Body -> " + JSON.stringify(responseData)
          )
          return responseData
      })
      .then(results => this.setState({results: results.value}))
Sign up to request clarification or add additional context in comments.

2 Comments

Interesting! Thanks for that. I still don't get results showed to the user though.. I always get the <p>Can't find results for your question</p>despite getting a response from the JSON. Something I don't get is wrong after {this.state.results ? (
Anyone? @rob-brander

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.