Chrome Extension with Database API interface

对着背影说爱祢 提交于 2019-12-13 08:11:49

问题


I want to update a div with a list of anchors that I generate from a local database in chrome. It's pretty simple stuff, but as soon as I try to add the data to the main.js file via a callback everything suddenly becomes undefined. Or the array length is set to 0. ( When it's really 18. )

Initially, I tried to install it into a new array and pass it back that way.

Is there a setting that I need to specify in the chrome manifest.json in order to allow for communication with the database API? I've checked, but all I've been able to find was 'unlimited storage'

The code is as follows:

    window.main = {};
window.main.classes = {};
(function(awe){
    awe.Data = function(opts){
      opts = opts || new Object();
      return this.init(opts);
    };
    awe.Data.prototype = {
        init:function(opts){
            var self = this;
            self.modified = true;

            var db = self.db = openDatabase("buddy","1.0","LocalDatabase",200000);
            db.transaction(function(tx){
                tx.executeSql("CREATE TABLE IF NOT EXISTS listing ( name TEXT UNIQUE, url TEXT UNIQUE)",[],function(tx,rs){
                    $.each(window.rr,function(index,item){
                        var i = "INSERT INTO listing (name,url)VALUES('"+item.name+"','"+item.url+"')";
                        tx.executeSql(i,[],null,null);
                    });
                },function(tx,error){

                });
            });
            self._load()
            return this;
        },
        add:function(item){
            var self = this;
            self.modified = true;
            self.db.transaction(function(tx){
                tx.executeSql("INSERT INTO listing (name,url)VALUES(?,?)",[item.name,item.url],function(tx,rs){
                    //console.log('success',tx,rs)
                },function(tx,error){
                    //console.log('error',error)
                })
            });
            self._load()
        },
        remove:function(item){
            var self = this;
            self.modified = true;
            self.db.transaction(function(tx){
                tx.executeSql("DELETE FROM listing where name='"+item.name+"'",[],function(tx,rs){
                    //console.log('success',tx,rs)
                },function(tx,error){
                    //console.log('error',tx,error);
                });
            });
            self._load()
        },
        _load:function(callback){
            var self = this;
            if(!self.modified)
                return;
            self.data = new Array();
            self.db.transaction(function(tx){
                tx.executeSql('SELECT name,url FROM listing',[],function(tx,rs){
                    console.log(callback)
                    for(var i = 0; i<rs.rows.length;i++)
                    {

                        callback(rs.rows.item(i).name,rs.rows.item(i).url)
                        // var row = rs.rows.item(i)
                        // var n = new Object()
                        // n['name'] = row['name'];
                        // n['url'] = row['url'];
                    }
                },function(tx,error){
                    //console.log('error',tx,error)
                })
            })
            self.modified = false
        },
        all:function(cb){
            this._load(cb)
        },
        toString:function(){
            return 'main.Database'
        }
    }
})(window.main.classes);

And the code to update the list.

this.database.all(function(name,url){
       console.log('name','url')
       console.log(name,url)

       var data = []
       $.each(data,function(index,item){
           try{
               var node = $('<div > <a href="'+item.url+'">'+item.name + '</a></div>');
               self.content.append(node);
               node.unbind();
               node.bind('click',function(evt){
                   var t = $(evt.target).attr('href');
                   chrome.tabs.create({
                       "url":t
                   },function(evt){
                       self._tab_index = evt.index
                   });
               });
           }catch(e){
               console.log(e)
           }
       })    
   });

回答1:


From looking at your code above, I notice you are executing "self._load()" at the end of each function in your API. The HTML5 SQL Database is asynchronous, you can never guarantee the result. In this case, I would assume the result will always be 0 or random because it will be a race condition.

I have done something similar in my fb-exporter extension, feel free to see how I have done it https://github.com/mohamedmansour/fb-exporter/blob/master/js/database.js

To solve a problem like this, did you check the Web Inspector and see if any errors occurs in the background page. I assume this is all in a background page eh? Try to see if any error occurs, if not, I believe your encountering a race condition. Just move the load within the callback and it should properly call the load.

Regarding your first question with the unlimited storage manifest attribute, you don't need it for this case, that shouldn't be the issue. The limit of web databases is 5MB (last I recall, it might have changed), if your using a lot of data manipulation, then you use that attribute.

Just make sure you can guarantee the this.database.all is running after the database has been initialized.



来源:https://stackoverflow.com/questions/6500869/chrome-extension-with-database-api-interface

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!