You are not logged in.
Pages: 1
I reuse some Javascript code from Javascript authentication . Thanks for Ab, esmondb and RangerX.
I added more functions to mORMotClient in order to consume Interface based services. I will share it when done. But I still have one point and I need some help.
For example if I have an interface like this
IAccountsChart = interface(IBaseFactory)
['{A35B2E70-C92D-4573-B46C-83F971B7E3DF}']
function GetChartData(out Items: TAccChartItems ): Integer;
function InsertChartItem(out Items: TAccChartItems; ParentId: TId; Index : Integer): Integer;
function DelChartItem(out Items: TAccChartItems; ItemId: TId): Integer;
function MoveChartItem(out Items: TAccChartItems; ItemId, ParentId : TId; Index : Integer=-1): Integer;
function UpdateChartItem(Item: TAccChartItemData): Integer;
end;
I want to produce the following Javascript code for this interface so I can reflect new added functions to Javascript.
function AccountsChart(mORMotClient){
this.onGetChartData= null;
this.onInsertChartItem= null;
this.onDelChartItem= null;
this.onMoveChartItem= null;
this.onUpdateChartItem= null;
........................
this.GetChartData = function(){
return doCall('GetChartData', null, this.onGetChartData);
}
this.InsertChartItem = function(Parent, Index){
return doCall('InsertChartItem', Parent, Index, this.onInsertChartItem);
}
this.DelChartItem = function(ItemId){
return doCall('DelChartItem', ItemId, this.onDelChartItem);
}
this.MoveChartItem = function(ItemId,Parent, Index){
return doCall('MoveChartItem', ItemId,Parent, Index, this.onMoveChartItem);
}
this.UpdateChartItem = function(Item){
return doCall('UpdateChartItem', Item, this.onUpdateChartItem);
}
}
can I generate that Javascript at my mORMot server?
I want to call it directly from the browser like that :
<script src="http://localhost:888/root/GetJScript/AccountsChart"></script>
<script>
......................
var accountsChart=New AccountsChart(mORMotClient);
var chartData = accountsChart.GetChartData();
......................
</script>
Last edited by Ehab (2018-10-15 13:10:47)
Offline
It may be possible if you write the proper Mustache template.
See https://synopse.info/files/html/Synopse … #TITLE_482
Offline
Thanks ab for your quick response and pointing me to Mustache template.
I used a Mustache template and I got some results very close to what I need.
My problem now is I want a comma (,) not semicolon (;) in function parameters like the following
function GetChartBranchData( Items; ItemId );
//I wanted it to be
//function GetChartBranchData( Items, ItemId );
Can I use something else instead of {{commaArg}} to produce a comma (,) not semicolon (;)?
This is the template :
{{<method}}function {{methodName}}({{#args}} {{^dirResult}} {{argName}}{{commaArg}}{{/dirResult}} {{/args}} );{{/method}}
{{<member}}this.on{{methodName}} = null;{{/member}}
{{#orm}}
{{^isInMormotPas}}
{{/isInMormotPas}}
{{/orm}}
{{#soa.services}}
/* Definition of {{interfaceURI}} Object */
// ------------------------------------
function {{interfaceURI}}(mORMotClient){
this.initialized=false;
this.mORMotClient=mORMotClient;
{{#methods}}
{{>member}}
{{/methods}}
var doCall = function(fnName, fnParam, callBack){
funcName = '{{interfaceURI}}.' + fnName;
funcParam = '[' + ((! fnParam) ? '' : JSON.stringify(fnParam)) + ']';
return mORMotClient.callFunc(funcName, funcParam, callBack, this);
}
this.Initialize = function(){
doCall('_contract_', null, this.onInitialize);
}
this.onInitialize = function(req){
var data = req.responce;
if(data.error.errorNo == 0)
req.owner.initialized = true;
}
{{#methods}}
{{>method}}
{{/methods}}
}
{{/soa.services}}
The result of this template is
/* Definition of AccountsChart Object */
// ------------------------------------
function AccountsChart(mORMotClient){
this.initialized=false;
this.mORMotClient=mORMotClient;
this.onExportJScript=null;
this.onFillDefaultChartData=null;
this.onGetChartData=null;
this.onGetChartBranchData=null;
this.onInsertChartItem=null;
this.onAddChartItem=null;
this.onDelChartItem=null;
this.onMoveChartItem=null;
this.onUpdateChartItem=null;
this.onGetChartItem=null;
this.onChangeChartItemKind=null;
var doCall = function(fnName, fnParam, callBack){
funcName = 'AccountsChart.' + fnName;
var fnParams = [];
for(var i=0; i < fnParam.length; i++) fnParams[i] = fnParam[i];
return mORMotClient.callFunc(funcName, JSON.stringify(fnParams), callBack, this);
}
this.Initialize = function(){
doCall('_contract_', null, this.onInitialize);
}
this.onInitialize = function(req){
var data = req.responce;
if(data.error.errorNo == 0)
req.owner.initialized = true;
}
this.ExportJScript= function ( ){
return doCall('ExportJScript', arguments, this.onExportJScript);
};
this.FillDefaultChartData= function ( Items; ChartType ){
return doCall('FillDefaultChartData', arguments, this.onFillDefaultChartData);
};
this.GetChartData= function ( Items ){
return doCall('GetChartData', arguments, this.onGetChartData);
};
this.GetChartBranchData= function ( Items; ItemId ){
return doCall('GetChartBranchData', arguments, this.onGetChartBranchData);
};
this.InsertChartItem= function ( Items; ParentId; Index ){
return doCall('InsertChartItem', arguments, this.onInsertChartItem);
};
this.AddChartItem= function ( Items; ParentId ){
return doCall('AddChartItem', arguments, this.onAddChartItem);
};
this.DelChartItem= function ( Items; ItemId ){
return doCall('DelChartItem', arguments, this.onDelChartItem);
};
this.MoveChartItem= function ( Items; ItemId; ParentId; Index ){
return doCall('MoveChartItem', arguments, this.onMoveChartItem);
};
this.UpdateChartItem= function ( Item ){
return doCall('UpdateChartItem', arguments, this.onUpdateChartItem);
};
this.GetChartItem= function ( Item; ItemId ){
return doCall('GetChartItem', arguments, this.onGetChartItem);
};
this.ChangeChartItemKind= function ( ItemId; ItemKind ){
return doCall('ChangeChartItemKind', arguments, this.onChangeChartItemKind);
};
}
Offline
Thanks ab
It works now after using
{{#commaArg}}, {{/commaArg}}
My template file name is "Js.pas.mustache" and I can call it from Javascript like this:
<script src='http://localhost:888/root/wrapper/Js/mORMotClient.pas.txt'></script>
But I want to call it like this
<script src='http://localhost:888/root/js/mORMotClient_Services.js'></script>
Or
<script src='http://localhost:888/root/js/Services.js'></script>
Can you please point me to a solution to change
wrapper/Js/mORMotClient.pas.txt
to
js/mORMotClient_Services.js
?
Last edited by Ehab (2018-10-16 12:46:24)
Offline
I would tend to use a mORMot-based service for this, with an in-memory cache of the js content.
Just re-use the content of procedure WrapperMethod() for your own method.
If you call the method js(Ctxt), then you will be able to parse what is after the root/js/.... method name from the Ctxt.URIAfterRoot value.
Offline
Hi ab
I am new to mORMot.
I would tend to use a mORMot-based service for this, with an in-memory cache of the js content.
Just re-use the content of procedure WrapperMethod() for your own method.
I didn't know what do you mean by "in-memory cache" and how to do that in mORMot, but I get that you advice me to save the content and reuse it. So I saved the js content to a file "Service.js". I did this at server start so I can get the file later when a client need it at anytime. I used something like this:
JsName := ExtractFileName(aJsFileName);
Content:= WrapperFromModel(aServer, StringFromFile(aMustacheTemplate), JsName , 888);
FileFromString(Content, aJsFileName);
If you call the method js(Ctxt), then you will be able to parse what is after the root/js/.... method name from the Ctxt.URIAfterRoot value.
I'm using something like sample 09 - HttpApi web server to access the file from Javascript like this:
<script src="http://localhost:888/root/js/Services.js"></script>
This is enough for my learning purpose right now, but it is still advisable to learn from you and other mORMot experts. I want to share a full working sample (Server, Delphi client, web client and MySql database). I hope this may save some time for other newbie like me. I know the rules No long code in the forum. Can I upload it to my website and put the download link here?
There is another thing I need to do and I need your help to point me to the right direction as usual.
Delphi :
function GetChartBranchData(out Items: TAccChartItems; ItemId: TId ): UInt32;
Output Javascript :
function GetChartBranchData(Items, ItemId)
I want to remove the out parameter(s) Items in this case. I don't want to confuse the Javascript programmer.
I want it to be like this:
Delphi :
function GetChartBranchData(out Items: TAccChartItems; ItemId: TId ): UInt32;
Output Javascript:
function GetChartBranchData(ItemId)
Last edited by Ehab (2018-10-17 02:27:49)
Offline
Yes, of course, you can upload it to your website, or you could even make a pull request on GitHub, adding a new folder in the "third party" samples.
For the output/results parameters in javascript, I guess the most obvious could be to return an object with the output fields: {Items:[...],Result:1234}
Offline
Hi ab,
For the output/results parameters in javascript, I guess the most obvious could be to return an object with the output fields: {Items:[...],Result:1234}
My last question was about the output of Mustache template not javascript.
I don't want the Delphi method parameters of kind output to be appear in Mustache template output.
For example if I have the following interface:
IAccountsChart = interface(IBaseFactory)
['{A35B2E70-C92D-4573-B46C-83F971B7E3DF}']
function GetChartBranchData(out Items: TAccChartItems; ItemId: TId ): UInt32;
end;
And I use the following template fragment for output method's name and parameter
{{<method}}this.{{methodName}}=function({{#args}}{{^dirResult}}{{argName}}{{#commaArg}}, {{/commaArg}}{{/dirResult}}{{/args}}){
.......................................
}{{/method}}
Mustache template output is :
this.GetChartBranchData = function(Items, ItemId){
.......................................
}
But I want the template to output:
this.GetChartBranchData = function(ItemId){
.......................................
}
Is that possible ?
Offline
Hi ab,
I have abandoned using the Mustache template. I used TSQLRestServerDB.Services to get the output I want.
I uploaded a sample at gulf-soft.com/e/files/Mormot_Sample.zip
In this sample I included my thought about making it easier for JavaScript programmer for consuming my services. Beside other things like simple Http server and using MySql.
Now if I have Interface like this:
IClientRepository = interface(IBaseFactory)
['{31D143DB-9EED-4C00-940B-52C9BDB515D1}']
function GetClient(Id : TId; out aClient: TSQLClient) : Cardinal;
function SaveClient(var aClient: TSQLClient) : Cardinal ;
..............................
end;
In JavaScript I will use some code like this:
var clientRepository = new ClientRepository(_mc);
var r = clientRepository.GetClient(Id);
if(r.XHR.status == 200){
workClient = r.responce.result[0];
displayClent(workClient);
}
else
alert(r.XHR.responseText);
I hope this sample helps others and I get some comments to improve my knowledge in mORMot.
Last edited by Ehab (2018-10-20 04:30:27)
Offline
Pages: 1