Go Back   CodingForums.com > :: Client side development > JavaScript programming

Before you post, read our: Rules & Posting Guidelines

Reply
 
Thread Tools Rate Thread
Enjoy an ad free experience by logging in. Not a member yet? Register.
Old 03-05-2012, 08:46 AM   PM User | #1
Publicus
New to the CF scene

 
Join Date: Mar 2012
Posts: 5
Thanks: 0
Thanked 0 Times in 0 Posts
Publicus is an unknown quantity at this point
Angry Clientside database and return from function

Yesterday I started looking into clientside database handling with html5 and localstorage. I've been trying for hours to make a function like the one below, but I can't figure out how to return the name variable. Any ideas?

Code:
function hent_kontakt_navn(var1, var2) {
	var db = MYDB;
	db.transaction(function (tx) {
	   tx.executeSql('SELECT * FROM db_kontakter WHERE field1=\'' + var1 + '\' AND field2=\'' + var2 + '\' LIMIT 1', [], function (tx, results) {
	   var len = results.rows.length, i;
	   for (i = 0; i < len; i++){
	      var fornavn = results.rows.item(i).fornavn;
	      var etternavn = results.rows.item(i).etternavn;
	      var navn = fornavn + ' ' + etternavn;
alert(navn); //This works and alerts the correct value
	   }
	 }, null);
	});
	return navn; //But this one returns undefined. I know variables don't pass like this between functions, but how can I make it work so that the function returns this var?
}
Publicus is offline   Reply With Quote
Old 03-05-2012, 10:47 AM   PM User | #2
Philip M
Supreme Master coder!

 
Philip M's Avatar
 
Join Date: Jun 2002
Location: London, England
Posts: 17,032
Thanks: 197
Thanked 2,410 Times in 2,388 Posts
Philip M has a spectacular aura aboutPhilip M has a spectacular aura aboutPhilip M has a spectacular aura about
The variable navn declared with the var keyword is local to your anonymous function. Delete the var keyword to make it global scope.

All advice is supplied packaged by intellectual weight, and not by volume. Contents may settle slightly in transit.
__________________

All the code given in this post has been tested and is intended to address the question asked.
Unless stated otherwise it is not just a demonstration.
Philip M is offline   Reply With Quote
Old 03-05-2012, 12:25 PM   PM User | #3
webdev1958
Banned

 
Join Date: Apr 2011
Posts: 656
Thanks: 14
Thanked 69 Times in 69 Posts
webdev1958 can only hope to improve
try

Code:
return db.navn
webdev1958 is offline   Reply With Quote
Old 03-06-2012, 12:30 PM   PM User | #4
Publicus
New to the CF scene

 
Join Date: Mar 2012
Posts: 5
Thanks: 0
Thanked 0 Times in 0 Posts
Publicus is an unknown quantity at this point
Thanks - I tried both but none of them are working. When using db.navn it returns "undefined".
Publicus is offline   Reply With Quote
Old 03-06-2012, 03:39 PM   PM User | #5
blaze4218
Regular Coder

 
Join Date: Apr 2005
Location: Texas
Posts: 448
Thanks: 24
Thanked 63 Times in 63 Posts
blaze4218 is an unknown quantity at this point
In order to make your variable global you should declare it outside of an anonymous function

Code:
function hent_kontakt_navn(var1, var2) {
	var db = MYDB , navn;  // Not global, but I think this is what you want 
	db.transaction(function (tx) {
	   tx.executeSql('SELECT * FROM db_kontakter WHERE field1=\'' + var1 + '\' AND field2=\'' + var2 + '\' LIMIT 1', [], function (tx, results) {
	   var len = results.rows.length, i;
	   for (i = 0; i < len; i++){
	      var fornavn = results.rows.item(i).fornavn;
	      var etternavn = results.rows.item(i).etternavn;
	      navn = fornavn + ' ' + etternavn;
alert(navn); //This works and alerts the correct value
	   }
	 }, null);
	});
	return navn; //But this one returns undefined. I know variables don't pass like this between functions, but how can I make it work so that the function returns this var?
}
__________________
Allwisend bin ich nicht, doch viel ist mir bewursst
-Goethe
blaze4218 is offline   Reply With Quote
Old 03-06-2012, 11:53 PM   PM User | #6
Publicus
New to the CF scene

 
Join Date: Mar 2012
Posts: 5
Thanks: 0
Thanked 0 Times in 0 Posts
Publicus is an unknown quantity at this point
Thanks again - I tried but still the variable navn is undefined. I've been searching around and I cannot find a way to make a variable set inside a function be available outside it.

So then the question is: How can I transfer this value (navn) so that it's returned like I want in the script?
Publicus is offline   Reply With Quote
Old 03-07-2012, 02:37 PM   PM User | #7
blaze4218
Regular Coder

 
Join Date: Apr 2005
Location: Texas
Posts: 448
Thanks: 24
Thanked 63 Times in 63 Posts
blaze4218 is an unknown quantity at this point
Quote:
Originally Posted by Publicus View Post
I've been searching around and I cannot find a way to make a variable set inside a function be available outside it.
That's because you can't. You are on the right track: you are returning the variable from the function. I wonder though, are you storing the returned value?

