The Fetch API is the modern version of the XMLHttpRequest that is used to fetch resources or to make A(Asynchronous)JAX call. The concept of the Fetch API is not too different from XHR, except that it provides more features and it is really flexible to use.
To fully grasp Fetch API, you might want to understand the older way of doing things: AJAX (Asynchronous JavaScript and XML) and Using The XMLHttpRequest API and ES6 Promises in JavaScript
The Promises guide is compulsory as Fetch returns promises, so, let's get started...
Fetch Usage
The fetch() method takes one argument, and that is the location of the resource you want to fetch. As I said before, it returns a Promise and that resolves to the Response of the request (which can be success or error).
Once a Response is retrieved, there are a number of methods available to define what the body content is and how it should be handled.
Simple Fetch Syntax
fetch('text.txt')
.then(function(response){
return response.text();
})
.then(function(data) {
console.log(data)
});
Here we are fetching a text file on our server, and printing it to the console. The simplest use of fetch() takes one argument — the path to the resource you want to fetch — and returns a promise containing the response (a Response object).
The response is just an HTTP response, not the actual TEXT, so, to extract the text body content from the response, we use the text method defined on the Body mixin, which is implemented by both the Request and Response objects. If it is a JSON, you use a JSON method.
Let's see a simple example:
We would start working with plain text, and we would use fetch to fetch the text asynchronously when a button is clicked.
I’ll be using the halfmoon CSS framework styling for this, so, in the HTML, add the following:
Note: You can use whatever CSS framework you want or you can simply use your CSS styles, this is just for illustration purposes.
<body>
<div class="content-wrapper text-center" id="container">
<div class="content-wrapper text-center">
<div class="container-fluid">
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card bg-light">
<div class="card-body">
<h2 class="card-header">Fetch API</h2>
</div>
<div id="form-container" class="container-fluid">
<div class="row justify-content-lg-start">
<!-- Submit Button -->
<div class="col-6 col-sm-5 col-md-4 col-lg-3 m-auto">
<input class="btn mt-10" id="load-text" type="submit" value="Load Plain Text">
</div>
<!-- Text would be added here-->
<div id="text"></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
<script src="js/main.js"></script>
The above is just the body element, so, you might want to add the necessary stuff in your HTML head tag, also, create a js folder, and create a main.js file. Lastly, create a folder name – “data”, and inside it create a file text.txt and add whatever you want in there, I added the following:
Fetching This text data using the Fetch API, isn't this awesome.
This is how the HTML structure looks like:
To start with, we add an event listener to the button, we then use the fetch method like so:
// The Fetch API
// Create Event Listener For the Load Plain Text Button
document.getElementById('load-text').addEventListener('click', function (e){
// Once the click event occur, we fetch the resource, and do some magic ;)
fetch('data/text.txt')
.then(function(response){
return response.text();
})
.then(function(data) {
document.getElementById('text').innerHTML = `<p>${data}</p>`;
// console.log(data)
});
e.preventDefault() // Prevent default behaviour of the button if there is any
})
We got our data loaded asynchronously with no form of waiting for the entire page to reload before getting the data.
These are the steps we took:
- We use the fetch method to fetch text data on our local computer, which then returns a promise containing the response, which is the HTTP response, and not the actual text data. So, we return the response.text() in order for the next .then() to make use of it.
- We then use the text method defined on the body mixin to extract the text body, we access the data and added it to the innerHTML of the HTML container:
document.getElementById('text').innerHTML = `<p>${data}</p>`;
, there is nothing stopping you from doing other stuff with the data.
Before we proceed, let's learn the arrow function to further simplify the use of callbacks:
Arrow Function Expressions
An arrow function expression is a compact alternative to a traditional function expression, so, instead of doing:
// Traditional Function
function (x){
return x + 50;
}
You can simplify with arrow function like so:
(x) => {
return x + 50;
}
You remove the word "function" and place arrow between the argument and opening body bracket.
To further simplify it, you can remove the body brackets and word "return", return is implicitly define:
(x) => x + 50;
That's not all, you can even remove the argument parenthesis if you like:
x => x + 50;
Easy right, from:
// Traditional Function
function (x){
return x + 50;
}
To
// Arrow Function
x => x + 50;
The { brackets } and ( parentheses ) and "return" are optional if you are only dealing with one argument or a single line of execution.
If you have multiple arguments, you must add parenthesis around the arguments:
Tradition function
// Traditional Function
function (x, y){
return x + y + 50;
}
Arrow function
// Arrow Function
(x, y) => x + y + 50;
If your function doesn't have an argument like so:
// Traditional Function (no arguments)
let x = 1, y = 2;
function (){
return x + y + 50;
}
// Arrow Function (no arguments)
let x = 1, y = 2;
() => x + y + 50;
If the body requires additional lines of processing, you'll need to re-introduce brackets PLUS the "return", it kinda make sense, since arrow functions might not know what we want to return:
// Traditional Function
function (x, y){
let z = 20;
return a + b + z;
}
// Arrow Function
(x, y) => {
let z = 20;
return a + b + z;
}
All the example we've done so far is for functions without names, a.k.a anonymous function.
function sum(x){
return x + 50;
}
// Arrow Function
let sum = x => y + 50;
With the understanding of the arrow function, let's convert our fetch example:
// The Fetch API
// Create Event Listener For the Load Plain Text Button
document.getElementById('load-text').addEventListener('click', function (e){
// Once the click event occur, we fetch the resource, and do some magic ;)
fetch('data/text.txt')
.then(function(response){
return response.text();
})
.then(function(data) {
document.getElementById('text').innerHTML = `<p>${data}</p>`;
// console.log(data)
});
e.preventDefault() // Prevent default behaviour of the button if there is any
})
To Fetch using Arrow functions:
// Create Event Listener For the Load Plain Text Button
document.getElementById('load-text').addEventListener('click', function (e){
// Once the click event occur, we fetch the resource, and do some magic ;)
fetch('data/text.txt')
.then( (response)=> response.text())
.then( (data) => document.getElementById('text').innerHTML = `<p>${data}</p>` )
e.preventDefault() // Prevent default behaviour of the button if there is any
})
Convince me this is not compact, and simpler.
Using The Fetch API With JSON
Working with JSON is no different from plain text, except that you need to use the JSON method to extract the JSON data. For this section, we would be using a fake JSON API, so, this time we would be testing an external fake JSON API, as you would most likely be working with an external API.
Go to https://jsonplaceholder.typicode.com/
and scroll to the resources section to see a couple of examples you can play with, I would be using the users' resources, which is here: https://jsonplaceholder.typicode.com/users
by default it gives you an array of 10 users, to access user one, you can simply add 1 to the URL like this: https://jsonplaceholder.typicode.com/users/1
We can put this into action using the following HTML structure:
<body>
<div class="content-wrapper text-center" id="container">
<div class="content-wrapper text-center">
<div class="container-fluid">
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card bg-light">
<div class="card-body">
<h2 class="card-header">Ajax - Working With JSON Data</h2>
</div>
<div id ="form-container" class="container-fluid">
<div class="row justify-content-lg-start">
<!-- Form Input -->
<form id="json-one-user" class="form-group m-auto">
<label class="w-300" for="user-id"></label>
<input autofocus class="form-control " id="user-id" placeholder="Enter User ID: 1 - 10"
type="text" value="">
<!-- Get Single User Submit Button -->
<input class="btn mt-10" id="one-json-data" type="submit" value="Get User">
<p class="mt-5m-auto">OR</p>
</form>
<!-- Get All User Submit Button -->
<div class="justify-content-center m-auto">
<input class="btn mt-10" id="all-json-data" type="button" value="Get All Users">
</div>
<div id="loading" class="mt-20 container-fluid"></div>
<!-- Table To Hold The Music List -->
<!-- Inner bordered table -->
<table class="table table-inner-bordered">
<thead>
<tr>
<th>#</th>
<th>Name</th>
<th>Address</th>
</tr>
</thead>
<tbody id="user-list">
<!-- We would dynamically insert the tbody row data -->
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
<script src="js/main.js" ></script>
The structure looks like this:
Let’s work with the single user input first, for that, I have:
Note: Make sure the fetch is followed by .then function
// The Fetch API
// For single user button
document.getElementById('json-one-user').addEventListener('submit', function (e){
// Get values entered into the input box
const userID = document.getElementById('user-id').value;
// Once the click event occur, we fetch the resource, and do some magic ;)
fetch(`https://jsonplaceholder.typicode.com/users/${userID}`)
.then( (response) => response.json())
.then( (data) => {
const list = document.getElementById('user-list');
// Create tr element
const row = document.createElement('tr');
// Insert cols
row.innerHTML = `
<td>${data.id}</td>
<td>${data.name}</td>
<td>${data.email}</td>`;
list.appendChild(row);
})
.catch(( err) => alert(err)) // If the promise failed, we catch and log the error in the console.
document.getElementById('user-id').value = '' // Clear the input
e.preventDefault() // Prevent default behaviour of the button if there is any
})
This is no different from the other examples, except with a couple of tweaks:
- For the single user, we listen to submit event type, which would only fire when a form is been submitted. So, I targeted the form ID:
json-one-user
- We get the value entered into the input box:
const userID = document.getElementById('user-id').value;
- We then fetch the external JSON resource:
fetch(`https://jsonplaceholder.typicode.com/users/${userID}`)
- The first .then return the response:
.then( (response) => response.json())
note that you can do return response.json() but since this is an arrow function, it is implicitly defined, after returning the response Promise, we catch it with the second .then - We are also using the arrow function with the second section, but you must use curly braces since it contains more than one line of expression:
.then( (data) => {...
- Within the second then, we grab the <tbody></tbody> element:
const list = document.getElementById('user-list');
and we created a tr element which is getting ready to be used:const row = document.createElement('tr');
- Lastly, we insert the data and appended it the row to the tbody element
- If the promise fails, we catch it and log it in the console:
.catch(( err) => console.log(err))
Here is an illustration:
Easy enough.
If you are like me, you might want to add a spinner while the request is processing. I got a cool spinner from flaticon for this illustration, so, create a folder name, icon, download a spinner, and add the spinner in the folder, rename the spinner to loading.svg.
Create a CSS/app.css folder, and add the following:
.icon {
display: inline-block;
width: 50px;
height: 50px;
animation: rotation 1s infinite linear;
}
@keyframes rotation {
from {
transform: rotate(0deg);
}
to {
transform: rotate(359deg);
}
}
Don’t bother adding a container to the HTML, I already added one right off bat, so, we can then do this in our JS file:
// For single user button
document.getElementById('json-one-user').addEventListener('submit', function (e){
/// Spinner
const image = document.createElement('img');
const divLoader = document.getElementById('loading');
image.setAttribute('src', 'icon/loading.svg') // Set src attribute
image.className = "icon";
// Append the image to div loader
divLoader.appendChild(image);
// Get values entered into the input box
const userID = document.getElementById('user-id').value;
// Once the click event occur, we fetch the resource, and do some magic ;)
fetch(`https://jsonplaceholder.typicode.com/users/${userID}`)
.then( (response) => response.json())
.then( (data) => {
// Remove the spinner icon since we are ready to display the result
let geticon = document.querySelector('.icon');
geticon.remove()
const list = document.getElementById('user-list');
// Create tr element
const row = document.createElement('tr');
// Insert cols
row.innerHTML = `
<td>${data.id}</td>
<td>${data.name}</td>
<td>${data.email}</td>`;
list.appendChild(row);
})
.catch(( err) => console.log(err)) // If the promise failed, we catch and log the error in the console.
document.getElementById('user-id').value = '' // Clear the input
e.preventDefault() // Prevent default behaviour of the button if there is any
})
As soon as the user clicks the submit button, we added the spinner, and in the second .then, we remove it since we are about to display the data.
This is the end result of that:
Cool if you ask me.
Awesome. For the Get All Users Button, we add the following event listener and function:
// For All user button
document.getElementById('all-json-data').addEventListener('click', function (e){
/// Spinner
const image = document.createElement('img');
const divLoader = document.getElementById('loading');
image.setAttribute('src', 'icon/loading.svg') // Set src attribute
image.className = "icon";
// Append the image to div loader
divLoader.appendChild(image);
// Once the click event occur, we fetch the resource, and do some magic ;)
fetch('https://jsonplaceholder.typicode.com/users/')
.then( (response) => response.json())
.then( (data) => {
let geticon = document.querySelector('.icon');
geticon.remove()
const list = document.getElementById('user-list');
data.forEach(function(user){
// Create tr element at each iteration
let row = document.createElement('tr');
// Insert cols
row.innerHTML = `
<td>${user.id}</td>
<td>${user.name}</td>
<td>${user.email}</td>`
list.appendChild(row);
});
})
.catch(( err) => console.log(err)) // If the promise failed, we catch and log the error in the console.
e.preventDefault() // Prevent default behaviour of the button if there is any
})
This is no different from the first one, except that the following request: https://jsonplaceholder.typicode.com/users
returns an array of users, so, we need to loop through it, which I did here:
data.forEach(function(user){
// Create tr element at each iteration
let row = document.createElement('tr');
// Insert cols
row.innerHTML = `${user.id}${user.name}${user.email}`
// Append to table
list.appendChild(row);
});
I am putting: let row = document.createElement(‘tr’); because I want to assign new item as it loops through, if it is not in the loop, you would get only the last item.
We can also check the status of the response, and otherwise throw an error if it isn't okay, I can convert this:
.then( (response) => response.json())
To:
.then(response => {
if (!response.ok) { // if response is not okay
throw new Error(`HTTP error! status: ${response.status}`); // the http status error code
} else {
return response.json(); // return response
}
})
So, this is the end result:
That’s it. Before moving on, let's get to understand Async and Await as we would be using that to build a custom HTTP library...
Async and Await
async function and the await keyword was introduced in ES2017. They both are syntactic sugar (a convenient way to write) on top of promises, making asynchronous code easier to write and to read afterward.
They make async code look more like old-school synchronous code.
Let's start with the async keyword:
To turn a function into an async, you put the async keyword in front a function declaration, here is an example of a standard function:
function greeting() { return "Hello World" };
greeting();
The above function returns "Hello World", simple right, I can turn it into an async function like so:
async function greeting() { return "Hello World" };
greeting(); // <- This returns a promise
You can also write it using an arrow function like so where greeting is the function name:
let greeting = async () => { return "Hello World" };
We can get the returned promise like so:
let greeting = async () => { return "Hello World" };
greeting.then((result) => console.log(result));
// Output =>
Hello World
or event with a shorthand notation:
greeting().then(console.log)
Cool.
So, the async keyword is added to functions to tell them to return a promise rather than directly returning the value.
What about the await keyword?
await can only be used inside an async function, and as you might have guessed, it is used to halt execution on a specific line until the promise fulfills, then return the resulting value.
To see a better use case for when to use await, I would convert, this:
// For All user button
document.getElementById('all-json-data').addEventListener('click', function (e){
// Once the click event occur, we fetch the resource, and do some magic ;)
fetch('https://jsonplaceholder.typicode.com/users/')
.then(response => {
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
} else {
return response.json(); // return response
}
})
.then( (data) => {
const list = document.getElementById('user-list');
data.forEach(function(user){
// Create tr element at each iteration
let row = document.createElement('tr');
// Insert cols
row.innerHTML = `
<td>${user.id}</td>
<td>${user.name}</td>
<td>${user.email}</td>`
list.appendChild(row);
});
})
.catch(( err) => console.log(err)) // If the promise failed, we catch and log the error in the console.
e.preventDefault() // Prevent default behaviour of the button if there is any
})
To:
// For All user button
document.getElementById('all-json-data').addEventListener('click', function (e){
async function fetchUser() {
let response = await fetch('https://jsonplaceholder.typicode.com/users/')
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
} else {
let jsonResult = await response.json(); // await response
jsonResult.forEach(function(user){
const list = document.getElementById('user-list');
// Create tr element at each iteration
let row = document.createElement('tr');
// Insert cols
row.innerHTML = `
<td>${user.id}</td>
<td>${user.name}</td>
<td>${user.email}</td>`
list.appendChild(row);
});
}
}
fetchUser() // call the fetch
.catch(( err) => console.log(err)) // If the promise failed, we catch and log the error in the console.
e.preventDefault() // Prevent default behaviour of the button if there is any
})
I don't know about you, but this makes the code much more simpler and readable, you write the way you speak.
The way it works is that we wrap the code in an async function, and we then assign a variable to hold the result of the response we are awaiting: await fetch('https://jsonplaceholder.typicode.com/users/')
await means to look forward to the result, in JavaScript runtime, it would pause that line (it won't execute that specific line) until the async function call has returned its result, which is super readable.
Once the async function call has been completed, the code continues to execute starting on the next line. For example:
let response = await fetch('https://jsonplaceholder.typicode.com/users/')
The response returned by the fulfilled fetch() promise is assigned to the response variable when that response becomes available, so as I said before, the parser pauses on that specific line until the response is returned.
Once the response is available, the parser moves to the next line, which in our case, we check if the response is okay, and if it is we also use another await, here:
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
} else { // ↓ here
let jsonResult = await response.json(); // await response
So, that line also pauses until it can extract the response to a JSON (I am using the json method cos we are working with JSON), I then store the result in the jsonResult variable as soon as it is available.
Once that is available, we then loop through the JSON data:
jsonResult.forEach(function(user){
const list = document.getElementById('user-list');
// Create tr element at each iteration
let row = document.createElement('tr');
// Insert cols
row.innerHTML = `
<td>${user.id}</td>
<td>${user.name}</td>
<td>${user.email}</td>`
list.appendChild(row);
});
We then call the fetch method, and catch an error if there is one:
fetchUser() // call the fetch
.catch(( err) => console.log(err)) // If the promise failed, we catch and log the error in the console.
Using async and await makes your code looks like you are writing a synchronous code, but behind the scene, it is all asynchronous, but in a way, it is not totally true:
Async/await makes your code look synchronous, and in a way it makes it behave more synchronously. The await keyword blocks the execution of all the code that follows it until the promise is fulfilled, exactly as it would with a synchronous operation. It does allow other tasks to continue to run in the meantime, but the awaited code is blocked.
Yes, it is syntactic sugar on top of promises, but if you want to run promises in parallel without awaiting the value of something, use the plain promise instead. Since we aren't doing anything in parallel yet, we should be fine.
Tiny HTTP Library (Fetch & async/await) ES6
Let's put all we've learned into practice, so, in this section, we would be creating a minimal HTTP library using Fetch API and async/await to:
- GET a request – GET is used to request data from a specified resource.
- POST a request – POST is used to send data to a server to create/update a resource.
- PATCH a request – PATCH updates part of the resource at that client-defined URL
- DELETE a request – The DELETE method deletes the specified resource.
https://jsonplaceholder.typicode.com/ let us play with all the above HTTP requests, we can use it to mimic an actual request.
Get a Request
We would create a new file for our library called tinyhttp.js which would contain the library code, and we would create a new file main.js which is where we would use the tinyhttp.js
In tinyhttp.js, I would start by creating a class with the get method like so:
'use strict';
// Class for our Tiny HTTP library
class TinyHTTP {
async Get(url) {
const response = await fetch(url)
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
} else {
return await response.json(); // wait, and return the result to the caller as soon as the await get a hold of the data
}
} // End of Get method -- http.Get(url).then().catch()
}
The async function takes in a URL param, which is what we would be fetching. We then assign a variable to hold the result of the response we are awaiting: const response = await fetch(url)
So, the response returned by the fulfilled fetch() promise is assigned to the response variable when that response becomes available, so the parser pauses on that specific line until the response is returned.
Once the response is available, the parser moves to the next line, which in our case, we check if the response is okay, and if it is we also use another await, here:
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
} else {
return await response.json(); // wait, and return the result to the caller as soon as the await get a hold of the data
}
So, the return awaits response.json() would first wait for a promise, it got one, it would return it to the caller (I am using the JSON method since we are working with JSON, if we are working with a text, we would use a text() method).
To use the Get method, open your main.js, and make use of it like so:
const http = new TinyHTTP; // Instantiate our library
http.Get('https://jsonplaceholder.typicode.com/users')
.then(user => console.log(user))
.catch(err => console.log(err))
Post Request
By default the fetch API uses a GET request, to use a POST request, you would have to explicitly add the method and the header like so:
// POST Async Method
async Post(url, data) {
const response = await fetch(url, {
method: 'POST',
headers: {
'Content-type': 'application/json'
},
body: JSON.stringify(data) // convert JS object to JSON
});
return await response.json(); // wait, and return the result to the caller as soon as the await get a hold of the data
} // End of Post Method -- http.Post(url, data).then().catch()
The Post method takes in two arguments:
- URL – The location or the URL you want the data to be created
- data – The data you are creating
When you are using the POST request, you need to set the value of an HTTP request header. A request header is an HTTP header that is used to provide information about the request context, this way, the server knows what type of data it is receiving. Since we are posting JSON data, we use:
headers: {
'Content-type': 'application/json'
},
We use JSON.stringify(data) to convert javascript object to JSON, here: body: JSON.stringify(data) // convert JS object to JSON
Lastly, we then return a promise using await: return await response.json(); /
To make use of the POST request, we would create a data, and use the POST method like so in our main.js file:
// Post Method
const http = new TinyHTTP; // Instantiate our library
// Create User
const data = {
name: 'the_devsrealm_guy',
email: 'devsrealm@mail.com'
};
http.Post('https://jsonplaceholder.typicode.com/users', data)
.then(user => console.log(user))
.catch(err => console.log(err))
// Output =>
/*
{name: "the_devsrealm_guy", email: "devsrealm@mail.com", id: 11}
email: "devsrealm@mail.com"
id: 11
name: "the_devsrealm_guy"
*/
https://jsonplaceholder.typicode.com took care of the ID increment, note that the request isn’t actually created, it is simply a fake REST API for testing things out.
That it is for the POST request...next up...
Patch a Resource
This method would let us update a resource:
// Patch Async Method
async Patch(url, data) {
const response = await fetch(url, {
method: 'PATCH',
headers: {
'Content-type': 'application/json'
},
body: JSON.stringify(data) // convert JS object to JSON
});
return await response.json(); // wait, and return the result to the caller as soon as the await get a hold of the data
} // End of Patch Method -- http.Patch(url, data).then().catch()
This is similar to the POST request, the only difference is when making use of it:
// Patch Method
const http = new TinyHTTP; // Instantiate our library
const data = {
name: 'new_devsrealm_guy',
email: 'devsrealm@mail.com'
};
// Update User 5
http.Patch('https://jsonplaceholder.typicode.com/users/5', data)
.then(user => console.log(user))
.catch(err => console.log(err))
// Output =>
// {id: 5, name: "new_devsrealm_guy", username: "Kamren", email: "devsrealm@mail.com", address: {…},…}
As you can see, I am specifying the URL I want to update, and the data object would update whatever key/value in the data object with the one in the actual URL.
Delete a Resource
This is really straightforward, we are deleting a specified resource:
// Delete Async Method
async Delete(url) {
const response = await fetch(url, {
method: 'DELETE',
headers: {
'Content-type': 'application/json'
},
});
return 'User Deleted...';
} // End of Delete Method -- http.Delete(url).then().catch()
The delete method doesn’t need a data argument as we only need the URL of whatever we want to delete. You don't need a body or stringify because we are sending nothing to the server.
When the resource is deleted, we return a message, here: return 'User Deleted...';
you can't use await there as a literal string isn't a promise type.
You can make use of it this way:
// Delete Method
const http = new TinyHTTP; // Instantiate our library
http.Delete('https://jsonplaceholder.typicode.com/users/5')
.then(user => console.log(user))
.catch(err => console.log(err))
// Output =>
User Deleted...
I think that's all! This is the full HTTP library:
'use strict';
// Class for our Tiny HTTP library
class TinyHTTP {
// GET Async Method
async Get(url) {
const response = await fetch(url)
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
} else {
// await response
return await response.json(); // wait, and return the result to the caller as soon as the await get a hold of the data
}
} // End of Get method -- http.Get(url).then().catch()
// POST Async Method
async Post(url, data) {
const response = await fetch(url, {
method: 'POST',
headers: {
'Content-type': 'application/json'
},
body: JSON.stringify(data) // convert JS object to JSON
});
return await response.json(); // wait, and return the result to the caller as soon as the await get a hold of the data
} // End of Post Method -- http.Post(url, data).then().catch()
// Patch Async Method
async Patch(url, data) {
const response = await fetch(url, {
method: 'PATCH',
headers: {
'Content-type': 'application/json'
},
body: JSON.stringify(data) // convert JS object to JSON
});
return await response.json(); // wait, and return the result to the caller as soon as the await get a hold of the data
} // End of Patch Method -- http.Patch(url, data).then().catch()
// Delete Async Method
async Delete(url) {
const response = await fetch(url, {
method: 'DELETE',
headers: {
'Content-type': 'application/json'
},
});
return 'User Deleted...';
} // End of Delete Method -- http.Delete(url).then().catch()
}
I built something similar with XHR, but this one is even more simpler and robust.