Login Register

Trying to understand how JSON data is passed from server to client

I am trying to understand how JSON data is retrieved/consumed from the server. My end goal is to be able to dynamically populate picklists (SELECTs) from a SQL Server backend. I have no problem creating the JSON data in ASP. My problem is translating it to plain string text on the client. The code below contains three cases. Cases 1 and 2 work fine. Case 3 does not work. One thing I have noticed a number of times is that when I have been able to print the JSON records they will print as "object, object" or something like that instead of showing the field values. I don't have the exact phrase, because I can't remember how to reproduce it. I have spent several days hacking away, reading AJAX/Dojo.data tutorials, and examples on the web, and cutting and pasting snippets from various places and experimenting in an attempt to get my hands around this. There is something basic I am just not yet grasping. I am hoping that a reply to this post or to my post in this forum earlier today (that uses the same key words) will switch the light on.

In the HTML header...

<code>
<script type="text/javascript" src="./dojo.1.0.2/dojo/dojo.js"
djConfig="parseOnLoad: true"></script>
<script type='text/javascript' src='./JSON_consumption.js'></script>
<script type="text/javascript">
// Load Dojo's code relating to the Button widget
dojo.require("dijit.form.Button");
dojo.require("dijit.form.FilteringSelect");
dojo.require("dojo.data.ItemFileReadStore");
dojo.require("dojo.parser");
</script>

<script>

var str="offices"
var url="UpdatePicklist.asp";
url=url+"?q="+str;
url=url+"&sid="+Math.random();

function callback_testButton(data,ioArgs) {
alert(data);
}
function errorMessage(data, ioArgs) {
alert('Error when retrieving data from the server!');
}

</script>
</code>

In the body...

<code>
<!--
************************************************************************************
CASE 1 Pass a dynamic JSON data structure produced by an ASP to a button element.
This case works. The alert returns the JSON data as a string.
************************************************************************************
-->
<button dojoType="dijit.form.Button" id="testButton">
Display server response
<script type="dojo/method" event="onClick">
dojo.xhrGet({
url: url,
//url: 'UpdatePicklist.asp',
//url: 'response1.asp',
//url: 'response.txt',
load: callback_testButton,
error: errorMessage,
//content: {name: dojo.byId('name').id }
});
</script>
</button>

<!--
************************************************************************************
CASE 2 Pass a static JSON data structure from a text file to a SELECT element.
This case works. The SELECT element gets populated successfully.
************************************************************************************
-->
<br />
<div dojoType="dojo.data.ItemFileReadStore" jsId="stateStore"
url="states.txt"></div>
<input dojoType="dijit.form.FilteringSelect"
store="stateStore"
searchAttr="name"
name="testSelect1"
autocomplete="true"
/>
<br />

<!--
************************************************************************************
CASE 3 Pass a dynamic JSON data structure produced by an ASP to a SELECT element.
This case fails. The SELECT element does not get populated successfully.
************************************************************************************
-->
<div dojoType="dojo.data.ItemFileReadStore" jsId="officeList"
url=url ></div>
<input dojoType="dijit.form.FilteringSelect"
id="testSelect2"
store="officeList"
searchAttr="fOffice"
name="testSelect2"
autocomplete="true"
/>
</code>

Is searchAttr == "xxxx" of

Is searchAttr == "xxxx" of Identifier:"xxxx" (from the store)?

Could you post a few lines (items) from your json data for case #3?

Here is the JSON data

The JSON data I am testing with is below:

({

"Records":

      [

            {"fOffice":"Dayton"},

            {"fOffice":"Fairview Heights"}

      ],

      "RecordCount":"2"

})

The JSON response is generated by the following ASP code: ...

<code>

 Set objRecSet = CreateObject("ADODB.Recordset")
 objRecSet.CursorType = adOpenForwardOnly
 objRecSet.LockType = adLockReadOnly

 sSQL = "SELECT DISTINCT [" & strFieldName & "] FROM [" & strTableName & "] ORDER BY [" & strFieldName & "]"
 objRecSet.Open sSQL, objConnection

 Dim jsonStrObj
 jsonStrObj = RStoJSON(objRecSet)
 Response.Write jsonStrObj

</code>

The RStoJSON function is called from the following code I found on the web:

<code>

'Function to convert an ADO recordset into a JSON object
'
'Written by Tracy Dryden, Commonwealth Technology Group, Inc.
'
'Released to the public domain.

