Send Data to the Server With axios

crrojas88

Rodrigo Rojas

Posted on June 2, 2021

Send Data to the Server With axios

You must be a glutton for punishment if you're here following my post on GET requests with axios.

axios npm logo

Love you axios

As long as I have you here, let's recap on what we covered in the last post:

  • We created a JSON server to store our contacts.
  • Installed and imported axios to our app
  • Made an HTTP GET request using useEffect() and axios.get()
import React, { useState, useEffect } from 'react';
import axios from 'axios';

const App = () => {

  // our state hooks
  const [ people, setPeople ] = useState([])
 // our new state hooks that will store our newName and newNumber field inputs.
  const [ newName, setNewName ] = useState('')
  const [ newNumber, setNewNumber ] = useState('')

  // our axios GET request
  const hook = () => {
    axios.get('http://localhost:3001/people')
    .then(response => {
      setPeople(response.data)
    })
  }

  // the useEffect function takes in 2 parameters, a function, and the number of times we want it to run.
  useEffect(hook, [])

//...
Enter fullscreen mode Exit fullscreen mode
How our app looks so far

In order to create a new resource for storing a contact, we're going to make an HTTP POST request to the people URL according to RESTful conventions. The data for the new contact will be sent in the body of the request.

const addContact = (e) => {
  e.preventDefault()

  const nameObj = {
    name: newName,
    number: newNumber
  }

  axios.post('http://localhost3001/people', nameObj)
  .then(response => {
   setPeople(people.concat(response.data))
   setNewName('')
   setNewNumber('')
 })
}
Enter fullscreen mode Exit fullscreen mode

The new contact returned by the backend server
is added to the list of contacts in our app's state by using the setPeople() function and then resetting the newName & newNumber creation form.

In this case, since the data sent in the POST request is a JavaScript object, axios automatically knows to set the appropriate application/json value for the Content-Type header. How cool is that? No more typing up those pesky headers.

Take note that the concat() method is not changing the original state, but instead making a new copy of the list.

import React, { useState, useEffect } from 'react';
import axios from 'axios';

const App = () => {

  // our state hooks
  const [ people, setPeople ] = useState([])
// our new state hooks that will store our newName and newNumber field inputs.
  const [ newName, setNewName ] = useState('')
  const [ newNumber, setNewNumber ] = useState('')

  const hook = () => {
    axios.get('http://localhost:3001/people')
    .then(response => {
      setPeople(response.data)
    })
  }
  useEffect(hook, [])

  const addContact = (e) => {
  e.preventDefault()

  const nameObj = {
    name: newName,
    number: newNumber
  }

  axios.post('http://localhost3001/people', nameObj)
  .then(response => {
   setPeople(people.concat(response.data))
   setNewName('')
   setNewNumber('')
  })
 }

//...
Enter fullscreen mode Exit fullscreen mode
State of our app so far...

Let's add some functionality to edit existing numbers if a contact name already exists.

const handleSubmit = (e) => {
    e.preventDefault()

    const exists = people.find(person => person.name === newName)

    if(exists) {
      const person = people.find(p => p.name === newName)
      const confirmChange = window.confirm(`${newName} already exists. Replace old number with a new one?`)
      if(confirmChange) {
      const id = person.id
      const updatedPerson = {...person, number: newNumber}
      const url = `http://localhost:3001/people/${id}`

      axios
      .put(url, updatedPerson)
      .then(response => {
      setPeople(people.map(p => p.id !== id ? p : response.data))
      })
      } else {
        setPeople(people)
      }
    } else {
      addContact(e)
    } 
    setNewName('')
    setNewNumber('')
  }
Enter fullscreen mode Exit fullscreen mode

Every line of code in the function body contains important details. Since we're using one single submit button, we're going to handle the logic in the handleSubmit function.

  • exists finds if the newName field matches a name inside the people array.
  • confirmChange sends a confirmation window to replace an existing contact.
  • If confirmed, the if statement block creates an updatedPerson object by using the spread operator and adding the new number. If not, then setPeople is run with the original array.
  • In that same if block, our axios PUT request is called to the backend where it will replace the old object.
  • The map method inside our setPeople function creates a new array by mapping every item from the old array into an item in the new array. In our example, the new array is created conditionally so that if p.id !== id is true, we simply copy the item from the old array into the new array. If false, then the note object returned by the server is added to the array instead.
  • Outside of our nested if statement, if the name does not exist, then the addContact function is called.

And that's it! We've now successfully made a POST and PUT HTTP request with axios. Our code is looking a little bloated now so let's see if we can clean it up a little by creating a separate module that will handle backend communication in another blog post.

Resources

💖 💪 🙅 🚩
crrojas88
Rodrigo Rojas

Posted on June 2, 2021

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related