Search code examples
jsonasp-classicvbscriptjscript

merge two json arrays, server side javascript, classic asp


I have a classic asp (vbscript) page that I want to load and merge two json files on (apply one over the other recursively).

<script language="JScript" runat="server">
function MergeJson(dest, src) {
for (var prop in src) {
        if (src.hasOwnProperty(prop)) {
    try {
        if ( src[prop].constructor==Object ) {
            dest[prop] = MergeJson(dest[prop], src[prop]); // recurse
        } else {
            dest[prop] = src[prop]; // update
        }
    } catch(e) {
        dest[prop] = src[prop]; // create
    }
        }
}
return dest;
}
</script>

The above function performs properly when I execute it client side (in Chrome, etc). But when I take the same function and add it server side, it fails. My calling code is in VBScript and is like this:

Sub GetJSON(byval path, byref oJSON)
    Dim str : str = GetFileString(Server.MapPath(path), "")
    If str = "" Then str = "{}" ' empty object
    Set oJSON = JSON.parse(join(array(str))) ' Douglas Crockford's json2.js
End Sub

Dim DefualtSettings : Call GetJSON("/defaults/settings.json", DefaultSettings)
Dim MySettings : Call GetJSON("/my/settings.json", MySettings)
Dim newSettings : newSettings = MergeJson(DefaultSettings, Settings)
response.write JSON.stringify(newSettings, null, 4) ' see it

I'm not that sure why it hasn't survived the transition to server side code. I've checked that I'm loading the json properly and that it is able to be parsed as such (so it's valid), and executing essentially the same client side is working fine... I'm unsure how to debug the code server side, I don't have any development tools on that box, it's just a standard windows server with IIS 7.5.


Solution

  • In VBScript, if you want to assign an object reference to a variable, you have to use the Set statement. Change this line:

    Dim newSettings : newSettings = MergeJson(DefaultSettings, Settings)
    

    to

    Dim newSettings : Set newSettings = MergeJson(DefaultSettings, Settings)
    

    Without Set, VBScript tries to coerce the right-hand side to a value type, usually by calling a default property, if it exists. In the case of the MergeJson function, it appears that the default property for JScript objects is the toString function, which, by default, returns the string "[object typename]". This would explain why "[object Object]" is being assigned to newSettings when you don't use Set.