[Pas2js] DataSet at the beginning
warleyalex
warleyalex at yahoo.com.br
Sat Nov 10 19:01:00 CET 2018
I want to load a JSON file from my own server containing an array into a
javascript Object variable.
I would like to do it at the beginning of page load in a "synchronous" way
because data is needed during page load. But I think synchronous
XMLHttpRequest on the main thread is deprecated because of its detrimental
effects to the end user's experience.
In the project source: after 500ms call p1;
I use window.setTimeout(@p1, 500); and worked as expected!
if i use just in async way
p1; // the JSON file still is loading, we can not properly set the
variables at the beginning. Any ideas?
How to load the dataset at the beginning of the project in async
XMLHttpRequest?
------// uCDS -----------
unit uCDS;
{$mode objfpc}
interface
uses
Classes, SysUtils, Types, JS, Web, DB, JSONDataSet;
type
TControl = TObject;
type
{ TWDataSource }
TWDataSource = class(TDataSource)
private
{ private declarations }
FParent: TControl;
FLeft: Integer;
FTop: Integer;
protected
{ protected declarations }
public
{ public declarations }
published
{ published declarations }
property Parent: TControl read FParent write FParent;
property Left: Integer read FLeft write FLeft;
property Top: Integer read FTop write FTop;
end;
type
TConnectErrorEvent = procedure(Sender: TObject; ErrorCode: Integer);
type
TDataSet = class;
type
{ TConnection }
TConnection = class(TComponent)
private
{ private declarations }
FReq: TJSXMLHttpRequest;
FDS: TDataSet;
FParent: TControl;
FLeft: Integer;
FTop: Integer;
FActive: Boolean;
FDataNode: String;
FURI: String;
FAfterConnect: TNotifyEvent;
FBeforeConnect: TNotifyEvent;
FOnConnectError: TConnectErrorEvent;
protected
{ protected declarations }
procedure SetActive(AValue: boolean);
public
{ public declarations }
function onLoad(Event: TEventListenerEvent): boolean;
procedure RegisterDataSet(value: TDataSet);
procedure DoBeforeConnect;
procedure DoAfterConnect;
procedure DoError(ErrorCode: Integer);
constructor Create(AOwner: TComponent); override;
published
{ published declarations }
property Parent: TControl read FParent write FParent;
property Left: Integer read FLeft write FLeft;
property Top: Integer read FTop write FTop;
property Active: Boolean read FActive write SetActive;
property DataNode: String read FDataNode write FDataNode;
property URI: String read FURI write FURI;
property AfterConnect: TNotifyEvent read FAfterConnect write
FAfterConnect;
property BeforeConnect: TNotifyEvent read FBeforeConnect write
FBeforeConnect;
property OnConnectError: TConnectErrorEvent read FOnConnectError write
FOnConnectError;
end;
type
{ TDataSet }
TDataSet = class(TBaseJSONDataSet)
private
{ private declarations }
FConnection: TConnection;
FParent: TControl;
FLeft: Integer;
FTop: Integer;
protected
{ protected declarations }
procedure SetConnection(Value: TConnection);
Function CreateFieldMapper : TJSONFieldMapper; override;
public
{ public declarations }
published
{ published declarations }
// Can be set directly if the dataset is closed. If metadata is set, it
must match the data.
Property Rows;
property Parent: TControl read FParent write FParent;
property Left: Integer read FLeft write FLeft;
property Top: Integer read FTop write FTop;
property Connection: TConnection read FConnection write SetConnection;
end;
implementation
{ TConnection }
procedure TConnection.SetActive(AValue: boolean);
begin
if ((FURI <> '') and AValue) then
begin
DoBeforeConnect();
FActive := AValue;
FReq := TJSXMLHttpRequest.new;
FReq.addEventListener('load', @onLoad);
FReq.open('GET',FURI,true);
FReq.send();
end;
end;
function TConnection.onLoad(Event: TEventListenerEvent): boolean;
var
J: JSValue;
JA: JSValue;
begin
if (FReq.status = 200) then
begin
J := TJSJSON.parse(FReq.responseText);
JA := TJSObject(J).Properties[FDataNode];
DoAfterConnect();
if (assigned(FDS)) then
begin
FDS.Rows := TJSArray(JA);
FDS.Open();
end else
DoError(FReq.status);
end;
end;
procedure TConnection.RegisterDataSet(value: TDataSet);
begin
FDS := value;
end;
procedure TConnection.DoBeforeConnect;
begin
if (assigned(FBeforeConnect)) then
FBeforeConnect(Self);
end;
procedure TConnection.DoAfterConnect;
begin
if (assigned(FAfterConnect)) then
FAfterConnect(Self);
end;
procedure TConnection.DoError(ErrorCode: Integer);
begin
if (assigned(FOnConnectError)) then
FOnConnectError(Self, ErrorCode);
end;
constructor TConnection.Create(AOwner: TComponent);
begin
inherited; //Create(AOwner);
FDS := nil;
end;
{ TDataSet }
procedure TDataSet.SetConnection(Value: TConnection);
begin
if (assigned(Value)) then
Value.RegisterDataSet(Self);
end;
Function TDataSet.CreateFieldMapper : TJSONFieldMapper;
begin
Result := TJSONObjectFieldMapper.Create;
end;
end.
-------------------------
------// project1.lpr -----
program project1;
{$mode objfpc}
uses
Classes, SysUtils, JS, Web, DB, JSONDataSet, uCDS;
var
Connection1: TConnection;
DataSet1: TDataSet;
DataSource1: TWDataSource;
procedure p1;
begin
while not DataSet1.EOF do
begin
console.log(
DataSet1.FieldByName('Species_No').AsString,
DataSet1.FieldByName('Category').AsString
);
DataSet1.Next;
end;
end;
begin
Connection1:= TConnection.Create(nil);
Connection1.Name := 'Connection1';
Connection1.Active := false;
DataSet1:= TDataSet.Create(nil);
DataSet1.Name := 'DataSet1';
DataSet1.Connection := Connection1;
DataSource1:= TWDataSource.Create(nil);
DataSource1.Name := 'DataSource1';
DataSource1.DataSet := DataSet1;
Connection1.URI := 'data.json';
Connection1.DataNode := 'data';
DataSet1.FieldDefs.Clear();
DataSet1.FieldDefs.Add('Species_No', TFieldType.ftString,0);
DataSet1.FieldDefs.Add('Category', TFieldType.ftString,50);
DataSet1.FieldDefs.Add('Common_Name', TFieldType.ftString,50);
DataSet1.FieldDefs.Add('Species_Name', TFieldType.ftString,50);
DataSet1.FieldDefs.Add('Length__cm_', TFieldType.ftInteger,0);
DataSet1.FieldDefs.Add('Length_In', TFieldType.ftString,30);
DataSet1.FieldDefs.Add('Notes', TFieldType.ftString,255);
Connection1.Active := true;
window.setTimeout(@p1, 500);
//p1;
end.
-------------------------
--
Sent from: http://pas2js.38893.n8.nabble.com/
More information about the Pas2js
mailing list