The JSON interface in "Component Library Source\WEBLib.JSON" is because of missing implementation code and the absence of any documentation already very hard to understand. On top, it lacks a lot of functionality. I already spent 2 days of research and programming helper classes where I had to dive down to the javascript level to get to a basic understanding on how JSON was implemented and to get to the information I need out of the TJSONObject like e.g. the number of properties stored in a JSON object or typed read or write of properties via the provided typed value classes. All this is very hard for a TMS Web Core beginner with only basic JS knowledge and effectively stops you from evaluating the possibilities of this product!
Then by accident I found out that the source in "Core Source\WEBLib.JSON" offers a much more elaborated interface and has everything needed. In particular, the implementation code is extremely helpful to understand the JSON implementation. So I wasted 2 days of time only because of an outdated unit interface!
I think I understand the need to provide two sets of sources. But then, the two sets should at least offer the same interfaces!
Is there a way for you guys to deliver synchronized interfaces rather soon? Or even better only one set of sources (maybe switch on/off implementation code between IDE and transpiler using conditional compiler directives)?
Implementation is not needed for the design-time, hence it is absent.
The interface should be identical. We will reopen this to make sure the interfaces are identical.
A single source solution is in the Delphi IDE not possible as the IDE isn't flexible enough to have a different compiler in use at design-time. A single source solution is in TMS WEB Core for Visual Studio Code where the entire design-time implementation is also based on web technology.
Well, if the functionality of a class is neither documented in the interface, nor in a manual, then the only information left to understand how the class is working is the implementation code...
In order to be able to move on with the evaluation of TMS Web Core, I just copied the Core Source version of WEBLib.JSON over to the the Component Library Source directory. Delphi is happy, I am happy and pas2js is happy as well. While this might probably not be possible with all units, at least for WEBLib.JSON, it is!
We will check this.
An extra thing to take in account is that the code must be compatible with older Delphi versions (till XE7) and also Lazarus.
Dear Bruno.
Please let me re-emphasize the urgency of synchronized interfaces, since even base units like JS have different and sometimes contradicting interfaces. Just one example:
Core Source
TJSJSON = class external name 'JSON' (TJSObject)
Public
class function parse(aJSON : String) : JSValue; <<-- JSValue here !!
Type
TJSValueType = (jvtNull,jvtBoolean,jvtInteger,jvtFloat,jvtString,jvtObject,jvtArray);
Function GetValueType(JS : JSValue) : TJSValueType;
Component Library Source
TJSJSON = class(TJSObject)
public
class function parse(aJSON: string): TJSObject; <<-- TJSObject here !!
TJSValueType --> MISSING!
GetValueType --> MISSING!
This again took me a lot of time to troubleshoot!
Coming back to WEBLib.JSON, I'm afraid to say that this implementation is hopelessly buggy, cumbersome and unneccessarily blown up. JSON is already built in at the core of javascript and in fact, based on what I already learned about javascript during the previous days, there isn't any real reason for an extra JSON class, as far as I can see. It's all already there in the JS unit.
Just one example of a severe bug in WEBLib.JSON even in the basics:
Var
wjs: WEBLib.JSON.TJSON;
wjo: WEBLib.JSON.TJSONObject;
wjs := WEBLib.JSON.TJSON.Create;
wjo := WEBLib.JSON.TJSONObject(wjs.Parse('{"foo":"bar"}'));
wjo.AddPair('answer',42);
Console.log(wjo.ToJSON);
This just prints "{"foo":"bar"}"
. The long-awaited answer to all questions is still missing! This is because the implementation of the class is adding the new key-value pair to an obscure internal list and not to the object itself using a property of the underlying TJSObject. I have given up on this class and written my own, which I am happy to share with anyone who might find this useful.