[JS] HTML5 opendatabase + jqTouch

Pagina: 1
Acties:

Onderwerpen


  • Svennetjee
  • Registratie: December 2007
  • Laatst online: 30-08 12:32
Hallo,

Ik ben de laatste tijd bezig een eerste webapp te maken met jqTouch icm de HTML5 openDatabase. Nu heb ik daar een erg handige plugin voor gevonden, jQTouch HTML5 database api extension, maar het wil allemaal niet lekker werken.

Wat is het probleem? Ik roep de database aan in een functie:

JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
function initDB() {

    $.post('../php/actions/prepareDB.php', function(data) {
        
        [..]

            jQT.dbOpen('order_webapp', '1.0', 'WebApp Database', 200000);
            
            jQT.dbDropTable("webapp_products");
            jQT.dbCreateTables({ "createTables":
                [
                    {'table': 'webapp_products', 'property': [
                        {'name': 'productID', 'type': 'INTEGER PRIMARY KEY'},
                        {'name': 'productName', 'type': 'TEXT'},
                        {'name': 'productPrice', 'type': 'DECIMAL(6,2)'},
                        {'name': 'productPriceFmt', 'type': 'TEXT'}
                    ]},
                    {'table': 'webapp_shoppingCart', 'property': [
                        {'name': 'productID', 'type': 'INTEGER PRIMARY KEY'},
                        {'name': 'number', 'type': 'TINYINT'}
                    ]}
                ]
            });
            
            jQT.dbInsertRows(JSON.parse(data));
            jQT.dbInsertRows({ "addRow": 
                [
                    {'table': 'webapp_shoppingCart', 'property': [
                        {'name': 'productID', 'value': '5' },
                        {'name': 'number', 'value': '3' }
                    ]}
                ]
            });
            
        [..]
        
    });
    
}
    
initDB();


(weggehaalde code is slechts check voor goed ontvangen van data via AJAX)

Dit gaat allemaal goed, de initialisatie, het maken van de tabellen en het invoegen van de benodigde data verloopt vlekkeloos.

Echter, als ik ergens buiten die functie data wil ophalen uit mijn database, bijvoorbeeld zo:

JavaScript:
1
2
3
4
5
6
7
    function getData() {
        jQT.dbSelectAll('webapp_products', function(data){
            console.log(data);
        });
    }

getData();


Dan verschijnt de volgende foutmelding op mijn scherm:

TypeError: Result of expression 'db' [undefined] is not an object.

Het lijkt me een probleem met de scope van de interne 'db' variabele, of iets met jQT. De enige manier waarop de functie dbSelectAll (of een andere willekeurige query) werkt is namelijk binnen de functie initDB().

Kan iemand mij vertellen wat ik fout doe?

BVD:)

  • Bosmonster
  • Registratie: Juni 2001
  • Laatst online: 10-09 08:45
die jQT variabele, is die wel toegankelijk buiten je initDB() functie?

Acties:
  • 0 Henk 'm!

  • Svennetjee
  • Registratie: December 2007
  • Laatst online: 30-08 12:32
Bosmonster schreef op donderdag 24 februari 2011 @ 23:09:
die jQT variabele, is die wel toegankelijk buiten je initDB() functie?
Ja, die wordt namelijk uit buiten mijn functie (buiten het script zelfs, op de pagina zelf voordat het script wordt ingesloten) gedefinieerd, dus is die net zo goed in de initDB() functie als in een willekeurige andere beschikbaar ;)

Het zit hem in het feit dat de database extensie een variabele voor de database (intern) aanmaakt, die op de een of andere manier niet de juiste scope heeft (imho)..

Acties:
  • 0 Henk 'm!

  • mithras
  • Registratie: Maart 2003
  • Niet online
Als je al bijna zeker weet dat het aan jQTouch ligt, heb je dit al aan de makers gevraagd :?

Acties:
  • 0 Henk 'm!

  • Svennetjee
  • Registratie: December 2007
  • Laatst online: 30-08 12:32