function RStoJSON(rs)
    dim sFld
    dim sFlds
    dim sRec
    dim sRecs
    dim sRecordSet
    dim lRecCnt

    sRecordSet = ""
    sRecs = ""
    lRecCnt = 0
    if rs.EOF or rs.BOF then
        RStoJSON = "null"
    else
        do while not rs.EOF and not rs.BOF
            lRecCnt = lRecCnt + 1
            sFlds = ""
            for each fld in rs.Fields
                sFld = """" & fld.Name & """:""" & toUnicode(fld.Value&"") & """"
                sFlds = sFlds & iif(sFlds <> "", ",", "") & sFld
            next 'fld
            sRec = "{" & sFlds & "}"
            sRecs = sRecs & iif(sRecs <> "", "," & vbCrLf, "") & sRec
            rs.MoveNext
        loop
        sRecordSet = "( {""Records"": [" & vbCrLf & sRecs & vbCrLf & "], "
        sRecordSet = sRecordSet & """RecordCount"":""" & lRecCnt & """ } )"
        RStoJSON = sRecordSet
    end if
end function

function toUnicode(str)
    dim x
    dim uStr
    dim uChr
    dim uChrCode
    uStr = ""
    for x = 1 to len(str)
        uChr = mid(str,x,1)
        uChrCode = asc(uChr)
        if uChrCode = 8 then ' backspace
            uChr = "\b"
        elseif uChrCode = 9 then ' tab
            uChr = "\t"
        elseif uChrCode = 10 then ' line feed
            uChr = "\n"
        elseif uChrCode = 12 then ' formfeed
            uChr = "\f"
        elseif uChrCode = 13 then ' carriage return
            uChr = "\r"
        elseif uChrCode = 34 then ' quote
            uChr = "\"""
        elseif uChrCode = 39 then ' apostrophe
            uChr = "\'"
        elseif uChrCode = 92 then ' backslash
            uChr = "\\"
        elseif uChrCode < 32 or uChrCode > 127 then ' non-ascii characters
            uChr = "\u" & right("0000" & CStr(uChrCode),4)
        end if
        uStr = uStr & uChr
    next
    toUnicode = uStr
end function

function iif(cond,tv,fv)
    if cond then
        iif = tv
    else
        iif = fv
    end if
end function

</code>

Thankyou for your assistance.

Normally, you would expect

Normally, you would expect the JSON returned to dojo for a filtering select to be of the form:

{
identifier:"fOffice",
items: [
        {fOffice:"Dayton"},
        {fOffice:"Fairview Heights"}
       ]
}

taken from here:

http://dojotoolkit.org/book/dojo-book-0-9/part-2-dijit/form-validation-s...

The "identifier" field is important. "Items" is the expected field name for the object array to follow.

Modify your json prep code to write it back as above (and w/o the parens), and see if it works for you.

Later, it would be better to wrap your server response in comments, i.e.,

Response.Write "/*" + jsonStrObj + "*/"

and set your server's output contentType (within the code block that is writing the content to the client) to "json-comment-filtered".

Resolved

Thank you frankf,

Your suggestions helped me get the code working. For the benefit of others here is the revised JSON data creator.

<code>
<%

'Function to convert an ADO recordset into a JSON object
'
'Written by Tracy Dryden, Commonwealth Technology Group, Inc.
'
'Released to the public domain.

function RStoJSON(rs)
dim sFld
dim sFlds
dim sRec
dim sRecs
dim sRecordSet
dim lRecCnt
dim identifierValue

sRecordSet = ""
sRecs = ""
lRecCnt = 0
if rs.EOF or rs.BOF then
RStoJSON = "null"
else
do while not rs.EOF and not rs.BOF
lRecCnt = lRecCnt + 1
sFlds = ""
for each fld in rs.Fields
'*** Modified by Gene Evans - Removed quotes from around field name. ***
'sFld = """" & fld.Name & """:""" & toUnicode(fld.Value&"") & """"
sFld = fld.Name & ":""" & toUnicode(fld.Value&"") & """"
sFlds = sFlds & iif(sFlds <> "", ",", "") & sFld
identifierValue = fld.Name
next 'fld
sRec = "{" & sFlds & "}"
sRecs = sRecs & iif(sRecs <> "", "," & vbCrLf, "") & sRec
rs.MoveNext
loop

'*** Modified by Gene Evans - Removed leading and trailing outside parens, added identifier, ***
'*** removed quotes from around attribute names, and changed Recordcount to itemCount. ***
'sRecordSet = "( {""Records"": [" & vbCrLf & sRecs & vbCrLf & "], "
'sRecordSet = sRecordSet & """RecordCount"":""" & lRecCnt & """ } )"
sRecordSet = "{ identifier: """ & identifierValue & ""","
sRecordSet = sRecordSet & vbCrLf & "items: [" & vbCrLf & sRecs & vbCrLf & "],"
sRecordSet = sRecordSet & vbCrLf & "itemCount: """ & lRecCnt & """ }"
RStoJSON = sRecordSet
end if
end function

function toUnicode(str)
dim x
dim uStr
dim uChr
dim uChrCode
uStr = ""
for x = 1 to len(str)
uChr = mid(str,x,1)
uChrCode = asc(uChr)
if uChrCode = 8 then ' backspace
uChr = "\b"
elseif uChrCode = 9 then ' tab
uChr = "\t"
elseif uChrCode = 10 then ' line feed
uChr = "\n"
elseif uChrCode = 12 then ' formfeed
uChr = "\f"
elseif uChrCode = 13 then ' carriage return
uChr = "\r"
elseif uChrCode = 34 then ' quote
uChr = "\"""
elseif uChrCode = 39 then ' apostrophe
uChr = "\'"
elseif uChrCode = 92 then ' backslash
uChr = "\\"
elseif uChrCode < 32 or uChrCode > 127 then ' non-ascii characters
uChr = "\u" & right("0000" & CStr(uChrCode),4)
end if
uStr = uStr & uChr
next
toUnicode = uStr
end function

function iif(cond,tv,fv)
if cond then
iif = tv
else
iif = fv
end if
end function

</code>