0

I'm pretty new to ReactJS so this is my implementation of using Fetch inside of it.

class App extends React.Component {
  function postData(url, data) {
      // Default options are marked with *
      return fetch(url, {
        body: JSON.stringify(data), // must match 'Content-Type' header
        cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
        credentials: 'same-origin', // include, same-origin, *omit
        headers: {
          'user-agent': 'Mozilla/4.0 MDN Example',
          'content-type': 'application/json'
        },
        method: 'POST', // *GET, POST, PUT, DELETE, etc.
        mode: 'cors', // no-cors, cors, *same-origin
        redirect: 'follow', // manual, *follow, error
        referrer: 'no-referrer', // *client, no-referrer
      })
      .then(response => response.json()) // parses response to JSON
    }


  render() {
    const test_content = ["first", "second", "third"];

    const initial_data = {
      'id': 1,
      'model-name': 'Joke'
    };

    postData('/start-jokes/', initial_data)
      .then(data => console.log(data)
       ) // JSON from `response.json()` call
      .catch(error => console.error(error));


    const jokes_div = test_content.map((item, i) => (
      <div key={i} className="card col-md-7">
        <div className="card-body">
            {item}
        </div>
      </div>
    ));
    return <div className="container" id="jokes">{jokes_div}</div>;
  }
}
// ========================================

ReactDOM.render(
  <App />,
  document.getElementById('root')
);

This works ok and the console logs this response.

Object { status: "ok", jokes: Array[10], ref-id: 11 }

The jokes array has an id and text in an Object, the text would be used same as test_content to populate the items with it's own unique key id shown here

enter image description here

any pointers on how to now populate from there will be much appreciated.

2 Answers 2

1

Never call the api in render. If you want the data to be loaded when the page renders call the function in the componentDidMount ; else if you want to load on some other events or some input change call it in onChange event and as said no need to return the results you can setState the response.

class App extends React.Component {
    constructor(props) {
       super(props);
       this.state = { 
           data : [],
        }
     }
    componentDidMount(){
     this.postdata()
    }

    postdata(){
        var self = this;
            fetch(url, {
            body: JSON.stringify(data),
            cache: 'no-cache', 
            credentials: 'same-origin', 
            headers: {
            'user-agent': 'Mozilla/4.0 MDN Example',
            'content-type': 'application/json'
            },
            method: 'POST',
            mode: 'cors', 
            redirect: 'follow',
            referrer: 'no-referrer',
            })
            .then(response => response.json()).then((json) => {
              self.setState({ data : json.data }) // which ever the key hold the data 
            })
    }

    render(){
       return( 
            <div>
            {this.state.data.length == 0 && 
               <div> No options available.</div>
            }
            {this.state.data.length > 0 && 
              <div className="container" id="jokes">
                   {this.state.data.map(function(item,i){
                          return(
                                <div key={i} className="card col-md-7">
                                <div className="card-body">
                                {item}   // here you are getting object in item. Get the key from the object like item.name
                                </div>
                                </div>
                      )
                   })}
               </div>
            }
          </div>
         )
    }
}
Sign up to request clarification or add additional context in comments.

11 Comments

it throws this error SyntaxError: http://35.196.142.180/static/js/react-script.js: Unexpected token (7:23) 5 | data : [], 6 | } > 7 | componentDidMount(){ | ^ 8 | this.postdata() 9 | } 10 |
@SamuelM. please check now i have updated the code. Forgot to close the parenthesis of constructor
sorry to have to point out another bug SyntaxError: http://35.196.142.180/static/js/react-script.js: Unexpected token (34:17) 32 | render(){ 33 | return( > 34 | {this.state.data.length == 0 && | ^ 35 | <div> No options available.</div> 36 | } 37 | {this.state.data.length > 0 &&
@SamuelM. please check now i have updated the code. Just wrap the return in <div> tag
think it's almost working... it throws an error for a missing value ReferenceError: url is not defined
|
0

As you're asynchronous, you'll need to take the lifecycle into account:

  1. call postData in componentDidMount
  2. instead of .then(response => response.json()) set the result into the state, e.g. .then(response => this.setState({jokes: response.json()}))
  3. in render, instead of test_content, use (this.state.jokes || [])

In larger applications, I'd consider separating rendering and data management (i.e. do two components), but I hope you get one step further with the points above...

1 Comment

Tried it this way, got an interesting bug pastebin.com/AsDKHjw5 not sure if it's because of how I used setState. The code now looks like this pastebin.com/ZBv9EXit

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.