javascript for-loop in SQLite query - Stack Overflow

I have created a function that will return the string "path" from my DB.function getAudio(mid

I have created a function that will return the string "path" from my DB.

    function getAudio(mid, cb) {
    //mid is an array containing the id to some multimedia files.
    for(i=0; i < mid.length; i++) {

        db.transaction(function(tx) {
                tx.executeSql('SELECT * FROM Multimedia WHERE Mid=' + mid[i] + ' AND Type=' + 2, [], function(tx, results) {    
                //type=2 is audio. (type=1 is picture file etc) There is only one audiofile in the array.
                    if(results.rows.length > 0) {
                        path = results.rows.item(0).Path; 
                        cb(path);
                    }
                }, errorCB);
        }, errorCBQuery);

    }//end for
}//end getAudio()

When I remove the for-loop, the query is successfull, when the for-loops is there, errorCBQuery or errorCB is called.

Any Ideas on how to fix this? Thanks :)

I have created a function that will return the string "path" from my DB.

    function getAudio(mid, cb) {
    //mid is an array containing the id to some multimedia files.
    for(i=0; i < mid.length; i++) {

        db.transaction(function(tx) {
                tx.executeSql('SELECT * FROM Multimedia WHERE Mid=' + mid[i] + ' AND Type=' + 2, [], function(tx, results) {    
                //type=2 is audio. (type=1 is picture file etc) There is only one audiofile in the array.
                    if(results.rows.length > 0) {
                        path = results.rows.item(0).Path; 
                        cb(path);
                    }
                }, errorCB);
        }, errorCBQuery);

    }//end for
}//end getAudio()

When I remove the for-loop, the query is successfull, when the for-loops is there, errorCBQuery or errorCB is called.

Any Ideas on how to fix this? Thanks :)

Share edited Mar 26, 2012 at 11:56 TorK asked Mar 26, 2012 at 11:32 TorKTorK 692 silver badges9 bronze badges 3
  • lol that is just a typo :p there has been plenty of removing and adding code the last hour. My bad :) – TorK Commented Mar 26, 2012 at 11:40
  • @T.J.Crowder ok, thanks for notifying me about that. edited :) – TorK Commented Mar 26, 2012 at 11:57
  • You should use parameterized sql instead of using string concatenation, in order to protect yourself from SQL injection. Given the array argument you passed I guess it would look something like tx.executeSql('SELECT * FROM Multimedia WHERE Mid=? AND Type=?', [mid[i], 2]. – hugomg Commented Mar 26, 2012 at 13:09
Add a ment  | 

1 Answer 1

Reset to default 7

This is the classic closure problem. transaction is an asynchronous call, which means your loop pletes before the function you pass in is triggered. The function has an enduring reference to the i variable, not a copy of it as of when you called transaction. So each of those functions (you're generating one on each loop) is seeing i == mid.length and thus mid[i] is undefined and your SQL gets messed up.

What you need to do is have the callbacks close over another variable that won't change when the loop proceeds. The usual way to do that is to use a factory function:

function getAudio(mid, cb) {
    //mid is an array containing the id to some multimedia files.
    for(i=0; i < mid.length; i++) {

        db.transaction(makeTx(mid[i]), errorCBQuery);

    }//end for

    function makeTx(val) {
        return function(tx) {
            tx.executeSql('SELECT * FROM Multimedia WHERE Mid=' + val + ' AND Type=' + 2, [], function(tx, results) {    
            //type=2 is audio. (type=1 is picture file etc) There is only one audiofile in the array.
                if(results.rows.length > 0) {
                    path = results.rows.item(0).Path; 
                    cb(path);
                }
            }, errorCB);
        };
    }

}//end getAudio()

There, I'm passing mid[i] into the makeTx function, which returns the function that will get passed into transaction. The function we return closes over the val argument for the call to makeTx that created it, which doesn't change.

That's a minimal rewrite of the code; you can probably take it further. For example, see missingno's ment on the question re parameterized statements.


Side note: It doesn't look like you declare i or path anywhere. If that's really true, you're falling prey to The Horror of Implicit Globals. Remend declaring them.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744922816a4601241.html

相关推荐

  • javascript for-loop in SQLite query - Stack Overflow

    I have created a function that will return the string "path" from my DB.function getAudio(mid

    1天前
    30

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信