skip to Main Content

I am working on a flask application and there is this javascript function associated with a form

function applyQueries() {
        // does some things
        if(currentCatalog != ''){
            addCatalogFilters(currentCatalog);
        }
        $.ajax({
            type: 'POST',
            url:  "/applyQueries",
            contentType: "application/json",
            success:function(response){ 
                        // does some stuff here
        })
}

The addCatalogFilters() function is also an ajax call. Both these calls change some variables in the python side of things. What I want to know is if the first ajax call (in addCatalogFilters), is guaranteed to execute and return before the second one. I am ending up with weird results that appear to be race conditions based on the order the ajax calls execute. Is this possible with code structured like this? Also if so, how can I fix it?

    // Add user catalog filters
    function addCatalogFilters() {
        catalog = currentCatalog;
        formData = new FormData(document.getElementById('catalogFilterForm'));
        $.ajax({
            type: 'POST',
            url:  "/addCatalogFilters",
            data: formData,
            processData: false,
            contentType: false,
            success: function (response){
                document.getElementById(catalog + 'close').style.display = 'block';
                document.getElementById(catalog + 'check').style.display = 'none';
                addBtns = document.getElementsByClassName("addBtn");
                removeBtns = document.getElementsByClassName("removeBtn");
                for (i = 0; i < addBtns.length; i++) {
                    addBtns[i].style.display = "none";
                    removeBtns[i].style.display = "inline-block";
                }
            }
        })
    };

4

Answers


  1. You could try using async/await like this:

    async function applyQueries() {
    
      if(currentCatalog !== ''){
        const filtersAdded = await addCatalogFilters(currentCatalog);
      }
    
      // Perform AJAX call
    
    }
    

    By usinc async/await, your code will wait until the addCatalogFilters() function has resolved. However, for this to work, the addCatalogFilters() function should be async with a return value. Something like this:

    async function addCatalogFilters(catalog){
      // Ajax call
      $.ajax({
            type: 'POST',
            url:  "foo",
            contentType: "application/json",
            success:function(response){ 
              return true
        })
    
    }
    
    Login or Signup to reply.
  2. You can ensure with success function of ajax. First call a ajax (let’s say ajax1) then call another ajax call within the success function of first ajax call (ajax1 success function).

    addCatalogFilters(currentCatalog)
    {
        $.ajax({
                type: 'POST',
                url:  "/the-post-usl",
    
                success:function(response){ 
    
                    $.ajax({
                    type: 'POST',
                    url:  "/applyQueries",
                    contentType: "application/json",
                    success:function(response){ 
                            // does some stuff here
                    });
            })
    }
    
    function applyQueries() {
            // does some things
            if(currentCatalog != ''){
                addCatalogFilters(currentCatalog);
            }
    
    }
    

    It may not be the optimum way. But guarantee one ajax call is complete before calling another.

    Login or Signup to reply.
  3. Depending on how applyQueries is called, you may need to have an await or .then where you call it. Note that you can also use “result = await addCatalogFilters(currentCatalog)” to put the ajax result into a variable result that you can work with and pass to your $.ajax call in applyQueries. I don’t know the nature of your code, so I can’t make any direct suggestions.

    async function applyQueries() {
            // does some things
            if(currentCatalog != ''){
                // await on the returned Promise-like jqXHR (wait for ajax request to finish)
                // recommend assigning awaited result to a variable and passing to next $.ajax
                await addCatalogFilters(currentCatalog);
            }
            return $.ajax({
                type: 'POST',
                url:  "/applyQueries",
                contentType: "application/json",
                success:function(response){ 
                            // does some stuff here
            })
    }
    

    // Add user catalog filters
    function addCatalogFilters() {
        catalog = currentCatalog;
        formData = new FormData(document.getElementById('catalogFilterForm'));
        // return the Promise-like jqXHR object: https://api.jquery.com/jQuery.ajax/#jqXHR
        return $.ajax({
            type: 'POST',
            url:  "/addCatalogFilters",
            data: formData,
            processData: false,
            contentType: false,
            success: function (response){
                document.getElementById(catalog + 'close').style.display = 'block';
                document.getElementById(catalog + 'check').style.display = 'none';
                addBtns = document.getElementsByClassName("addBtn");
                removeBtns = document.getElementsByClassName("removeBtn");
                for (i = 0; i < addBtns.length; i++) {
                    addBtns[i].style.display = "none";
                    removeBtns[i].style.display = "inline-block";
                }
            }
        })
    };
    
    Login or Signup to reply.
  4. You can use async/await. However, as no one has mentioned, I would like to demonstrate how you can accomplish this with Promise.

    Lets define two functions:

    function first_function(data) {
    
      return new Promise((resolve, reject) => {
    
        let dataSet = [[]];
    
        let response;
    
        $.ajax({
          type: "POST",
          url: 'example.com/xyz',
          async: false,
          data: data,
          success: function (value) {
            response = value;
            dataSet = JSON.parse(response);
            resolve(dataSet)
          },
    
          error: function (error) {
            reject(error)
          },
          processData: false,
          contentType: false
        });
    
      })
    
    }
    
    
    function second_function(data) {
    
      return new Promise((resolve, reject) => {
    
        let dataSet = [[]];
    
        let response;
    
        $.ajax({
          type: "POST",
          url: 'example.com/abc',
          async: false,
          data: data,
          success: function (value) {
            response = value;
            dataSet = JSON.parse(response);
            resolve(dataSet)
          },
    
          error: function (error) {
            reject(error)
          },
          processData: false,
          contentType: false
        });
    
      })
    
    }
    

    Now you can make sure that second_function() gets called only after the execution of ajax request in first_function() by following approach:

    first_function(data)
      .then(dataSet => {
        //do other things
        second_function(dataSet)
          .then(dataSet2 => {
            ////do whatever you like with dataSet2
    
          })
          .catch(error => {
            console.log(error);
          });
    
      });
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search