Search code examples
javascriptasync-awaitfetches6-promise

How to use a promise again after it has already been resolved


I am currently trying to create a feature that allows users to add and remove their favourite locations. The favourite locations are being stored in a database and I am using a promise to fetch and display the locations. This works fine for when the page loads. However, I want the fetch to take place again after each time a user adds or removes a favourite location and so I will be displaying the most up to data information. I think the problem I have at the moment is that I am trying to call the async function again but because the promise has already been resolved when the page loads the fetch is not taking place. Is there a way to get around this?

My code that I am using looks like:

var current_user = context.current_user;
var favAddressSection = document.getElementById('favouriteAddressSection');
var locations = []

const getFavAddresses = new Promise((resolve, reject) => {
  setTimeout(() =>{
    if (current_user == 0){
      resolve(null)
    }
    fetch("api/favaddress/")
      .then(response => {
          return response.json();
      })
      .then(data => {
          for (var i =0; i < data.length; i++){
            locations.push(data[i])
          }
          resolve(locations)
      })
      .catch(error => {
        reject(console.log(error))
      })
    })
  }, 1);


async function getFavAddressAwait(){

  const addresses = await getFavAddresses;
  var innerHTML = " "; 
  for (var i = 0; i < addresses.length; i++){
    innerHTML += '<div class="favAddressElement"> <h4>' + addresses[i].name + '</h4> <button class="favAddressButton"> <img src="../static/images/favAddress.png"> </button> <button onClick=deleteLocation(' + addresses[i].id + ')>Remove</button></div>'
  }
  if (addresses.length < 6){
    innerHTML += '<div class="favAddressElement"> <h5> Add Favourite </h5> <button id="addAddress" class="favAddressButton" onClick=showForm()> <img src="../static/images/add_fav.png"/> </button> </div> '
  }
  favAddressSection.innerHTML = innerHTML;
}

getFavAddressAwait();


function deleteLocation(primarykey){
  axios.delete(`http://127.0.0.1:8000/api/favaddress/destroy/${primarykey}`)
    .then(res => console.log(res))
    .then(getFavAddressAwait())
    .catch(err => console.log(err));
}


Solution

  • You could change your getFavAddress variable to return a new promise instance everytime it's called.

    Also, I'd recommend removing your setTimeout, unless you have a reason for it?

    Like so:

    const getFavAddresses = () => new Promise((resolve, reject) => {
        if (current_user == 0){
            resolve(null);
        }
        fetch("api/favaddress/")
            .then(response => {
                return response.json();
            })
            .then(data => {
                for (var i =0; i < data.length; i++){
                    locations.push(data[i]);
                }
                resolve(locations);
            })
            .catch(error => {
                reject(console.log(error));
            })
        ;
    }, 1);
    

    and then just update your call to it: await getFavAddress()