irigsoft Posted June 11, 2021 Share Posted June 11, 2021 Hello. How is possible to wait until javascript function on client side stop execution or return value in AjaxEvent I use this on uniButton.OnClick var myMemo : TuniMemo begin UniSession.AddJS (' var xhttp = new XMLHttpRequest();' + ' xhttp.timeout = 2000;' // time in milliseconds + ' xhttp.onreadystatechange = function() {' + ' if (this.readyState == 4 && this.status == 200) {' + ' var sRes = this.responseText;' + ' ajaxRequest (' + myMemo.JSName + ' , "FiscalAnswer", ["_value=" + sRes,"_cmd=" + "' + sCMD + '"])' + ' ;' + ' }' + ' };' + ' xhttp.open("GET", ''' + fURL + TRIM (UniMainModule.URLCommands.Text) + ''', true);' + ' xhttp.send();' ); end; myMemo.OnAjaxEvent begin TRY if EventName = 'FiscalCMD' then begin FiscalCMD := params.values['_cmd']; end; if EventName = 'FiscalAnswer' then begin FiscalCMD := params.values['_cmd']; TuniMemo(Sender).Text := params.values['_value']; UniMainModule.onError := (POS ('<Err Source=',params.values['_value']) > 0); If not DirectoryExists (ExtractFileDir(Application.ExeName) + '\Log\Tremol\') then ForceDirectories(ExtractFileDir(Application.ExeName) + '\Log\Tremol\'); TuniMemo(Sender).Lines.SaveToFile(ExtractFileDir(Application.ExeName) + '\Log\Tremol\' + FiskalDevice.ID + '_' + FormatDateTime('ddMMyyyy',Now,UniServerModule.MySettings) + '.log'); //RetAnswer; If (UniMainModule.URLCommands.Count > 0) AND (not UniMainModule.onError) then begin UniMainModule.URLCommands.Delete (0); end; UniMainModule.onprint := False; end; EXCEPT on e:Exception do Dialogs.ShowMessage (EventName + ' - ' + e.message); END; end; I want server to wait untill on ajaxevent ocure Quote Link to comment Share on other sites More sharing options...
Sherzod Posted June 11, 2021 Share Posted June 11, 2021 Hello, This post may help you: Quote Link to comment Share on other sites More sharing options...
irigsoft Posted June 11, 2021 Author Share Posted June 11, 2021 1 hour ago, Sherzod said: Hello, This post may help you: Thank You. Is there some documentation for UniSession.SendResponse(); ? Quote Link to comment Share on other sites More sharing options...
andyhill Posted June 11, 2021 Share Posted June 11, 2021 +1 Quote Link to comment Share on other sites More sharing options...
irigsoft Posted June 12, 2021 Author Share Posted June 12, 2021 Can I use Promise (from here: https://usefulangle.com/post/383/javascript-wait-multiple-ajax-requests-to-finish) to make the server wait for the client to return the response to AjaxEvent ? Quote Link to comment Share on other sites More sharing options...
Sherzod Posted June 12, 2021 Share Posted June 12, 2021 55 minutes ago, irigsoft said: Can I use Promise (from here: https://usefulangle.com/post/383/javascript-wait-multiple-ajax-requests-to-finish) to make the server wait for the client to return the response to AjaxEvent ? Well, I think so. Have you tried? Quote Link to comment Share on other sites More sharing options...
irigsoft Posted June 12, 2021 Author Share Posted June 12, 2021 6 minutes ago, Sherzod said: Well, I think so. Have you tried? No. But I get that my javascript function sometime have not return answer, just get respont = 200 . So I catch this on ajax event. mymemo.onAjaxEvent: begin TRY if EventName = 'FiscalCMD' then begin FiscalCMD := params.values['_cmd']; end; if (EventName = 'NoFiscalAnswer') then begin FiscalCMD := params.values['_cmd']; TuniMemo(Sender).Text := 'ANSWER=' + params.values['_value']; uniMainModule.onprint := False; //go to the next command in list If (UniMainModule.URLCommands.Count > 0) and (not UniMainModule.onError) then begin uniMainModule.SendtoFiscalDevice (TuniMemo(Sender),UniMainModule.URLCommands [0]); end; end; if EventName = 'FiscalAnswer' then begin TRY FiscalCMD := params.values['_cmd']; TuniMemo(Sender).Text := params.values['_value']; if TRIM (TuniMemo(Sender).Text) <> '' then begin UniMainModule.onError := (POS ('<Err Source=',params.values['_value']) > 0); If not DirectoryExists (ExtractFileDir(Application.ExeName) + '\Log\Tremol\') then ForceDirectories(ExtractFileDir(Application.ExeName) + '\Log\Tremol\'); TuniMemo(Sender).Lines.SaveToFile(ExtractFileDir(Application.ExeName) + '\Log\Tremol\' + FiskalDevice.ID + '_' + FormatDateTime('ddMMyyyy',Now,UniServerModule.MySettings) + '.log'); end; EXCEPT on e:Exception do Dialogs.ShowMessage (EventName + ' - ' + e.message); END; uniMainModule.onprint := False; //go to the next command in list If (UniMainModule.URLCommands.Count > 0) and (not UniMainModule.onError) then begin uniMainModule.SendtoFiscalDevice (TuniMemo(Sender),UniMainModule.URLCommands [0]); end; end; EXCEPT on e:Exception do Dialogs.ShowMessage (EventName + ' - ' + e.message); END; end; my javascript function on button.Click begin UniSession.AddJS (//'function loadDoc() {' + //old function use var xhttp = new XMLHttpRequest(); - end cause the problem //, now i use let xhttp = new XMLHttpRequest(); - end all it's OK ' let xhttp = new XMLHttpRequest();' + ' xhttp.timeout = 2000;' // time in milliseconds + ' xhttp.onreadystatechange = function() {' + ' if (this.readyState == 4 ) { ' + ' if (this.status == 200) {' + ' var sRes = this.responseText;' //+ ' alert ("HAVE responce");' + ' ajaxRequest (' + myMemo.JSName + ' , "FiscalAnswer", ["_value=" + sRes,"_cmd=" + "' + sCMD + '"]);' + ' } else {' //+ ' alert ("NO responce");' + ' ajaxRequest (' + myMemo.JSName + ' , "NoFiscalAnswer", ["_value=" + "OK","_cmd=" + "' + sCMD + '"]);' + ' };' + ' };' + ' };' + ' xhttp.open("GET", ''' + fURL + TRIM (cmd) + ''', true);' + ' xhttp.send();' ); ); end; Quote Link to comment Share on other sites More sharing options...
Sherzod Posted June 12, 2021 Share Posted June 12, 2021 Okay. Were you able to achieve the result? Quote Link to comment Share on other sites More sharing options...
irigsoft Posted June 12, 2021 Author Share Posted June 12, 2021 10 minutes ago, Sherzod said: Okay. Were you able to achieve the result? Yes. this make the magic : 'let xhttp = new XMLHttpRequest();' Quote Link to comment Share on other sites More sharing options...
irigsoft Posted June 16, 2021 Author Share Posted June 16, 2021 Hello, @Sherzod I'm sorry, but I still have a problem getting information from the client. The procedure works, but the server executes code and does not block. So, I have this logic: 1. For a loop in a server 2. JSCode (Send url to device). I use Promises and XhttpRequest 3. in ajaxevent waiting for a response from the client 4. if the answer is true, go to the next one in the cycle from point 1. This loop has a ShowMessage (intToStr (I)) for each step of the loop, but I get it once with the last value of the loop. I even use ShowMask on ButtonClick. Quote Link to comment Share on other sites More sharing options...
Sherzod Posted June 16, 2021 Share Posted June 16, 2021 20 minutes ago, irigsoft said: The procedure works, but the server executes code and does not block. Hello, Perhaps you'd better combine with this? http://unigui.com/doc/online_help/synch-and-asynch-operations.htm Quote Link to comment Share on other sites More sharing options...
irigsoft Posted June 16, 2021 Author Share Posted June 16, 2021 14 minutes ago, Sherzod said: Hello, Perhaps you'd better combine with this? http://unigui.com/doc/online_help/synch-and-asynch-operations.htm Thank You, this is for Showmodal. Buf if I want to wait until onajaxevent ocure (or exact Eventname in ajaxevent) to proceed with loop ? Quote Link to comment Share on other sites More sharing options...
Sherzod Posted June 16, 2021 Share Posted June 16, 2021 1 minute ago, irigsoft said: Buf if I want to wait until onajaxevent ocure (or exact Eventname in ajaxevent) to proceed with loop ? Sorry, сan you make a small test case for the whole process, for a better understanding!? Quote Link to comment Share on other sites More sharing options...
irigsoft Posted June 16, 2021 Author Share Posted June 16, 2021 just function will post here. uniMainModule - public UniMainModule.URLCommands : TStringList; on btnclik to start loop: procedure TUniForm_FiscalSettings.UniButton1Click(Sender: TObject); var sList : Integer; begin sList := 0; FiskalDevice.ID := ''; FiskalDevice.MFP := ''; UniMainModule.onPrint := False; UniMainModule.onError := False; repeat Inc (sList); if UniCheckBox_CheckIfConnected.Checked then begin UniComboBox_FiscalID.ItemIndex := sList; end; //1 step - send settings to device UniMainModule.URLCommands.Clear; UniMainModule.URLCommands.Add ('/settings(com="' + UniComboBox_FiscalID.Text + '",tcp=0)'); UniMainModule.SendtoFiscalDevice_DirectAPI (uniMemo_Fisc,UniMainModule.URLCommands [0]);//procedure on client side //2 step - if result from 1 step then get device ID UniMainModule.URLCommands.Clear; UniMainModule.URLCommands.Add ('/ReadSerialAndFiscalNums()'); UniMainModule.SendtoFiscalDevice_DirectAPI (uniMemo_Fisc,UniMainModule.URLCommands [0]);//procedure on client side //send next command to device UniMainModule.URLCommands.Clear; UniMainModule.URLCommands.Add ('/PaperFeed()'); UniMainModule.SendtoFiscalDevice_DirectAPI (uniMemo_Fisc,UniMainModule.URLCommands [0]); //procedure on client side //if have result from 2 step showmessage - just for test ! if FiskalDevice.ID > '' then begin ShowMessage ('Fisc ID: ' + FiskalDevice.ID); break; end; if FiskalDevice.ID <> '' then begin end; until (sList > UniComboBox_FiscalID.Count-1) OR (FiskalDevice.ID <> ''); end; Quote Link to comment Share on other sites More sharing options...
irigsoft Posted June 16, 2021 Author Share Posted June 16, 2021 procedure on client side declared in uniMainModule: UniMainModule.SendtoFiscalDevice_DirectAPI (uniMemo_Fisc,UniMainModule.URLCommands [0]); //procedure on client side var sCMD, fURL : string; begin If (TRIM (cmd) <> '') //AND (not uniMainModule.onprint) //OR (not uniMainModule.onError) then begin TRY sCMD := StringReplace (COPY (cmd,2,POS ('(',cmd)-2),'"','',[rfReplaceAll]); fURL := UniServerModule.SistemSettingsList.Values ['PrintServer_URL']; UniMainModule.onprint := True; myMemo.Clear; //jQuery // UniSession.addJS ('$.get(''' + fURL + TRIM (cmd) + ''', function(responseText) {' // + ' var sRes = responseText;' // //+ ' alert ("HAVE responce:" + sRes);' // + ' ajaxRequest (' + myMemo.JSName // + ' , "FiscalAnswer", ["_value=" + sRes,"_cmd=" + "' + sCMD + '"]);' // + '});' // ); //execute XMLHttpRequest UniSession.AddJS (' new Promise(function(resolve, reject) {' + ' let xhttp = new XMLHttpRequest();' + ' xhttp.timeout = 2000;' // time in milliseconds + ' xhttp.onreadystatechange = function() {' + ' if (this.readyState == 4 ) { ' + ' if (this.status == 200) {' //must wait this to return onajaxevent + ' var sRes = this.responseText;' + ' ajaxRequest (' + myMemo.JSName + ' , "FiscalAnswer", ["_value=" + sRes,"_cmd=" + "' + sCMD + '"]);' + ' } else {' + ' ajaxRequest (' + myMemo.JSName + ' , "NoFiscalAnswer", ["_value=" + "OK","_cmd=" + "' + sCMD + '"]);' + ' };' + ' resolve(this.responseText);' + ' };' + ' };' + ' xhttp.open("GET", ''' + fURL + TRIM (cmd) + ''', false);' //set to false to make server wait util client finish + ' xhttp.send(null);' + '});'//end Promise ); EXCEPT //on E: Exception do Dialogs.ShowMessage ('SendtoFiscalDevice ERROR: ' + e.Message);//uniMainModule.onprint := False; END; If (UniMainModule.URLCommands.Count > 0) AND (not UniMainModule.onError) then begin UniMainModule.URLCommands.Delete (0); cmd := ''; end; end; Quote Link to comment Share on other sites More sharing options...
irigsoft Posted June 16, 2021 Author Share Posted June 16, 2021 on ajavaevent in myuniMemo on MainForm if EventName = 'FiscalAnswer' then begin TRY FiscalCMD := params.values['_cmd']; TuniMemo(Sender).Text := 'ANSWER=' + params.values['_value']; if TRIM (TuniMemo(Sender).Text) <> '' then begin UniMainModule.onError := (POS ('<Err Source=',TuniMemo(Sender).Text) > 0); //if return error If (UniMainModule.onError) then begin UniMainModule.FiscalErrorTxt := TuniMemo(Sender).Text; //UniSession.AddJS('alert (' + params.values['_value'] + ')') end; RetAnswer; //procedure work on aswer UniMainModule.onprint := False; end; EXCEPT //on e:Exception do Dialogs.ShowMessage (EventName + ' - ' + e.message); END; //go to execute next command in list If (UniMainModule.URLCommands.Count > 0) //and (not UniMainModule.onError) then begin uniMainModule.SendtoFiscalDevice_DirectAPI (TuniMemo(Sender),UniMainModule.URLCommands [0]); end; end; EXCEPT //on e:Exception do Dialogs.ShowMessage (EventName + ' - ' + e.message); END; Quote Link to comment Share on other sites More sharing options...
irigsoft Posted June 16, 2021 Author Share Posted June 16, 2021 Here is the situation in real life: 1. uniGui StandAllone server 2. Android device (android WebView with uniGui application started on it) or on mobile browser 3. Android third party server (application server to comunicate to device) instaled on Android device (same as pont 2) 4. UniGui Application send commands to point 3 with XHttpRequest url: http://localhost:4444/settings (com=deviceID,tcp=0); - no answer from point 3 send next commmand: url http://localhost:4444/getDeviceinfo(); - must WAIT answer from point 3 when answer comming on ajaxevent, send next command http://localhost:4444/PaperFeed(); - must WAIT answer from point 3 Quote Link to comment Share on other sites More sharing options...
irigsoft Posted June 16, 2021 Author Share Posted June 16, 2021 20 minutes ago, Sherzod said: Sorry, сan you make a small test case for the whole process, for a better understanding!? I posted all the features and logic, I hope that's enough Quote Link to comment Share on other sites More sharing options...
irigsoft Posted June 16, 2021 Author Share Posted June 16, 2021 @Sherzod I am sorry, is there a functionallity like Synchronize(Wait : boolean) and Synchronize(Delay : integer), but Synchronize(Wait : boolean) - wait for some variable value? I see on documentation that Synchronize(Wait : boolean) for user interaction. Quote Link to comment Share on other sites More sharing options...
Hayri ASLAN Posted June 16, 2021 Share Posted June 16, 2021 19 minutes ago, irigsoft said: @Sherzod I am sorry, is there a functionallity like Synchronize(Wait : boolean) and Synchronize(Delay : integer), but Synchronize(Wait : boolean) - wait for some variable value? I see on documentation that Synchronize(Wait : boolean) for user interaction. Hello Please check UniSweetAlert.Execute function. You will understand how we are waiting for the result in the thread. 1 Quote Link to comment Share on other sites More sharing options...
irigsoft Posted June 16, 2021 Author Share Posted June 16, 2021 5 minutes ago, Hayri ASLAN said: Hello Please check UniSweetAlert.Execute function. You will understand how we are waiting for the result in the thread. Thank You, I will. Quote Link to comment Share on other sites More sharing options...
irigsoft Posted June 16, 2021 Author Share Posted June 16, 2021 I did a few tests with the suggestions from here, but I think the example expects user interaction, maybe I'm wrong. In my case I start a cycle from the server, which has 5 steps, on each a function is started by the user addJS, without interaction with the user (the Mask is visible) the server expects a response in the variable "print", and the response from the finished function I catch in "onajaxevent". I would like not to run step 2 of the cycle until I get the answer from step 1. Now I'm experimenting with a combo box. I start server procedure with onbuttonClick. There are 5 values in it, for each of them I perform the function on the part of the user, which must return the third value in the list and the server to stop the cycle. In this situation visually I get: The last value is loaded in the list and in one memo field I see how the results of the function are scrolled for all steps for I := 0 to Combobox.Count - 1 do begin Combobox.ItemIndex := I; //start my clientside procedure - uniMemo.onajaxevent if ResultofClient = 3 then break; end; Solution : UniMainModule.EnableSynchronousOperations must be true, to refresh combox on client Side. Quote Link to comment Share on other sites More sharing options...
irigsoft Posted June 23, 2021 Author Share Posted June 23, 2021 Using Promise with asynchronous = false, do whatever it takes. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.