3

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>';

}
Nosredna
  • 83,000
  • 15
  • 95
  • 122
  • 1
    Google is becoming omnipresent. I've just googled "javascript var hoisting" in order to get some official docs, and the first result on the page was this very question. – Ionuț G. Stan Jul 23 '09 at 22:01

3 Answers3

6

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
  • 83,000
  • 15
  • 95
  • 122
  • 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 Jul 23 '09 at 21:59
  • Ooo. You're giving me one of those IE6 migraines that's so hard to get rid of! – Nosredna Jul 23 '09 at 22:04
  • 1
    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 Jul 23 '09 at 22:20
  • 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 Aug 06 '09 at 01:20
  • You can apprently try this in IE6. typeof alert !== "function" – Breton Aug 06 '09 at 01:21
3

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
  • 316,276
  • 54
  • 369
  • 333
1

AKA How can one de-reference JavaScript variables when enclosing an outer scope?

Community
  • 1
  • 1
ken
  • 3,650
  • 1
  • 30
  • 43