www.webdeveloper.com
Results 1 to 10 of 10

Thread: Strange function issue

Hybrid View

  1. #1
    Join Date
    May 2013
    Posts
    5

    Strange function issue

    Hi there, i'm trying to get item from a local SQLITE db table:

    function getInfo(itemId) {

    var itemName = "defaultName";

    DEMODB.transaction(
    function (transaction) {
    transaction.executeSql("SELECT * FROM itemsTable where id=?", [itemId], function (transaction, results) {
    if (results.rows.length > 0) {
    for (var i = 0; i < results.rows.length; i++) {
    var row = results.rows.item(i);
    var newFeature = new Object();

    newFeature.getName = row['name'];

    itemName = newFeature.getName;
    alert(itemName);
    }
    }
    }, null);
    }
    );

    alert(itemName);
    }

    the inner alert is showing the correct content (row['name']) but the outer alert (after the loop) is showing the default VAR content. how can that be? isn't the itemName = newFeature.getName; needs to implement the "itemName" variant after the loop?

    What am i doing wrong?

    Thanks

  2. #2
    Join Date
    Mar 2009
    Posts
    467
    As far as I can see and guess its a scope problem.
    Code:
    var itemName = "defaultName";
    and
    Code:
    itemName = newFeature.getName;
    aren't the same variable, even though they have been given the same name. The first appears to be out of scope within the function that fires your inner alert.

  3. #3
    Join Date
    May 2013
    Posts
    5

    thanks but even if i declare it...

    Thank you for you answer.
    i tried to declare the variable as global (at the beginning of the JS file) but still the same problem.

    Another strange thing that probably got to do with this is that the second alert (outside the loop) is popping first, before the top one (inside the loop) even though the top one is before in the code.

    Am i missing something?

    Thanks

  4. #4
    Join Date
    Mar 2009
    Posts
    467
    Another strange thing that probably got to do with this is that the second alert (outside the loop) is popping first, before the top one (inside the loop) even though the top one is before in the code.
    Okay--

    It would appear that the function which queries the database is asynchronous. Its launched and the rest of the code continues executing the 'outer' alert before the DB query has been answered and processed.

    To test for this I would change the 'outer'
    Code:
    alert(itemName);
    to something like:

    Code:
    var zz = function(){alert(itemName);};
    setTimeout(zz, 1000);
    If you get the expected rather than the default answer you'll know that this is what's going on.

  5. #5
    Join Date
    May 2013
    Posts
    5

    Yes! now i get the correct info on the...

    Now i get the correct info on the 'outer' alert.
    Thanks man!

    But how do i prevent/disable the inner call to the database to be async?
    Can you direct me? please view my original code i posted here.

    Thanks

  6. #6
    Join Date
    Mar 2009
    Posts
    467
    But how do i prevent/disable the inner call to the database to be async?
    I'm not sure you can. You need to look at the DB documentation to see if you can do this. If you cannot the usual thing to do is to divide the function that uses an asynch call into two functions at the point just after the asych call, and invoke the second as the last portion of the callback function for the asych call. I know I'm not being very clear here but I will try. Imagine:

    Code:
    function One(){
    --block A -- does something such as parsing data
    --asych function with callback function 'function(){ alert("HI");}
    --block b --code that does some other task
    }
    If block b needs data which is retrieved by the asych function this is bad news. So we change this to two functions:

    Code:
    function Two(){
    -block A from above
    --asynch function --same as above BUT for one change to the callback function: 'function(){ alert("HI"); Three();}
    }
    
    function Three(){
    --block b  from above
    }
    This way block b will not run before the asych function has fully executed.
    I hope this makes sense.
    Last edited by Tcobb; 05-22-2013 at 12:26 PM.

  7. #7
    Join Date
    May 2013
    Posts
    5

    Sorry for that but still not working...can you guide?

    This is my code:

    function one(actionId) {
    DEMODB.transaction(
    function (transaction) {
    if (actionId != '0') {
    transaction.executeSql("SELECT id FROM mainTable where id=?", [actionId], getOne, errorHandler);
    }
    }
    );
    }

    function getOne(transaction, results) {
    var itemName = "";
    for (var i = 0; i < results.rows.length; i++) {
    var row = results.rows.item(i);
    var newFeature = new Object();

    newFeature.id = row['id'];

    itemName = two('' + newFeature.id + ''); //call the inner function

    alert("2-" + newFeature.id + '-' + itemName); //second alert
    }

    function two(itemId) {
    DEMODB.transaction(function (transaction) {
    transaction.executeSql("SELECT name FROM secondTable where id=?", [itemId], function (transaction, results) {
    if (results.rows.length > 0) {
    for (var i = 0; i < results.rows.length; i++) {
    var row = results.rows.item(i);
    var newFeature = new Object();

    newFeature.name = row['name'];
    result = newFeature.name;

    alert('1-' + itemId + '-' + result); //first alert
    }
    }
    }, null);
    });
    }

    This still not working properly.
    The //first alert is popping after the //second alert

    I just need the "itemName" varible to be filled before the second alert.
    In c# it is very simple, did not think JS will give me that pain

    Please advise

    Thanks

  8. #8
    Join Date
    Mar 2009
    Posts
    467
    Sorry -but I am having a hard time understanding what you are trying to accomplish and why. But you might try this. I moved your final alert into the callback function and placed it after the processing FOR loop.

    Code:
    function getInfo(itemId) {
        
        var itemName = "defaultName";
        
        DEMODB.transaction(
    		       function (transaction) {
    			   transaction.executeSql("SELECT * FROM itemsTable where id=?", [itemId], function (transaction, results) {
    				   if (results.rows.length > 0) {
    				       for (var i = 0; i < results.rows.length; i++) {
    					   var row = results.rows.item(i);
    					   var newFeature = new Object();
    					   
    					   newFeature.getName = row['name'];
    					   
    					   itemName = newFeature.getName;
    					   alert(itemName);
    				       }
    				   }
    				   alert(itemName);  // I moved it to here
    			       }, null);
    		       }
    		       );
    
        //alert(itemName);==========COMMENTED OUT
    }

  9. #9
    Join Date
    May 2013
    Posts
    5

    What i'm trying to accomplish...

    I will explain what i'm trying to accomplish:

    1. lets say i have 2 tables on my sqlite database. lets call them "table1" and "table2".
    2. each has an "id" column as a key. "table 2" contains a column name "parentId" that has the key id number of "table1".
    3. i have a js function that loops threw all items in "table1".
    4. i pull the row id of "table1" and want to create another function that takes this id (for each row), finds all items in "table2" with this number in the "parentId" column in "table2".
    4. then i want to print/show on page for each row of "table1" his id and all other id's (or a different column, not really matter for this example) from "table2".
    5. i know i can do JOIN in my sql but i want to use "table2" items to create more conditions outside the inner function so i need it to work this way (if possible).

    In c# it is very simple, js is giving me hard times.
    Probably because of the async but i'm sure there is a simple solution for that.

    Thanks

  10. #10
    Join Date
    Mar 2009
    Posts
    467
    For that you might try this approach:

    1. get the entire set of results from querying table1 and store it in a variable. Call
    it resultSet. Set a variable (counter) to zero. Set a var (limit) to the number
    of rows in resultSet. Set a var total as an empty array.

    2.create a function(A) that takes as its arg an offset to the rows in the resultSet,
    which should be the counter var as an argument. Each time this function is
    called it makes ONE and ONLY ONE query to table two, directing the output to:

    3.function(B), which (1)takes the results of a query and pushes them to the
    'total' array, (2) increments the counter var.
    --if counter is less than limit, it then invokes function A as in A(counter)
    --if counter equals the limit, it calls the function (whatever that is) that
    should be called after all the data has been obtained, and all that data is
    now stored in the 'total' array for the taking.

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center



Recent Articles