mithras schreef op vrijdag 25 februari 2011 @ 07:52:
Als je al bijna zeker weet dat het aan jQTouch ligt, heb je dit al aan de makers gevraagd :?
Ik weet zeker dat het niet aan de makers ligt :P
Ik weet (bijna) zeker dat het aan de database extensie ligt, dus vanmiddag ga ik het even proberen zonder die extensie/wrapper, kijken of het dan wel lukt :)

Acties:
  • 0 Henk 'm!

  • mithras
  • Registratie: Maart 2003
  • Niet online
Svennetjee schreef op vrijdag 25 februari 2011 @ 08:00:
[...]


Ik weet zeker dat het niet aan de makers ligt :P
Ik weet (bijna) zeker dat het aan de database extensie ligt, dus vanmiddag ga ik het even proberen zonder die extensie/wrapper, kijken of het dan wel lukt :)
Ah, de database functies zijn een extensie van de bestaande jQTouch code :)

Ik heb even de code doorgespit, maar in dbExecuteQuery(stringQuery,debugTxtRaw,fn) wordt een variabele db gebruikt die wordt gedefinieerd op dit moment (bovenin file):

JavaScript:
1
2
3
4
5
6
7
8
(function($) {
    if ($.jQTouch)
    {
        $.jQTouch.addExtension(function Counter(jQTouch){
          // hier code met db definitie
        }
    }
}


Je zal even moeten debuggen wat daar precies gebeurt en waarom uiteindelijk db niet wordt aangemaakt :)

Acties:
  • 0 Henk 'm!

  • Bosmonster
  • Registratie: Juni 2001
  • Laatst online: 10-09 08:45
Wanneer roep je die getData precies aan? Aangezien je DB-connectie asynchroon wordt aangemaakt. initDB() en getData() achter elkaar aanroepen gaat fouten opleveren dan natuurlijk.

Acties:
  • 0 Henk 'm!

  • Svennetjee
  • Registratie: December 2007
  • Laatst online: 30-08 12:32
mithras schreef op vrijdag 25 februari 2011 @ 08:14:
[...]

Je zal even moeten debuggen wat daar precies gebeurt en waarom uiteindelijk db niet wordt aangemaakt :)
Bosmonster schreef op vrijdag 25 februari 2011 @ 10:13:
Wanneer roep je die getData precies aan? Aangezien je DB-connectie asynchroon wordt aangemaakt. initDB() en getData() achter elkaar aanroepen gaat fouten opleveren dan natuurlijk.
Dat is dus het probleem. Ik wil die gegevens opvragen terwijl het script nog bezig is de database aan te maken. Net even snel een testje gedaan door getData pas na 5 sec aan te roepen, en dat werkte prima.

De vraag is nu: hoe kom ik er achter of de database al ready is? De database variable (db) uit de extentie is niet toegankelijk in mijn script, is er iets van een openDatabase.ready() iets die dat kan checken?

Alvast heel erg bedankt mithras en Bosmonster! ;)

Acties:
  • 0 Henk 'm!

  • mithras
  • Registratie: Maart 2003
  • Niet online
Even geprobeerd wat documentatie van de openDatabase() op te zoeken, maar er is nog weinig over te vinden helaas.

Een ugly hack zou kunnen zijn dat je in een loop om de x miliseconden checked of db niet meer null is en vervolgens uit de loop stapt. Dat stop je in een aparte call en wanneer je meer weet over mogelijke callbacks kan je dat eenvoudig vervangen.

Acties:
  • 0 Henk 'm!

  • Svennetjee
  • Registratie: December 2007
  • Laatst online: 30-08 12:32
mithras schreef op vrijdag 25 februari 2011 @ 17:21:
Even geprobeerd wat documentatie van de openDatabase() op te zoeken, maar er is nog weinig over te vinden helaas.

