Xbasic

json_generate Function

Syntax

C result = json_generate(var as P [, flagSpecialFlags as L [, flagCondense as L [,indent as C [,flagHonorNulls as L]]]])

Arguments

varPointer

An Xbasic dot variable you want to convert to a JavaScript object.

flagSpecialFlagsLogical

If flagSpecialTags is .t. then you can use the {javascript} prefix in a property to include arbitrary JavaScript, including functions, in the resulting JavaScript object.

flagCondenseLogical

Specify whether or not the JavaScript object should be generated on a single line. If .f., the output will be nicely formatted with tabs and new lines.

indentCharacter

Only applies if flagCondense is .f.. Specifies the character prefix to use on all indented lines. Typically used to include   character to make the resulting output look nice in an HTML document.

flagHonorNullsLogical

Default value is .f.. If flagHonorNulls is .t., a null value is emitted for variables that are blank strings.

Returns

resultCharacter

Returns the dot variable as a string containing a JavaScript object.

Description

Generate takes a variable, an Xbasic dot variable, and returns a string containing a JavaScript object literal.

Discussion

The json_generate() function takes an xbasic dot variable and generates a string containing a JavaScript object. While it may appear to be JSON, the JavaScript object json_generate() generates may actually not be valid JSON. The following example explains:

dim p as p
p.name = "Fred"
p.city = "Boston"
?json_generate(p)
= {
    "name": "Fred",
    "city": "Boston"
}

In this case, the string that is generated is indeed valid JSON.

However, consider this case

dim p as p
p.name = "Fred"
p.city = "Boston"
p.date = date()
?json_generate(p)
= {
    "name": "Fred",
    "city": "Boston",
    "date": Date('2019/04/11')
}

In this case, the generated string is not valid JSON. However, it is a valid JavaScript object and a typical use case for this is when you want to send a JavaScript response from an Ajax callback where the response should be a JavaScript object. For example consider this Xbasic function which handles an Ajax callback:

function xb as c (e as p)
dim p as p
p.name = "Fred"
p.city = "Boston"
p.date = date()
dim jsstring as c 
jsstring = json_generate(p)
dim js as c 
js = "var myvar = " + jsstring
xb = js 
end function

The json_generate() function is capable of generating more complex JavaScript objects, such as objects that include functions. For example:

dim p as p
p.name = "Fred"
p.sayHello = "{javascript}function(name) {alert('Hello: ' + name);}"

?json_generate(p,.t.) 'note the second argument to json_generate() is .t.. The default value is .f.
= {
    "name": "Fred",
    "sayHello": function(name) {alert('Hello: ' + name);}
}

The prefix {javascript} in the string indicates that the text following the prefix is a JavaScript function.

json_generate() is designed so that you use the json_parse() function to perform a full "round trip" conversion between Xbasic and JavaScript without losing any information in the original object. This is not the case with property_to_json().

If you want a true JSON object, then use property_to_json(). For example:

delete p 
dim p as p
p.name = "Fred"
p.city = "Boston"
p.date = date()
?json_reformat(property_to_json(p))
= {
    "name": "Fred",
    "city": "Boston",
    "date": "2019-04-11"
}

The above string is a valid JSON string, but notice that we have lost information about the original type of type of the "date" property. The date was converted from a date type to a string containing a date.

The json_generate() function should be used in place of varToJSON() which has been deprecated. The json_generate() function is identical to varToJSON() in all respects, except that the attribute name and string values are quoted using double quotes in accordance with the official JSON specification.

The JSON spec does not escape single quotes.
dim pj as p
pj.text = "some text with ' single quote"
?json_generate(pj)
= {
    "text": "some text with ' single quote"
}

Example: Using flagSpecialFlags 

flagSpecialFlags is used when you are trying to generate a JavaScript object for a dot variable that includes a JavaScript function call or inline JavaScript.

For example:

dim p as p
p.name = "foo"
p.function = "{javascript}function() { alert('hello') }"

?json_generate(p,.t.)
= {
    "name": "foo",
    "function": function() { alert('hello') }
}

Without flagSpecialFlags set to .t., p.function would be treated as a string and would not be converted to a JavaScript function. For example:

?json_generate(p,.f.)
={
    "name": "foo",
    "function": "{javascript}function() { alert('hello') }"
}

Example: Using flagHonorNulls 

If a property contains a null value, json_generate(), the flagHonorNulls parameter can be set to .t. to ensure that null properties are preserved and are not converted to blank strings.

For example, in the example below, the age property is converted to a blank string if flagHonorNulls is set to false:

dim p as p
p.name = "joe"
p.age = null_value()
p.function = "{javascript}null"

dim specialFlags as L = .t.
dim condense as L = .t.
dim honorNull as L

' Don't preserve null values:
honorNull = .f.

? json_generate(p,specialFlags,condense,"",honorNull)
= {
    "name": "joe",
    "age": "",
    "function": null
}

' Preserve null values:
honorNull = .t.

? json_generate(p,specialFlags,condense,"",honorNull)
= {
    "name": "joe",
    "age": null,
    "function": null
}

See Also