skip to Main Content

I’ve got an $.each loop, that is within another $.each that is calling a function to add values to my back end system.

My $.each loops are like this:

$.each(locations, function( i, location ) { 
    $.each(location, function( i, site ) {
        addsite ( site.url, site.address, site.zip, site.contact, site.id )
    })
})

When I call the function addsites directly, not from within the $.each loops it works as expected, however when called from within the $.each loops it works, but sometimes code is being called before other code has completed.

After lots of testing I’ve worked out it’s due to $.ajax being called which obviously doesn’t complete before the other code is run.

My working function is :

function addsite( url, address, zip, contact, id ) {
                
    // 1. lots of jquery
    // 2. lots of jquery
    
    $.ajax({ type: "POST",   
        url: url,
        cache: false,
        complete : function(text) {
            console.log ( '3.' + text )

        }
    });
    
    // 4. more jquery
})

I added debugging into points 1, 2, 3 and 4 and could see that everything in 1. and 2. is called correctly, but the code in 4. is being running before the $.ajax has completed.

When the function is called in the $.each loop, I see 1,2,4 multiple times in the console.log followed by multiple 3’s as that is completing later. This needs to be running as 1,2,3,4.

I understand why that happens and have found adding async: false to $.ajax allows this to work, but that is depreciated so I’m trying to find a better way.

Do I need to do something to the $.each loops or the addsite function ? If it’s the function I need to make sure this works when called directly not just from the $.each loops.

Could some advise how I can get this to work correctly.

Thanks

2

Answers


  1. A Little bit updated code as per your understanding standard:

    $.each(locations, function( i, location ) { 
        $.each(location, function( i, site ) {
            addsite ( site.url, site.address, site.zip, site.contact, site.id, function() {
                
                console.log("AJAX request complete for " + site.id);
            });
        });
    });
    

    Also in this fn

    function addsite( url, address, zip, contact, id, callback ) {
    
        $.ajax({ 
            type: "POST",   
            url: url,
            cache: false,
            complete : function(text) {
                console.log ( text );
                callback(); 
            }
        });
        
    }
    

    Try this..

    Login or Signup to reply.
  2. I’m sorry that I didn’t immediately see that it can’t be used async: false in ajax request.

    Now reworked the cycles on for of and add async await, made a test case:

    // 👇 for example, the location is only with id
    const locations = [
      [
        {id: 1},
        {id: 2}
      ],
      [
        {id: 3},
        {id: 4}
      ]
    ];
    
    // 👇 your function
    const addsite = async( url, address, zip, contact, id ) => {
    
      console.log(`before ${id}`); // 👈 before ajax scripts
      
      await $.ajax({
        type: 'POST',   
        url: 'https://www.boredapi.com/api/activity', // 👈 for testing
        cache: false,
        complete : function(text) {
          console.log(`${id} is complete`); // 👈 site added
        }
      });
      
      console.log(`after ${id}`); // 👈 after ajax scripts
      console.log(''); // 👈 just divider
      
    };
    
    // 👇 loops
    (async () => {
      for (let location of locations) { // 👈 first loop
        for (let site of location) { // 👈 second loop
          await addsite(site.url, site.address, site.zip, site.contact, site.id);
        }
      }
    })();
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search