Axios for AJAX calls
In a previous lesson, we used the fetch() function in JavaScript to make AJAX calls (HTTP requests). But there is a popular library called Axios that can be easier to use than fetch().
In order to follow along with this activity, you'll have to use the JSON server package, and set it up work with a collection of 'users', like we did in this activity. So, you should have the user-data.json file.
Open a terminal and cd to the directory that has the user-data.json file in it. Then run this command to start the JSON server on port 8080:
npx json-server -w user-data.json -p 8080
Make sure the JSON server is up and running by visiting this URL in your browser: http://localhost:8080/users. The response should show you the entire collection of users.
You now have a 'mock' API (web service) that you can use to make AJAX calls to (aka HTTP requests).
Create a file named axios.html, and put the following starter code into it:
<!DOCTYPE html>
<html>
<head>
<title>Axios Tests</title>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script type="text/javascript">
window.addEventListener("load", () => {
// MAKE SURE THE JSON SERVER IS RUNNING BEFORE TRYING THESE SAMPLES
// npx json-server -w user-data.json
const baseURL = "http://localhost:8080/users/";
const errorHandler = (error) => console.log("ERROR!", error);
document.querySelector("[name=btn1]").addEventListener("click", () => {
alert("TODO: GET All Users");
});
document.querySelector("[name=btn2]").addEventListener("click", () => {
alert("TODO: GET All Users (async/await)");
});
document.querySelector("[name=btn3]").addEventListener("click", () => {
alert("TODO: GET User By ID");
});
document.querySelector("[name=btn4]").addEventListener("click", () => {
alert("TODO: POST new user");
});
document.querySelector("[name=btn5]").addEventListener("click", () => {
alert("TODO: PUT user");
});
document.querySelector("[name=btn6]").addEventListener("click", () => {
alert("TODO: DELETE user");
});
});
</script>
</head>
<body>
<h1>Using the Axios library for AJAX calls</h1>
<button name="btn1">Get All Users</button>
<button name="btn2">Get All Users (async/await)</button>
<button name="btn3">Get User By ID</button>
<button name="btn4">POST (Insert) User</button>
<button name="btn5">PUT (Update) User</button>
<button name="btn6">DELETE User</button>
</body>
Notice that there is a SCRIPT element that links to the Axios library. This gives use access to an 'axios' object that we can call methods on in order to make various types of HTTP requests (such as GET, POST, PUT, etc.). All of these methods return a Promise object, and as you know from a previous activity, we have two options for how we can deal with a Promise. One way is to use the then() and catch() methods of the Promise object that gets returned. The other is to use async and await.
For example, we could do something like this:
axios.get(/*URL GOES HERE*/).then(/*SUCCESS HANDLER FUNCTION GOES HERE*/).catch(/*ERROR HANDLER GOES HERE*/)
This would make a GET request to the URL that is passed in as the param to the get() method. The get() method returns a promise, so we can use method chaining to call then() and catch() on the promise.
Before moving on, note that I created a baseURL constant so that we don't have to repeat the URL that points to the JSON server. I also created a named function called errorHandler that we can use in each of the upcoming examples.
Replace the alert that says TODO: GET All Users with this code:
axios
.get(baseURL)
.then(response => {
console.log("SUCCESS", response)
const data = response.data;
console.log("DATA:", data);
})
.catch(errorHandler);
Notice the parameter that is passed into the success handler function. As you know, you get to choose names for your parameters, but I named it response because it will be an object that represents the HTTP response from the server.
Load the sample file in the browser, click on the first button to trigger the code, and then look in the console log. You should see that the response is an object that includes a status property (which is the HTTP status code of the response), and a headers property, which includes the HTTP headers that were sent in the response.
The response object will also include a data property, which represents the body of the HTTP response. By default, Axios assumes that the body of the response will be a JSON string, and it will automatically parse it into a JavaScript object for you.
Another way to deal with functions that return promises is to use the async and await keywords. Replace the alert that says TODO: GET All Users (async/await) with this code:
const getAllUsers = async() => {
try{
const response = await axios.get(baseURL);
const users = response.data;
console.log(users);
}catch(error){
errorHandler(error);
}
}
getAllUsers();
Run this code (click the second button) and check the console log for the 'users' data.
You can send an HTTP GET request for a specific user by appending the user's id to the URL, like so (replace the alert that says TODO: GET User By ID with this code):
const userId = 3;
axios
.get(baseURL + userId)
.then(response => console.log(response.data))
.catch(errorHandler);
When you run this code in the browser (and click the third button), you should see the console log that shows Anna Smith's information.
The following code sample sends an HTTP POST request, which will add a new user to the user-data.json file. Replace the alert that says TODO: POST new user with this code:
const newUser = {first_name: "Jen", last_name: "Lee", email: "jl@gmail.com"};
axios
.post(baseURL, newUser)
.then(response => {
console.log("POST status:", response.status)
console.log("DATA:", response.data)
})
.catch(errorHandler);
Note that we are calling the post() method on the axios object, which will result in an HTTP POST request. Also note that we are passing in the newUser object as the second param. Axios will automatically 'stringify' the user data before sending it in the request body.
If you run this code, you should see in the console log that the server responded with a status code of 201, which indicates that data was successfully 'posted' (aka 'inserted').
Also notice that the response body (the response.data property) is an object that represents the user that was just added by the server, AND that it includes the id that was assigned to the new user. The JSON server will assign ids for POST requests.
Now look inside the user-data.json file, and you should see that the JSON server has added the new user to it.
To update a user that is already on the server, we can make a PUT request by calling the put() method of the axios object. Replace the alert that says TODO: PUT user with this code:
const userToUpdate = {
id: 1,
first_name: "BOB",
last_name: "SCHWARTZ",
email: "rob23@gmail.com"
};
axios
.put(baseURL + userToUpdate.id, userToUpdate)
.then(response => console.log("PUT status:", response.status))
.catch(errorHandler);
Note that when making PUT requests, we must append the id (of the user) to the URL. The JSON server will use this id to know which user to replace.
After running this code in the browser, look in the console log and you should see that the response for the PUT request includes a status of 200, which indicates the server successfully handled the request.
Now look inside the user-data.json and you should see that the first user has been updated.
Finally, we'll finish off these AJAX calls that result in CRUD operations on the server by deleting a user. Replace the alert that says TODO: DELETE user with this code:
const idOfUserToDelete = 5;
axios
.delete(baseURL + idOfUserToDelete)
.then(response => console.log("DELETE status:", response.status))
.catch(errorHandler);
In this sample, we call the delete() method of the axios object (which results in an HTTP DELETE request). And we concatenated the id of the user to the URL, so that the server knows which user to delete.
If you run this code, you should see it returns a status of 200, which indicates the user was successfully deleted. But if you refresh the page, the request will result in an error because the use has already been deleted and no longer exists in the collection of users.
In the near future, we'll be using Axios to make components that send requests for CRUD operations from a front end application to a back end server.