Gedalya Gedalya - 5 months ago 10
Javascript Question

Loading Message While Function Processes

I am looking for a way to have a pop-up dialog display a loading message while a function executes. I see examples of doing this for a page loading but it is less clear to me how to handle this for a javascript function. I've made several attempts and they fail due my inability to manage the asynchronous nature of this action. Loading the message dialog, then executing the function, then closing the message dialog. For example I can get the message to pop-up fine and have the process running; but trying to add in the close out portion fails. I find that the close dialog portion triggers before the actual function I am trying to process is finished.

I have a loading modal as follows:

<loading modal-id="loadingMessage" message="Processing, please wait..."></loading>


The function to display the message; which returns a promise:

function displayLoadingMessage() {
var count = 0;
var defer = $q.defer();

var stop = $interval(function() {
var loadingMessage = $('#loadingMessage');

if (loadingMessage != null && loadingMessage.length > 0) {
loadingMessage.modal({
keyboard: false,
backdrop: 'static'
});

$interval.cancel(stop);
defer.resolve();
}

count++;

if (count > 100) {
$interval.cancel(stop);
defer.resolve();
}
}, 100);

return defer.promise;
};


I've tried chaining the calls in an asynchronous fashion as follows:

var message = displayLoadingMessage()
message.then(functionToWaitOn()).then($('#loadingMessage').modal('hide'));


The function
functionToWaitOn()
calls other function(s). The basic layout though is:

function functionToWaitOn() {
if(condition == true) {
secondFunction();
} else {
thirdFunction();
}
}


secondFunction()
/
thirdFunction()
is where the major work is done; they trigger a process on the server side which executes and this is what takes the time.

Any help appreciated.

Answer

EDIT

You need to change fundamentally how you are doing this. functionToWaitOn() needs to return a promise, and by the looks of things, so do secondFunction() and thirdFunction()

I assume somewhere along the way you are calling $http.get() or something similar - you need to make that specific function return a promise.

I think you should read up more on how deferred and promises work. See this and this

function functionToWaitOn() {
    var defer = $q.defer();
    if (condition) {
        secondFunction().then(function() { defer.resolve() }
    } else {
        thirdFunction().then(function() { defer.resolve() }
    }
    return defer.promise;
}

You need to remember that then() takes anonymous functions or function pointers as arguments. Your code needs to be:

var message = function() {
    return displayLoadingMessage();
}

message().then(function() {
    functionToWaitOn().then(function() {
        $("#loadingMessage").modal('hide');
    }
});

Or more simply...

displayLoadingMessage().then(function() {
    functionToWaitOn().then(function() {
        $("#loadingMessage").modal('hide');
    }
});

Be aware that you might end up in callback hell after this