Originally posted on my blog.
TL;DR
In this post we'll do everything we did in the second post, but with Fetch API.
What's this Fetch API?
The almighty docs say
The Fetch API provides an interface for fetching resources (including across the network). It will seem familiar to anyone who has used
XMLHttpRequest
(see the first post in the series on how to do that), but the new API provides a more powerful and flexible feature set.
I prepared this demo page so that you can test.
You'll remember from the last post that in order to make an AJAX call with jQuery, you have to do something like this:
$('#result').load('http://nikola-breznjak.com/_testings/ajax/test1.php?ime=Nikola');
Go ahead and run that code on the demo page in the browser's dev tools Console (consult the last post if you're stuck).
Now, the very same thing with the Fetch API looks like this:
fetch('http://nikola-breznjak.com/_testings/ajax/test1.php?ime=Nikola')
.then(function(response) {
return response.text();
})
.then(function(text) {
$('#result').html(text);
});
Go ahead and try it in the Console. Change the ime
parameter, and you'll see that the text on the page will change to Hello [name]
, where [name] will be the parameter you entered. Note that in the example above I still used jQuery to set the content of the div with id result
.
The docs have way more info on this but, as they say, the difference between fetch()
and $.ajax()
is in two main things:
- The Promise returned from
fetch()
won’t reject on HTTP error status even if the response is an HTTP 404 or 500. Instead, it will resolve normally (with ok status set to false), and it will only reject on network failure or if anything prevented the request from completing. - By default,
fetch()
won't send or receive any cookies from the server, resulting in unauthenticated requests if the site relies on maintaining a user session (to send cookies, the credentialsinit
option must be set).
⚠️ At a later point you may want to read a bit more about Promises in JavaScript.
Rewriting the mini project
I encourage you to try it for yourself and then check your solution to mine.
The mini project (which you can test here) would be rewritten like this:
var link = 'http://nikola-breznjak.com/_testings/ajax/test2.php';
fetch(link)
.then(function(response){
return response.json()
})
.then(function(result){
var oglasiHTML = '';
$.each(result, function(index, oglas){
var klasaCijene = '';
if (oglas.cijena < 100){
klasaCijene = 'is-success';
}
else if (oglas.cijena >= 100 && oglas.cijena < 300){
klasaCijene = 'is-info';
}
else if (oglas.cijena >= 300){
klasaCijene = 'is-danger';
}
oglasiHTML += `
<div class="columns">
<div class="column is-one-quarter">
<span class="tag ${klasaCijene}">${oglas.cijena}</span>
</div>
<div class="column">${oglas.tekst}</div>
</div>
`;
});
$('#oglasi').html(oglasiHTML);
});
There are a few things that I'd like to point out here:
- I used the
response.json()
because I know that this API returns a JSON response (you can check by opening that link in the browser). - I used the jQuery each function to iterate over the
result
. - I used the template literals to construct the final
oglasiHTML
in a much cleaner way than we did that in the previous post with using concatenation.
I want more examples
Say you have this demo page, and you need to make the newsletter signup form use AJAX instead of going to a new page when you click the Subscribe
button. Right now the API (located at http://nikola-breznjak.com/_testings/ajax/email.php) doesn't actually process what you send to it but try to send data with the request as well for practice.
How would you do it? Where would you start?
Well, here are a few search terms you could Google:
- `fetch api submit data'
Again, here's my solution, but I encourage you to try it yourself first.
$('form').submit(function(ev){
ev.preventDefault();
var url = $(this).attr('action');
var formData = $(this).serialize();
fetch(url, {method: 'post', body: formData})
.then(function(response){
$('#newsletter').html('Thank you for subscribing, please check your email.');
});
});
There are a few things that I'd like to point out here:
- I was able to use the
form
selector without any id because it's the only form on the page. If there were more forms on the page, I'd have to distinguish them by using an id (which is always a good practice, even if it's just one form) - I used jQuery's submit function to set an event handler that will be executed when the form will be submitted (
Subscribe
button clicked, or ENTER pressed while in one of the fields) - I used the
ev.preventDefault()
to prevent the form from "doing its thing" and loading the 'email.php' page, as its default behavior - I used
$(this).attr('action')
to extract the API URL from the form definition it the HTML (feel free to check it out in the element inspector) - I used
$(this).serialize()
to encode a set of form elements as a string which I then passed tobody
attribute of thefetch
settings object. This function sends a request to the server using the POST method (using themethod
setting on the settings object), which (as we learned in the previous post) is the preferred way of sending some sensitive data that needs to be handled on the server - I used the html function on a
div
with the idnewsletter
to set its new content
Can I have one more, please?
Sure, but promise you'll do it yourself first!
I do 🤞
OK then, let's do this 💪
Here's a new demo page that you'll use for this example.
⚠️ I'm using Bulma to make the site look pretty. As their website says:
'Bulma is a free, open-source CSS framework based on Flexbox and used by more than 150,000 developers.'
I'll just say it's really great and easy to learn, so make sure you check it out.
In this challenge, you have to create a gif search application using the Giphy Search API. As the docs state, you'll need to get the API key by creating an app. Once you do that, you'll be able to search their API like, for example, this: http://api.giphy.com/v1/gifs/search?q=funny+cat&api_key=dc6zaTOxFJmzC
. You can use this API key, but be sure to create your own if this one gets banned for too many requests 🤦
Once you fetch the gifs (or still images if you so choose), show them in the div with a class result
(yes, class, not id 👍).
Here's the part where you roll up your sleeves, create it, feel proud of yourself 💪, and then come here to check how I did it.
`
$('form').submit(function(ev){
ev.preventDefault();
var searchTerm = $('input').val();
var apiLink = "http://api.giphy.com/v1/gifs/search?api_key=dc6zaTOxFJmzC&q=" + searchTerm;
var output = '';
fetch(apiLink)
.then(function(response){
return response.json();
})
.then(function(images){
$.each(images.data, function(i, im){
output += `<img src="${im.images.downsized.url}"/>`;
});
$('.result').html(output);
});
});
`
As you may notice, very few things changed from the last post, and it's quite easy to exchange the jQuery AJAX calls with Fetch API.
Conclusion
That's all for this blog post. I hope it was useful and that you've seen how easy it is to make AJAX requests with the Fetch API. I also hope you liked the demo exercises 👍
This wraps it up with these three post series. Have a great time and see you soon! 💪
Top comments (5)
Very nice post, but I don't quite understand why you would use
$('#result')
instead ofdocument.querySelector('#result')
; the first is quicker to write, but the latter is easier to understand and doesn't require loading jQuery to work.same for
$.each
; it's 2019, we can just write[1, 2, 3, 4].each(console.log)
, no need for jquery whatsoever <3Ah, sorry, not sure how I missed this reply :(
Thank you for your comments, I agree.
Love the AJAX soap bottle. I had the same joke. Makes me think about javascript everytime I do the dishes!
Nice post ! maybe you can show how to use or introduce async/await with the fetch API by still using the same examples :)
Thank you! That's a good idea 👍