Question

Heyo,

Basic workflow:

  • Form submit button is clicked
  • Submit event is captured
  • Capture function runs a callback script
    • If the script returns false e.preventDefault() is called
    • ELSE Form submits

The above is all working fine. I have just provided it for context. The issue I am having is that as part of the callback script, a series of SQL UPDATE events are fired off. The script for this is below:

function writeNewProductDetails() {
    for(var i = 0; i < $('#productForm').children('input').length; i++) {
        var input = $('#productForm').children('input')[i];
        var inputType = $(input).attr('id').split('---');
        var inputVal = $(input).val();

        switch(inputType[1]) {
            case 'quantity' :
                localDB.webdb.runSQL('UPDATE orderLines SET "collected" = "'+inputVal+'" WHERE orderLineID = '+inputType[0])
                break;
            case 'code' :
                localDB.webdb.runSQL('UPDATE orderLines SET "code" = "'+inputVal+'" WHERE orderLineID = '+inputType[0])
                break;
        }
    }
    window.location(history(-1));
    return false;
}

Now a lot of this code is irrelevant to the question, the key part is the switch statement and the following two lines. The window.location and return false commands are used to avoid actually submitting the form (as the processing is already done).

Here is the crux of the issue. If I comment out the window.location(history(-1)) command and just have the function return false (ie stop the page submitting), the web-sql commands kick off and run as expected. If I leave it in, then the window seems to shift away before the sql commands have finished processing. This means that the database doesn't update.

Is this sort of issue a known problem, and is there a 'best-practice' to deal with it? I can't imagine that using the web-sql backend on form submit is a completely foreign concept?

---EDIT---

In the end I went with the following solution, its not the prettiest one in the world but it works.

  • Firstly I defined a global variable var queryCountWNPD = 0; the wnpd stands for writeNewProductDetails.
  • I then incremented the variable whenever a query was sent ie queryCountWNPD++; \\ localDB.webdb.runSQL('UPDATE orderLines...
  • After that I added a callback function to the sql command detailsWritten
  • This function (below) decrements the queryCountWNPD then checks if it is equal to 0. If it is then it runs the original window.history.go(-1) command.

    function detailsWritten() {
        queryCountWNPD--;
    
        if(queryCountWNPD == 0) {
            window.history.go(-1);
        }
    }
    

The answer below was credited because it pointed me in the right direction.

Was it helpful?

Solution

Interesting problem. It looks like you're having a concurrency issue. It appears as if the JS parser is not waiting for runSQL to finish before moving on to the next statement. At which point, JS continues to execute, until you hit window.location, which instantly loads a page from the history, and you lose your context. This also means, I don't think you ever hit your return false, because window.location acts like an interrupt, it fires immediately.

Also note that control statements (for, switch, if, etc.) do not increment the stack in JavaScript. I'm not sure how this applies, but I have a funny feeling that it might matter.

See if you can put the window.location outside of this function, higher in the stack so to speak. So let this function return false, then in the caller, if false, window.location(history(-1)). Functions DO increment the stack, so the parser might wait until all calls finish before "closing off" that stack level.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top