Multiple ajax calls inside a each() function.. then do something once ALL of them are finished?

Use deferred objects:

$("#form").submit(function(e){

    e.preventDefault();

    var calls = [];

    $(".friendName[value!='']").each(function(){
        // Submit the ajax request
        calls.push($.ajax({ 
            type: 'POST', 
            url: 'ajax/url', 
            data: {
                name: name,
                email: email
             },
             success: function(json) {
                // Log a console entry if our ajax request was successful
                console.log(name + " was submitted via ajax");
             }
         }));
    });

    $.when.apply($, calls).then(function() {
        window.location= '/thanks';
    });
});

Ok, this is fairly easy since you're using jQuery. jQuery comes with an integrated promise maker which also is wired up with jQuery's Ajax calls. What does that mean? Well, we can easily go like this:

var requests = [ ];

// ...

// Submit the ajax request
requests.push($.ajax({ 
    type: 'POST', 
    url: 'ajax/url', 
    data: {
        name: name,
        email: email
    },
    success: function(json) {
        // Log a console entry if our ajax request was successful
        console.log(name + " was submitted via ajax");
    }
}));

// at this point we filled our array with jXHR objects which also inherit the promise API

$.when.apply( null, requests ).done(function() {
    document.location.href = '/thanks';
});

Note: The above code will only fire, if all requests completed successfully. If you need to handle the case if one ore more requested failed, use .then() or .fail() instead of .done(), too.


Just keep a counter of the AJAX calls and check to see when they have all completed. Something like this:

$("#form").submit(function(){
    var ajaxMax = $(".friendName[value!='']").length, ajaxCounter = 0;
    $(".friendName[value!='']").each(function(){
        var idEmail = 'friendEmail' + $(this).attr("id").replace('friendName','');
        if($("#"+idEmail+"[value!='']").length > 0){
            var name = $(this).val();
            var email = $("#"+idEmail).val();

            // Submit the ajax request
            $.ajax({ 
                type: 'POST', 
                url: 'ajax/url', 
                data: {
                    name: name,
                    email: email
                },
                success: function(json) {
                    // Log a console entry if our ajax request was successful
                    console.log(name + " was submitted via ajax");
                    if(++ajaxCounter >= ajaxMax)
                        window.location= '/thanks';
                }
            });
        }
    });
});