3

I created an IG like button where the number of like changes after a click. I added 2 fetch functions - one with PUT. I tried multiple ways but the results are same - the GET fetch is getting executed first. How can I prevent that?

function liking(tweetid) {

    let l = document.querySelector('#numlikes-' + tweetid);

    fetch(`tweets/${tweetid}`, {
        method: 'PUT',
        body: JSON.stringify({
            tweet_like: 1
        })
    });
    
    fetch(`tweets/${tweetid}`)
    .then(response => response.json())
    .then(post => {
        l.innerHTML = post.likes;
    });

}
abhiramrp
  • 99
  • 6
  • Duplicate: [Web Fetch API (waiting the fetch to complete and then executed the next instruction)](https://stackoverflow.com/questions/41775517/web-fetch-api-waiting-the-fetch-to-complete-and-then-executed-the-next-instruct) –  Nov 08 '21 at 15:33

3 Answers3

3

Javascript is a synchronous language, a line of code is not waiting for line before to finish by default. By near instant operations that is not important and won’t matter. Here since the fetch needs to communicate with a server your second fetch starts, before the first one finished. There are two simple solutions to solve this issue

Using async await

Since ES6 we have the ability to use async await:

async function liking(tweetid) {

    let l = document.querySelector('#numlikes-' + tweetid);

    await fetch(`tweets/${tweetid}`, {
        method: 'PUT',
        body: JSON.stringify({
            tweet_like: 1
        })
    });
    
    await fetch(`tweets/${tweetid}`)
    .then(response => response.json())
    .then(post => {
        l.innerHTML = post.likes;
    });

}

Chaining with .then:

function liking(tweetid) {

    let l = document.querySelector('#numlikes-' + tweetid);

    fetch(`tweets/${tweetid}`, {
        method: 'PUT',
        body: JSON.stringify({
            tweet_like: 1
        })
    }).then(() => {
      fetch(`tweets/${tweetid}`)
      .then(response => response.json())
      .then(post => {
          l.innerHTML = post.likes;
      });
    });
    
}
Julian Wagner
  • 674
  • 6
  • 16
Markiesch
  • 721
  • 3
  • 11
  • Thank you! The first one is working just like I want to! – abhiramrp Nov 08 '21 at 21:26
  • I does not make sense to me to say "Javascript is a synchronous language, a line of code is not waiting for line before to finish by default. " What is a synchronous language? And Javascript is not line based, so it does not make sense to say line of code is not waiting. But most of all most definitely statements in Javascript are executed in order so previous command is completed before the next one begins executing. APIs can and some do exhibit asyn / out of order execution but statements don't. – nyholku Jul 17 '23 at 16:02
0

fetch is an async function. It means you cannot predict which fetch response you receive first. To make it to call in order you should call GET fetch in the response callback of PUT fetch.

function liking(tweetid) {

    let l = document.querySelector('#numlikes-' + tweetid);

    fetch(`tweets/${tweetid}`, {
        method: 'PUT',
        body: JSON.stringify({
            tweet_like: 1
        })
    }).then(() => {
           fetch(`tweets/${tweetid}`)
           .then(response => response.json())
           .then(post => {
              l.innerHTML = post.likes;
           });
    })

}
Georgy
  • 1,879
  • 2
  • 9
  • 14
0

I posted an answer in Stack Exchange to this problem:

https://sharepoint.stackexchange.com/questions/263675/how-to-use-promise-all-and-foreach-to-make-ajax-call-per-array-item/305752#305752

It includes the full AJAX Helper typescript (it is typescript though) that allows you to make multiple ajax calls on an array in series (wait for one to finish before executing next).

Note thought, this solution is only if you want to make the SAME request on an array of objects, if you want to make different requests then you would have to manually chain them with the .then

Trevor F
  • 1,429
  • 9
  • 6