Een ugly hack zou kunnen zijn dat je in een loop om de x miliseconden checked of db niet meer null is en vervolgens uit de loop stapt. Dat stop je in een aparte call en wanneer je meer weet over mogelijke callbacks kan je dat eenvoudig vervangen.
Jep was er net even naar aan het zoeken. Ik ga eens opzoeken of ik niet iets in elkaar kan vogelen dat, bijv. net als zo'n ajax call, pas code uitvoert als het resultaat binnen is. Als ik daar gewoon de rest van de code in zet moet het probleem ook opgelost zijn toch?

Acties:
  • 0 Henk 'm!

  • Raymond P
  • Registratie: September 2006
  • Laatst online: 22:46
Misschien dat ik ergens overheen kijk, maar getData als callback van $.post is niet wat je wilt?

- knip -


Acties:
  • 0 Henk 'm!

  • Svennetjee
  • Registratie: December 2007
  • Laatst online: 30-08 12:32
Raymond P schreef op vrijdag 25 februari 2011 @ 17:49:
Misschien dat ik ergens overheen kijk, maar getData als callback van $.post is niet wat je wilt?
In principe wel, maar dat wil ik graag op een ander moment doen (bijv. als er op een link wordt geklikt), en niet gelijk als de database wordt aangemaakt ;)

Acties:
  • 0 Henk 'm!

  • Tharulerz
  • Registratie: April 2009
  • Laatst online: 10-04 05:16
Als ik je probleem goed begrijp dan kan je gewoon een callback definieren die een boolean set dat de database aangemaakt is, en in je getData eerst checken of die boolean geset is?

Acties:
  • 0 Henk 'm!

  • Svennetjee
  • Registratie: December 2007
  • Laatst online: 30-08 12:32
Tharulerz schreef op vrijdag 25 februari 2011 @ 18:29:
Als ik je probleem goed begrijp dan kan je gewoon een callback definieren die een boolean set dat de database aangemaakt is, en in je getData eerst checken of die boolean geset is?
Klopt, punt is alleen dat als de database nog niet klaar is, de functie niet wordt uitgevoerd, terwijl die juist moet wachten tot de database dan klaar is dan en dan alsnog de functie uitvoeren ;) En setTimeout vind ik niet zo netjes

Acties:
  • 0 Henk 'm!

  • Raymond P
  • Registratie: September 2006
  • Laatst online: 22:46
Svennetjee schreef op vrijdag 25 februari 2011 @ 18:25:
[...]


In principe wel, maar dat wil ik graag op een ander moment doen (bijv. als er op een link wordt geklikt), en niet gelijk als de database wordt aangemaakt ;)
Ah, vrij simpel op te lossen dan.
In plaats van timeouts te gebruiken wat mithras aangeeft kan je het andersom doen.
JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
var dbReady = false;
var dbCalled = false;

    function initDB() { 
        dbReady = false;
        $.post({
            [...]
            dbReady = true;
            dataRequested();
        }),
    }
    
    function dataRequested(){
        if(dbCalled === true){
            getData();
        }
    }
    
    function getData(){
        if(dbReady === false){
            dbCalled = true;
            return;
        }
        
        [...]
        dbCalled = false;
    }


Minder smerig dan loopen ;)

Edit: dbReady weer op false mocht je de functie meerdere malen gebruiken.

[ Voor 6% gewijzigd door Raymond P op 25-02-2011 18:50 ]

- knip -


Acties:
  • 0 Henk 'm!

  • Svennetjee
  • Registratie: December 2007
  • Laatst online: 30-08 12:32
Mijn dank is groot, slimme oplossing! Heb het net eventjes snel toegepast en werkt prima!
O+

Acties:
  • 0 Henk 'm!

  • mithras
  • Registratie: Maart 2003
  • Niet online
Raymond P schreef op vrijdag 25 februari 2011 @ 18:46:
[...]


