views:

472

answers:

5

I have a very simple Javascript function that hits a MS SQL server and returns some records back. There is a cell that i want to only display in the top table row when it is unique. I believe my problem is var hoisting because the variable that i assign within the while loop does not work because the value is not carried from the last records to compare. Here is the code

function searchIndex()
{

    var termcounter = "";

    flyoutHTML = '<table>';

    var adOpenDynamic = 2
    var adLockOptimistic = 3

    var conn = new ActiveXObject("ADODB.Connection");
    var connectionstring = "Provider=SQLOLEDB;Server=XXXXXXXX;INTEGRATED SECURITY=SSPI;DATABASE=YYYYYYYYYY;"

    conn.Open(connectionstring)
    var rs = new ActiveXObject("ADODB.Recordset")

    rs.Open("SELECT field1, field2, field4, field4, field5 FROM dbo.table;", conn)

    if (rs.eof)
    {
    flyoutHTML += '<tr><td align="center">No Records Found!</td></tr>';
    }
    else
    {


    while(!rs.eof)
    {

    if (termcounter != rs(0))
    {
     var termcounter = rs(0);
     flyoutHTML += '<tr>';
     flyoutHTML += '<td colspan="3">' + rs(0) + '</td>';
     flyoutHTML += '</tr>';
    }


    flyoutHTML += '<tr>';
    flyoutHTML += '<td>' + rs(1) + '</td><td>' + rs(2) + '</td><td>' + rs(3) + '</td>';
    flyoutHTML += '</tr>';

    rs.movenext

    }
    rs.close
    conn.close


    flyoutHTML += '</table>';

}
+5  A: 

Take the "var" off the var termcounter = rs(0);

You're probably right about hoisting--JavaScript doesn't have block scope, so both times you declare termcounter it's in the same scope. This is a very common mistake, since JavaScript looks like C-based languages which have block scope.

Declaring a var in a conditional or looping block is equivalent to declaring it at the beginning of the function that block is in, scope-wise.

You'll lose less hair if you always place your var declarations at the top of functions--never in conditional or loop blocks. See Crockford. You can use JSLint to warn you. (Oh, by the way, you're missing a ton of semicolons--JSLint will hurt your feelings.)

So why are you redeclaring it? Drop the second "var" and just do the assignment.


The Microsoft stuff is alien to me, but I find the rs(0) syntax baffling. Is rs an object? Or is there some kind of magic that makes it into a function as well (you never know with JS)? I did some Googling and I wonder if you need to be using rs.fields(0) or rs.fields(0).name or rs.fields(0).value or something.

Nosredna
I remember I once saw a case in IE6 where array elements were read using parenthesis, not square brackets. And it worked.
Ionuț G. Stan
Ooo. You're giving me one of those IE6 migraines that's so hard to get rid of!
Nosredna
I just tried parens rather than brackets in Chrome's console. No go. _TypeError: object is not a function_ I'll hear no more of your IE6 craziness. :-)
Nosredna
functions can have properties in javascript. Since we're talking about a "host object" here, all it needs is to have, internally, some kind of "call" parameter, and you can call it like a function, even if typeof rs !== "function". (the ecmascript committy fixed that little problem in ES5. Now ALL callable objects must return "function" when you use it as the operand of the typeof operator.
Breton
You can apprently try this in IE6. typeof alert !== "function"
Breton
+3  A: 

You have this:

var termcounter = rs(0);

I don't think you want to be redeclaring it here - remove the var:

termcounter = rs(0);
Greg
A: 

Sorry about declaring it twice that was me trying anything to make this work. I just forgot to remove it. So does anyone have a different way to do this? I'm a VB programmer and JavaScript has been killing me...

A: 

So in case folks don't understand how this should look the table output would look like:

Title 1 Record 1 Record 2 Record 3 Title 2 Record 4 Record 5 Record 6 Record 7 Title 3 Record 8 Record 9 etc...

What's happening is this:

Title 1 Record 1 Record 2 Record 3 Record 4 Record 5 Record 6 Record 7 Record 8 Record 9 etc...