Hi
in the Function below i'm trying to wait until all data are loaded and event fired in Procedure PreparaOrd(...); that call wdTOrdAfterScroll and wdROrdAfterOpen too but i tested function CreaModOrdine return before all data and event are fired !!
all this code is correctly wrote ?
Thx
Function TDM0.CreaModOrdine(CodUtente:String):TJSPromise; // Ritorna il nr. ordine, -1 errore
Begin
Result:=TJSPromise.New(Procedure(ASuccess, AFailed: TJSPromiseResolver)
Var QryOrd:String;
ResData:TaStrings;
Procedure PreparaOrd(OrdPK1:Integer = 0);
Begin
Try
With wdTOrd Do Begin
OrdPK2:=0;
If OrdPK1 = 0 Then Begin // Nuovo ordine
//Close();
//SetJsonData('{}');
Open();
Insert();
FieldByName('Cod_CliFor').AsString:=CodUtente;
FieldByName('Inizio_Ins').AsDateTime:=Now();
// Raccolgo tutte le info del cliente (rawinvoke) e le metto nell'ordine
Post();
ApplyUpdates();
End Else Begin // Result > 0 c'è un ordine già aprto
//QueryString:=Format('$filter=(PK_1 eq %d)',[OrdPK1]);
Close();
QueryString:=Format('$filter=(PK_1 eq %d)&$expand=ORD_RISTO_R/PK_1',[OrdPK1]);
Load();
End;
End;
Finally
//Calc_RiepOrdine();
End;
End;
// ---------------------------------------------------------
procedure OnDataResponse(DataResponse: TXDataClientResponse);
Var OrdPK1:Integer;
Procedure MsgDlgProc(AValue: TModalResult);
Begin
If AValue = mrYes Then Begin // Apre l'ultimo ordine sospeso del cliente
// 1) Carica i dati e in wdROrdAfterOpen Apre il riepilogo
PreparaOrd(OrdPK1);
ASuccess(orMOD);
End;
If AValue = mrNo Then Begin
// 1) Elimina sul server l'ordine sospeso dall'archivio ...
QryOrd:=Format('DELETE FROM Ord_Risto_T WHERE PK_1 = %d ', [OrdPK1]);
wdcData.RawInvoke('IDataService.Call_ServiceWeb',['QRY_CMD',QryOrd,-1], Nil);
// 2) ... ne apre un altro nuovo ...
PreparaOrd(0);
ASuccess(orNEW);
End;
End;
Begin
OrdPK1:=0;
// NB : il nome del campo di ritorno è casesensitive, deve essere maiuscolo
ResData:=GetJsonValues(String(DataResponse.Result),['PK_1']);
If Length(ResData) > 0 Then
OrdPK1:=StrToInt(ResData[0]);
// Se già esiste un ordine chiede se lo si vuole riaprire gestendo i casi nella sotto procedura MsgDlgProc,
// se non esiste ne crea uno nuovo
If OrdPK1 > 0 Then
frmMain.WebMessageDlg.ShowDialog(
'Vuoi riprendere l''ultimo ordine sospeso ?'+#13#10+'(NO crea un nuovo ordine)', mtConfirmation, [mbYes, mbNo], @MsgDlgProc)
Else Begin
PreparaOrd(0);
ASuccess(orNEW);
End;
End;
Begin // promise
// Cerca un ordine già aperto per l'utente loggato, altrim. lo inserisce nuovo
QryOrd:=Format(
'SELECT PK_1 FROM Ord_Risto_T '+
'WHERE Cod_CliFor = ''%s'' AND Coalesce(Inizio_Ins,'''') <> '''' AND Coalesce(Fine_Ins,'''') = '''' ',
[CodUtente]);
(Sorry i can't delete first post and then i rewrite better my post)
Hi
in the Function below i'm trying to wait until all data are loaded and event fired in Procedure PreparaOrd(...); that call wdTOrdAfterScroll and wdROrdAfterOpen too but i tested function CreaModOrdine return before all data and event are fired !!
all this code is correctly wrote ?
Thx
Function TDM0.CreaModOrdine(CodUtente:String):TJSPromise; // Ritorna il nr. ordine, -1 errore
Begin
Result:=TJSPromise.New(Procedure(ASuccess, AFailed: TJSPromiseResolver)
Var QryOrd:String;
ResData:TaStrings;
Procedure PreparaOrd(OrdPK1:Integer = 0);
Begin
Try
With wdTOrd Do Begin
OrdPK2:=0;
If OrdPK1 = 0 Then Begin // Nuovo ordine
//Close();
//SetJsonData('{}');
Open();
Insert();
FieldByName('Cod_CliFor').AsString:=CodUtente;
FieldByName('Inizio_Ins').AsDateTime:=Now();
// Raccolgo tutte le info del cliente (rawinvoke) e le metto nell'ordine
Post();
ApplyUpdates();
End Else Begin // Result > 0 c'è un ordine già aprto
//QueryString:=Format('$filter=(PK_1 eq %d)',[OrdPK1]);
Close();
QueryString:=Format('$filter=(PK_1 eq %d)&$expand=ORD_RISTO_R/PK_1',[OrdPK1]);
Load();
End;
End;
Finally
//Calc_RiepOrdine();
End;
End;
// ---------------------------------------------------------
procedure OnDataResponse(DataResponse: TXDataClientResponse);
Var OrdPK1:Integer;
Procedure MsgDlgProc(AValue: TModalResult);
Begin
If AValue = mrYes Then Begin // Apre l'ultimo ordine sospeso del cliente
// 1) Carica i dati e in wdROrdAfterOpen Apre il riepilogo
PreparaOrd(OrdPK1);
ASuccess(orMOD);
End;
If AValue = mrNo Then Begin
// 1) Elimina sul server l'ordine sospeso dall'archivio ...
QryOrd:=Format('DELETE FROM Ord_Risto_T WHERE PK_1 = %d ', [OrdPK1]);
wdcData.RawInvoke('IDataService.Call_ServiceWeb',['QRY_CMD',QryOrd,-1], Nil);
// 2) ... ne apre un altro nuovo ...
PreparaOrd(0);
ASuccess(orNEW);
End;
End;
Begin
OrdPK1:=0;
// NB : il nome del campo di ritorno è casesensitive, deve essere maiuscolo
ResData:=GetJsonValues(String(DataResponse.Result),['PK_1']);
If Length(ResData) > 0 Then
OrdPK1:=StrToInt(ResData[0]);
// Se già esiste un ordine chiede se lo si vuole riaprire gestendo i casi nella sotto procedura MsgDlgProc,
// se non esiste ne crea uno nuovo
If OrdPK1 > 0 Then
frmMain.WebMessageDlg.ShowDialog(
'Vuoi riprendere l''ultimo ordine sospeso ?'+#13#10+'(NO crea un nuovo ordine)', mtConfirmation, [mbYes, mbNo], @MsgDlgProc)
Else Begin
PreparaOrd(0);
ASuccess(orNEW);
End;
End;
Begin // promise
// Cerca un ordine già aperto per l'utente loggato, altrim. lo inserisce nuovo
QryOrd:=Format(
'SELECT PK_1 FROM Ord_Risto_T '+
'WHERE Cod_CliFor = ''%s'' AND Coalesce(Inizio_Ins,'''') <> '''' AND Coalesce(Fine_Ins,'''') = '''' ',
[CodUtente]);
wdcData.RawInvoke('IDataService.Call_ServiceWeb',['QRY_SEL',QryOrd,-1], @OnDataResponse);
End); // promise
End;
// -----------------------------------------------------------------------------
procedure TDM0.wdOrdAfterApplyUpdates(Sender: TDataSet; Info: TResolveResults);
Var i:Smallint;
ResolveInfo:TResolveInfo;
begin
For I:=0 to Length(Info.Records)-1 Do Begin
ResolveInfo:=Info.Records[I];
//If ResolveInfo.Status = TUpdateStatus.usResolveFailed Then Begin
If ResolveInfo.Error <> '' Then Begin
frmMain.WebMessageDlg.ShowDialog(ResolveInfo.Error, mtError, [mbOk], Nil);
Exit; // al primo errore esce !
End;
End;
end;
// -----------------------------------------------------------------------------
procedure TDM0.wdTOrdNewRecord(DataSet: TDataSet);
begin
DataSet.FieldByName('ORD_RISTO_R').Value:=TJSArray.New();
end;
// -----------------------------------------------------------------------------
procedure TDM0.wdTOrdAfterScroll(DataSet: TDataSet);
begin
//frmMain.WebMessageDlg.ShowDialog(
// 'aft scroll', mtConfirmation, [mbYes, mbNo], Nil);
wdROrd.Close();
wdROrd.SetJsonData(wdTOrdORD_RISTO_R.Value);
// GetJsonValues(String(wdTOrdORD_RISTO_R.Value),[],wdROrd);
wdROrd.Open();
end;
// -----------------------------------------------------------------------------
procedure TDM0.wdROrdAfterOpen(DataSet: TDataSet);
begin
// rilevo l'ultimo progressivo rigo per event. inserimenti successivi
If DataSet.RecordCount > 0 Then Begin
DataSet.Last();
OrdPK2:=DataSet.FieldByName('PK_2').AsInteger;
End;
// Calc_RiepOrdine(); // NON USARLO QUA DA PROBLEMI
end;
// -----------------------------------------------------------------------------
procedure TDM0.wdROrdNewRecord(DataSet: TDataSet);
begin
TJSObject(wdROrd.CurrentData)['PK_1@xdata.ref']:=
Format('ORD_RISTO_T(%d)', [TJSObject(wdTOrd.CurrentData)['PK_1']]);
Inc(OrdPK2);
Dataset.FieldByName('PK_2').AsInteger:=OrdPK2;
end;
// -----------------------------------------------------------------------------
procedure TDM0.wdROrdBeforePost(DataSet: TDataSet);
begin
With Dataset Do Begin
FieldByName('Tot_Importo').AsFloat:=
FieldByName('Quantita').AsFloat * FieldByName('Prezzo').AsFloat;
FieldByName('Tot_Rigo').AsFloat:=FieldByName('Tot_Importo').AsFloat;
End;
end;
Your code is already rather complex for a simple support question, but the culprit seems to be here:
PreparaOrd(0);
ASuccess(orNEW);
PreparaOrd performs async operations (ApplyUpdates and Load), thus it returns before those operations are finished. The ASuccess is immediately called, so your promised is "finished", but the calls to ApplyUpdates and Load as still being processed.