loading...

Making AJAX calls using the Fetch API

nikola profile image Nikola Brežnjak ・6 min read

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 credentials init 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 to body attribute of the fetch settings object. This function sends a request to the server using the POST method (using the method 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 id newsletter 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! 💪

Discussion

pic
Editor guide
Collapse
darkwiiplayer profile image
DarkWiiPlayer

Very nice post, but I don't quite understand why you would use $('#result') instead of document.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 <3

Collapse
anthonypierrat profile image
Anthony PIERRAT

Nice post ! maybe you can show how to use or introduce async/await with the fetch API by still using the same examples :)

Collapse
nikola profile image
Nikola Brežnjak Author

Thank you! That's a good idea 👍

Collapse
interactiverob profile image
Rob Kirkner

Love the AJAX soap bottle. I had the same joke. Makes me think about javascript everytime I do the dishes!