DEV Community

loading...

How to deal with non-async APIs in an async way using javascript

climentea profile image Alin Climente ・2 min read

Let's say you have to work with an API which is not updated to the newest async trends.

Making a call to an API takes some time and you need to keep the users informed about what's going on with their request.

Instead of making the user stare at a loading screen you can handle their requests using javascript along with any modern frontend framework (React, Vue etc).

By making use of stores you can handle a sync API backend without altering your way of working with a frontend framework.

Let's say we have this code on the backend:

from time import sleep
from flask import Flask, render_template
from flask.json import jsonify

api = Flask(__name__)

@api.route("/")
def index():
    return render_template("index.html")

@api.route("/long-wait")
def long_wait():
    sleep(5) # some task that takes a lot of time to process
    return jsonify({"data": "was gathered"})

@api.route("/short-wait")
def short_wait():
    sleep(1) # another task that takes a little bit less
    return jsonify({"data": "fetched"})

if __name__ == "__main__":
    api.run(debug=True)

Enter fullscreen mode Exit fullscreen mode

In the example from above we have 2 endpoints that we are interested in: /long-wait and /short-wait. Both do some computations on the backend, while one of them takes longer than the other (the API is made in Flask, which is a sync backend framework for Python3).

With javascript you can make a better experience by using something like the lines written bellow:


    <button>get some data (long-wait)</button>
    <p>click to fetch data</p>

    <button>get some data (short-wait)</button>
    <p>click to fetch data</p>


    <script>

        let btn = document.getElementsByTagName("button")[0]
        let p = document.getElementsByTagName("p")[0]

        btn.addEventListener("click", () => {
            btn.disabled = true
            btn.innerText = "loading..."
            p.innerText = "data is being fetched"
            fetch("http://localhost:5000/long-wait")
            .then(res => res.json())
            .then(data => {
                console.log(data)
                btn.disabled = false
                btn.innerText = "get some data (long-wait)"
                p.innerText = JSON.stringify(data)
            })
        })


        let btn_short_wait = document.getElementsByTagName("button")[1]
        let p_short_wait = document.getElementsByTagName("p")[1]

        btn_short_wait.addEventListener("click", () => {
            btn_short_wait.disabled = true
            btn_short_wait.innerText = "loading..."
            p_short_wait.innerText = "data is being fetched"
            fetch("http://localhost:5000/short-wait")
            .then(res => res.json())
            .then(data => {
                btn_short_wait.disabled = false
                console.log(data)
                btn_short_wait.innerText = "get some data (short-wait)"
                p_short_wait.innerText = JSON.stringify(data)
            })
        })

    </script>

Enter fullscreen mode Exit fullscreen mode

In the above lines you have some simple javascript code which deals with the API in an async way, keeping the user informed on their requests.

Below we have a sample on how the code works:

sync_apis

Discussion (0)

pic
Editor guide