javascriptreactjshttprequestfetch-api

How to send a POST request with fetch?


I am able to fetch a GET request from the server, but unable to POST a request dynamically. I am taking an input value, but it's showing the error below:

Error: SyntaxError: "JSON.parse: unexpected character at line 1 column 1 of the JSON data"

const url = 'http://some domain/api/tweets';
const input = {tweet: {body:  ''}};
 
class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      error: null,
      isLoaded: false,
      data: [],
      value: ''
    }
    this.onSubmit = this.handleSubmit.bind(this);
    this.handleChange = this.handleChange.bind(this);
  }
  
  handleChange(e) {
    this.setState({value: e.target.value});
  }

  componentDidMount() {
    fetch('http://some domain/api/tweets')
      .then(res => res.json())
      .then(
        (result) => {
          this.setState({
            isLoaded: true,
            data: result.data
          });
        },
        (error) => {
          this.setState({
            isLoaded: true,
            error
          });
        }
      );
  }

  handleSubmit(e) {
    e.preventDefault();
    fetch(url, {
      method: 'POST',  
      body: JSON.stringify(this.state.value),  
      headers: {
        'Content-Type': 'application/json'
      }
    }).then(res => res.json())
    .then(response => console.log('Success:', JSON.stringify(response)))
    .catch(error => console.error('Error:', error));
  }

  render() {
    const { error, isLoaded, data } = this.state;
    if (error) {
      return <div>Error: {error.message}</div>;
    } else if (!isLoaded) {
      return <div>Loading...</div>;
    } else {
      return (
        <div className='list-type5'>
          <form onSubmit={this.onSubmit}>
            <input type='text' placeholder='Body' value={this.state.value} onChange={this.handleChange} />
            <input type="submit"  />
          </form>
          <ol>
            {data.map(i => (
              <div key={i.id}>
                <li>
                  <a> <b> ID:</b>  {i.id} | <b> Body:</b> {i.body} | <b> Views:</b> {i.views}   </a>
                </li>
              </div>
            ))}
          </ol>
        </div>
      );
    }
  }
}

export default App;

Solution

  • I just changed it to remove const input = {tweet: {body: ''}}; from the top and wrote it into the handleSubmit function instead as below:

    handleSubmit(e) {
      e.preventDefault();
      const input = {tweet: {body:  this.state.value}};
      fetch(url, {
        method: 'POST',  
        body: JSON.stringify(input),  
        headers: {
          'Content-Type': 'application/json'
        }
      }).then(res => res.json())
      .then(response => console.log('Success:', JSON.stringify(response)))
      .catch(error => console.error('Error:', error));
    }