Web SQL Database + Javascript loop
Asked Answered
C

2

7

I'm trying to figure this out but can't seem to on my own...
I'm playing with Web SQL DBs and I can't get a loop to work properly with it.
I use:

for (var i=0; i<=numberofArticles-1; i++){  
    db.transaction(function (tx) {  
    tx.executeSql('INSERT INTO LOGS (articleID) VALUES (?)',  [i]);
  });
 };

And I get only 5's.. I don't get the incremental i values.
Can anyone suggestion what I'm doing wrong and what I should be thinking about?

Cinderella answered 28/1, 2011 at 6:18 Comment(0)
A
6

It looks like the function is asynchronous, and that by the time tx.executeSql fires, the loop have finished looping and i has been changed several times.

You can solve this with a closure.

for (var i=0; i<=numberofArticles-1; i++){ 
    function (value) { 
        db.transaction(function (tx) {  
        tx.executeSql('INSERT INTO LOGS (articleID) VALUES (?)',  [value]);
      });
    }(i); // <-- CALL the function
 };
Almeda answered 28/1, 2011 at 6:52 Comment(5)
@David Dorward Could you please explain a little the sintax (the javascript not the websql)? Especially the line " }(i); // <-- CALL the function". I mean, i could just copy the code, but i'd like to fully understand it.Ovolo
You call a function by sticking (any args) on the end of it. function (){}() is just like function foo() {}; foo(); except it doesn't keep foo around for later use.Almeda
(and since variables are local to a specific function call, having a new function call each time around the loop makes new local variables)Almeda
one last thing, shouldn't the argument for the insert be "[value]" instead of "[i]"?Ovolo
That is incorrect. The argument for the function should be i, but the argument for the insert should be value - the code as written works only by coincidenceTehee
M
11

Do it the other way around:

<script>
    numberofArticles = 5;
    db = openDatabase("websql", "0.1", "web-sql testing", 10000);
    db.transaction(function(tx) {
        tx.executeSql('CREATE TABLE IF NOT EXISTS LOGS (id unique, articleID int)');
    });
    db.transaction(function (tx) {  
        for (var i=0; i<=numberofArticles-1; i++){  
            tx.executeSql('INSERT INTO LOGS (articleID) VALUES (?)',  [i]);
        };
    });
</script>

And the alternative, the proper way with the loop outside which is unnecessary in this case

    for (var i=0; i<=numberofArticles-1; i++){  
      (function(i) {
        db.transaction(function (tx) {  
                tx.executeSql('INSERT INTO LOGS (articleID) VALUES (?)',  [i]);
        });
      })(i);
    };
Montreal answered 28/1, 2011 at 6:50 Comment(0)
A
6

It looks like the function is asynchronous, and that by the time tx.executeSql fires, the loop have finished looping and i has been changed several times.

You can solve this with a closure.

for (var i=0; i<=numberofArticles-1; i++){ 
    function (value) { 
        db.transaction(function (tx) {  
        tx.executeSql('INSERT INTO LOGS (articleID) VALUES (?)',  [value]);
      });
    }(i); // <-- CALL the function
 };
Almeda answered 28/1, 2011 at 6:52 Comment(5)
@David Dorward Could you please explain a little the sintax (the javascript not the websql)? Especially the line " }(i); // <-- CALL the function". I mean, i could just copy the code, but i'd like to fully understand it.Ovolo
You call a function by sticking (any args) on the end of it. function (){}() is just like function foo() {}; foo(); except it doesn't keep foo around for later use.Almeda
(and since variables are local to a specific function call, having a new function call each time around the loop makes new local variables)Almeda
one last thing, shouldn't the argument for the insert be "[value]" instead of "[i]"?Ovolo
That is incorrect. The argument for the function should be i, but the argument for the insert should be value - the code as written works only by coincidenceTehee

© 2022 - 2024 — McMap. All rights reserved.