1

Here is a for loop written by Javascript. It is trying to apply queries for websql.

for (var i = 0; i < 10; i++){
 db.transaction(function (tx){
 tx.executeSql('INSERT INTO ProjSetsT (ProjID) VALUES (?);', [i]);
 });
}

The attempt is obvious, I tried to add values "0, 1, 2, ... 9" into column ProjID in table ProjSetsT. It does not work. I only got the last element, i.e. "9" inserted, but not the first eight numbers.

Is there any syntax mistakes?

asked Sep 25, 2012 at 15:36
2
  • 2
    Syntax mistakes would prevent it from running outright... WebSQL is an asynchronous API, you can't expect it to catch the right values this way. See Web SQL Database + Javascript loop. Also, running multiple queries in one transaction is faster and actually guarantees the insertion order. Running each one in a separate transaction is a slow free-for-all with random ordering. Commented Sep 25, 2012 at 15:38
  • 1
    Why not make one query? Where the value binded is a string built from the values in the for loop. Commented Sep 25, 2012 at 15:39

3 Answers 3

4

I think db.transaction might run asynchronously so that might be messing it up for you. Have you tried to move your for loop inside the transaction?

db.transaction(function (tx){
 for (var i = 0; i < 10; i++){
 tx.executeSql('INSERT INTO ProjSetsT (ProjID) VALUES (?);', [i]);
 }
});
answered Sep 25, 2012 at 15:38
Sign up to request clarification or add additional context in comments.

1 Comment

You are right. And I think this is the most straight forward method to do it though other people's advices all work. That's why I put yours as the answer.
2

Every function you pass as an argument shares the same reference to i, so every new function object's i value gets incremented. given the async context, i will have reached its max size before the first function you create inside the loop gets called

You can fix it using a closure:

for (var i = 0; i < 10; i++)
{
 db.transaction((function(privateI)
 {//privateI is unique for every function object
 return function (tx)
 {
 tx.executeSql('INSERT INTO ProjSetsT (ProjID) VALUES (?);', [privateI]);
 };
 })(i));//pass current value here
}
answered Sep 25, 2012 at 15:40

Comments

1

You have several functions referencing the same i variable, which ends up as 10.

You need a new varible scope for each function.

for (var i = 0; i < 10; i++){
 db.transaction(makeHandler(i));
}
function makeHandler(j) {
 return function (tx){
 tx.executeSql('INSERT INTO ProjSetsT (ProjID) VALUES (?);', [j]);
 };
}

Now i is passed to makeHandler, which receives it as j.

Every time makeHandler is called, it returns a function that references its own local j varaible.

answered Sep 25, 2012 at 15:38

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.