Does your code look like this
Code:
function hent_kontakt_navn(var1, var2) {
	var db = MYDB , navn;
	db.transaction(function (tx) {
	   tx.executeSql('SELECT * FROM db_kontakter WHERE field1=\'' + var1 + '\' AND field2=\'' + var2 + '\' LIMIT 1', [], function (tx, results) {
	   var len = results.rows.length, i;
	   for (i = 0; i < len; i++){
	      var fornavn = results.rows.item(i).fornavn;
	      var etternavn = results.rows.item(i).etternavn;
	          navn = fornavn + ' ' + etternavn;
alert(navn); //This works and alerts the correct value
	   }
	 }, null);
	});
	return navn; //But this one returns undefined. I know variables don't pass like this between functions, but how can I make it work so that the function returns this var?
}
alert(navn) //this won't work
or does your code look like this
Code:
function hent_kontakt_navn(var1, var2) {
	var db = MYDB , navn;
	db.transaction(function (tx) {
	   tx.executeSql('SELECT * FROM db_kontakter WHERE field1=\'' + var1 + '\' AND field2=\'' + var2 + '\' LIMIT 1', [], function (tx, results) {
	   var len = results.rows.length, i;
	   for (i = 0; i < len; i++){
	      var fornavn = results.rows.item(i).fornavn;
	      var etternavn = results.rows.item(i).etternavn;
	          navn = fornavn + ' ' + etternavn;
alert(navn); //This works and alerts the correct value
	   }
	 }, null);
	});
	return navn; //But this one returns undefined. I know variables don't pass like this between functions, but how can I make it work so that the function returns this var?
}
otherNavn = function hent_kontakt_navn(val1, val2) // returning the value is not enough, you must now store it somewhere
alert(otherNavn) //this will show the returned value from the function
also, I would recommend storing an initial value of navn when you initialize it, and testing navn right before your return statement, so you can get a better idea of what value is where and when...

consider the following proof
Code:
function myFunc(userInput){
    var record = 5; // Just a base value to make sure we know what to expect.

    if (typeof userInput=='Number') {

        (function(){
            var unusableRecord = 5;  // this is not returned from the anonymous function, so we won't be able to access it anywhere but here (inside this function)

            record += userInput; // Now we changed the value of our record;

            alert(record); // If this doesn't alert we we don't expect the value of record to have changed...
        })();

    }

    try{
        alert(unusableRecord); // This will always be 'undefined' and thus fail
    }catch(e){
        alert('undefined');
    }
    
    alert(record);  // Whatever value this alerts is what we can expect to be returned from the function.

    return record; // Now we can use this outside of the function, but it is of no use if we don't assign it to a variable.
}

myFunc(2); // This will execute, and myFunc will return 7... but we don't store it, so its useless...

alert(myFunc(2) + 5);  // this will alert 12, but again... we don't store the value, so useless. (unless you only intend to inform the user of this arbitrary value...)

var newValForRecord = myFunc(prompt()); // Try this with user input, and try it without user input.

alert(newValForRecord);  // This will not be undefined
__________________
Allwisend bin ich nicht, doch viel ist mir bewursst
-Goethe
blaze4218 is offline   Reply With Quote
Old 03-07-2012, 08:24 PM   PM User | #8
felgall
Master Coder

 
felgall's Avatar
 
Join Date: Sep 2005
Location: Sydney, Australia
Posts: 5,447
Thanks: 0
Thanked 496 Times in 488 Posts
felgall is a jewel in the roughfelgall is a jewel in the roughfelgall is a jewel in the rough
You are aware that this particular API was abandoned back in November last year as no agreement could be reached on how any of it is supposed to work. Those few browsers that do support some of this code each have a different level of support and those that currently don't support it have no plans to support it until such time as it is completely rewritten to work the way they want it to (each with a completely different idea of what they want).

It took about 10 years for a two path split in the way JavaScript would go to be resolved (with ECMAScript 3.1 and ECMAScript 4 finally being abandoned in favour of the compromise ECMAScript 5) so a compromise on this API (where there are at least five or more different proposals) will probably take around 40 years to come up with a compromise acceptable to all parties.
__________________
Stephen
Learn Modern JavaScript - http://javascriptexample.net/
Helping others to solve their computer problem at http://www.felgall.com/
felgall is offline   Reply With Quote
Old 03-07-2012, 09:49 PM   PM User | #9
Publicus
New to the CF scene

 
Join Date: Mar 2012
Posts: 5
Thanks: 0
Thanked 0 Times in 0 Posts
Publicus is an unknown quantity at this point
blaze4218: I'm getting the return like you wrote in your second example.

