When interacting with ordinary javascript libraries or a remote webservice you natually have to go native with your datastructures. Under Smart this can be handled in a variety of ways but the two most common approaches are to either use a record or a variant.
Using records
Records in Smart work just like they do in other object pascal environments. And since Smart compiles to javascript rather than machine opcodes, a record will always compile to an ordinary javascript structure. I should note that javascript really doesnt distinguish between what we would call a record and objects. In javascript everything is an object.
So the following object pascal code:
[sourcecode language=”delphi”]
type TMyInfo = Record
miName: String;
miAge: Integer;
miGender: integer;
End;
[/sourcecode]
Results in the following predictable javascript code:
[sourcecode language=”javascript”]
{
miName: "",
miAge: 0,
miGender: 0
}
[/sourcecode]
This means that when you want to interact with native javascript libraries that expects a structure of values, you can use records to match it directly.
Variants
Using variants to achieve the same thing is perhaps easier, especially since you dont have to predefine the structure by hand. As of writing however it does require you to initialize the variant manually. We will probably add some RTL functions to simplify this very soon, but for now you can use this “one liner” ASM snippet:
[sourcecode language=”delphi”]
Procedure testvariant;
var
mData: variant;
Begin
asm @mData = {}; end; // Set variant to "empty JS object"
mData.miName:=’john doe’;
mData.miAge:=39;
mData.miGender:=1;
end;
[/sourcecode]
The resulting javascript structure will be exactly the same as that produced by the record. One difference to keep in mind though, is that the compiler will output the names “as is”. There is no way for Smart to map the content of a native object so make sure you get the names right.
mData := Null;
or
mData := Variant.Null;
would be a nice syntactic sugar for
asm @mdata = {} end;
Yes i was thinking the same thing.
Or just adding a function to w3system.pas
function w3_CreateVar(vType:TVariantType):Variant;
I feel this belongs to the lowlevel RTL, so I’ve notified Eric about it.
The Null variant probably has to map to ‘null’ (ie. no object).
For the empty object, the {} in JavaScript is actually a constructor, so it would have to map to a constructor or function in Pascal (you can’t map it to a constant or variable, as that would just share the object reference).
mData := CreateEmptyJSObject;
or something like that. Maybe
mData := Variant.Create;
or
mData := new Variant;
could do, though they would look kinda weird in Pascal.
If course, I though exactly of the same when I was slowly falling into sleep. And my ideas were also the same – Variant.Create (Delphi style) or new Variant (Prism style).