Ah, vrij simpel op te lossen dan.
In plaats van timeouts te gebruiken wat mithras aangeeft kan je het andersom doen.
JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
var dbReady = false;
var dbCalled = false;

    function initDB() { 
        dbReady = false;
        $.post({
            [...]
            dbReady = true;
            dataRequested();
        }),
    }
    
    function dataRequested(){
        if(dbCalled === true){
            getData();
        }
    }
    
    function getData(){
        if(dbReady === false){
            dbCalled = true;
            return;
        }
        
        [...]
        dbCalled = false;
    }


Minder smerig dan loopen ;)

Edit: dbReady weer op false mocht je de functie meerdere malen gebruiken.
Denk wel dat je zelf constant moet kijken of getData() wel gelukt is. Wat als je het te snel doet en de db nog niet klaar is? Moet je alsnog wachten en het a) loopen of b) in een queue zetten voor latere afhandeling.

Het ging mij er juist om dat je een callback kan creëren (ja, wel heel vies, dat snap ik) waarbij je omliggende code geen last heeft van wachten, controles etc. Nu moet je dat overal en altijd inbouwen en een fallback mechanisme maken wat er gebeurt wanneer het nog niet gereed is.

Acties:
  • 0 Henk 'm!

  • Svennetjee
  • Registratie: December 2007
  • Laatst online: 30-08 12:32
mithras schreef op zaterdag 26 februari 2011 @ 09:43:
[...]
Denk wel dat je zelf constant moet kijken of getData() wel gelukt is. Wat als je het te snel doet en de db nog niet klaar is? Moet je alsnog wachten en het a) loopen of b) in een queue zetten voor latere afhandeling.

Het ging mij er juist om dat je een callback kan creëren (ja, wel heel vies, dat snap ik) waarbij je omliggende code geen last heeft van wachten, controles etc. Nu moet je dat overal en altijd inbouwen en een fallback mechanisme maken wat er gebeurt wanneer het nog niet gereed is.
Ik heb het nu zelf iets anders aangepakt. In plaats van voor elke functie zo'n check te bouwen, en als de database nog niet bestaat hem in de queue te zetten, wrap ik gewoon een functie om alle code die eerst checkt of de database al wel geladen is. Goed. het script moet even wachten, maar de database is zo'n vitaal onderdeed van de applicatie dat dit meer een voordeel is dan een nadeel ;)

Acties:
  • 0 Henk 'm!

  • Raymond P
  • Registratie: September 2006
  • Laatst online: 22:46
mithras schreef op zaterdag 26 februari 2011 @ 09:43:
[...]
Denk wel dat je zelf constant moet kijken of getData() wel gelukt is. Wat als je het te snel doet en de db nog niet klaar is? Moet je alsnog wachten en het a) loopen of b) in een queue zetten voor latere afhandeling.

Het ging mij er juist om dat je een callback kan creëren (ja, wel heel vies, dat snap ik) waarbij je omliggende code geen last heeft van wachten, controles etc. Nu moet je dat overal en altijd inbouwen en een fallback mechanisme maken wat er gebeurt wanneer het nog niet gereed is.
Daar is de extra functie dataRequested() voor, een eventuele fallback bouw je hier in. Het heeft in deze situatie wat overhead, omdat je simpelweg de boolean ook direct kan checken.

Ik gebruik zelf een soortgelijke constructie om m'n AJAX calls waar de callback een array checkt op pending requests, wat logica uitvoert, requests eventueel bundelt en cached results terug geeft wanneer mogelijk. Werkt goed.
De rest van de code zal niet hoeven te wachten, loopt gewoon asynchroon en callt zelf de functies die nodig zijn. Imho zou je gehele requests die failen al opgevangen moeten hebben lang voordat je dit punt bereikt.
Je zou zelfs nog de booleans + logica uit getData() weg kunnen halen en het in initDB() zetten, zo zou je er verder in je code helemaal niets mee te maken hebben en wordt dat automatisch opgevangen.

Ff voor de duidelijkheid: het is een tijdje geleden dat ik jQuery gebruikt heb. Wellicht is er een simpelere oplossing, maar ben blij dat 'k iig een beetje heb kunnen helpen.

- knip -

Pagina: 1