Code:
otherNavn = function hent_kontakt_navn(val1, val2) // returning the value is not enough, you must now store it somewhere
alert(otherNavn) //this will show the returned value from the function
But still the navn variable isn't passed. I know it's because I don't understand how the function I'm using works. So how can I get the data out of there?
Publicus is offline   Reply With Quote
Old 03-07-2012, 10:12 PM   PM User | #10
blaze4218
Regular Coder

 
Join Date: Apr 2005
Location: Texas
Posts: 448
Thanks: 24
Thanked 63 Times in 63 Posts
blaze4218 is an unknown quantity at this point
I can't figure out how to test your code, that's why I gave you the detailed example on how to form the type of function you want.

Can you post your function as it appears now? or even better... do you have a link to a live example?
__________________
Allwisend bin ich nicht, doch viel ist mir bewursst
-Goethe
blaze4218 is offline   Reply With Quote
Old 03-08-2012, 11:37 AM   PM User | #11
Publicus
New to the CF scene

 
Join Date: Mar 2012
Posts: 5
Thanks: 0
Thanked 0 Times in 0 Posts
Publicus is an unknown quantity at this point
Thanks alot for your help! I have uploaded the script here: http://robinhavre.no/test/index.html

You see that everything works the way it's supposed to, except for this one function not returning the variable. The function is called on line 86 in script.js, and you find it on line 95.
Publicus is offline   Reply With Quote
Old 03-08-2012, 05:32 PM   PM User | #12
blaze4218
Regular Coder

 
Join Date: Apr 2005
Location: Texas
Posts: 448
Thanks: 24
Thanked 63 Times in 63 Posts
blaze4218 is an unknown quantity at this point
Ok, I see the problem. But the solution might be beyond my knowledge.

I inserted 2 additional alerts to see the flow of execution through the function:
Code:
    function hent_kontakt_navn(landskode, mobilnr) { //I WANT THIS FUNCTION TO RETURN THE STRING navn
        var db = DBTEST;
        var navn;

alert('starting anon funct')
        db.transaction(function (tx) {
            var connString = 'SELECT * FROM db_kontakter WHERE landskode="' + landskode + '" AND mobilnr="' + mobilnr + '" LIMIT 1';

            tx.executeSql(connString, [], function (tx, results) {
                var len = results.rows.length, i;

                for (var i = 0; i < len; i++){

                      var fornavn = results.rows.item(i).fornavn;
                      var etternavn = results.rows.item(i).etternavn;

                      navn = fornavn + ' ' + etternavn;

                      alert('Name that should be returned: ' + navn); //Works!
               }
            }, null);

	});
alert('finishing anon funct.\n navn equals : '+navn)

        return navn; //Doesn't work
    }
Here's what I observed:
The function hent_kontakt_navn() is called 4 times. Each time we receive an alert indicating that the anonymous function is starting followed by the alert that the anonymous function is finished. We do not receive any alerts from inside the anonymous function until after hent_kontakt_navn() has executed 4 times.

The way your code is structured, it appears as though you are executing the anonymous functions in the scope of hent_kontakt_nab(), so you would expect everything to occur in succession. I have refactored your code a bit so you can see what is actually happening here. The following 3 functions are identical to hent_kontakt_navn, and perform the same execution:

Code:
    function make_conn(tx) {
        var connString = 'SELECT * FROM db_kontakter WHERE landskode="' + landskode + '" AND mobilnr="' + mobilnr + '" LIMIT 1';

        tx.executeSql(connString, [], get_navn, null);

    }

    function get_navn(tx, results) {
        var len = results.rows.length, i;

        for (var i = 0; i < len; i++){

            var fornavn = results.rows.item(i).fornavn;
            var etternavn = results.rows.item(i).etternavn;

            var navn = fornavn + ' ' + etternavn;

            alert('Name that should be returned: ' + navn); //Works!
        }
        return navn; // This *might* help, if you could capture it's value in the scope we are returning to...
    }

    function hent_kontakt_navn(landskode, mobilnr) { //I WANT THIS FUNCTION TO RETURN THE STRING navn
        var db = DBTEST;
        var navn;
/* 
*if you were executing the mak_conn function you would have "make_conn()"
*but instead, you are actually passing the value of make_conn to db.transaction()
*so that it can be executed later in the scope of that function... So there really
*is no way to return the value executed in make_conn to this scope without a closure.
*the same is true of the line "tx.executeSql(connString, [], get_navn, null);" above.
*/
        db.transaction(make_conn);

        return navn; //Doesn't work
    }
Once I realized what the problem was, I was able to do a quick search and found this
getting a webkit executesql transaction to return a value
in which they also said you need a closure but they did not provide sample code to make it work. But
at least you can research the *right question* now
__________________
Allwisend bin ich nicht, doch viel ist mir bewursst
-Goethe
blaze4218 is offline   Reply With Quote
Reply

Bookmarks

Tags
clientside database, database, html5, sql, sqlite

Jump To Top of Thread


Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 11:46 AM.


Advertisement
Log in to turn off these ads.