Easily Make Asynchronous REST Calls In Delphi 10.2.1 Tokyo On Android, iOS, macOS, and Windows 10

by Oct 8, 2017

The Hospitality Survey App template contains a RAD Server project and a Delphi client project. You can download the Hospitality Survey App template code for yourself from Embarcadero's GetIt. The Delphi client project makes REST calls via the BaaS components to RAD Server. Keep in mind that this same source code will work with TRESTClient and TNetHTTPClient. It is beneficial for the REST calls to be made in an asynchronous way because the interface stays responsive and on some platforms like Android it is required that HTTP calls are made asynchronously.

There are quite a few different ways to achieve asynchronous calls using the various libraries and functionality built into Delphi 10.2.1 Tokyo. The below source code is one way to make asynchronous calls that I found which worked for me. It uses the Parallel Programming Library with it's TTask object in this case. If you're interested in more on how TTask works check out this tutorial as well. It includes examples of pausing and canceling tasks.

In the below code a TTask is used to create a thread where the BackendEndpointGet component calls it's Execute method. The BackendEndpointGet.Tag property is used to store whether the BackendEndpointGet component is in use or not (BUSY or NOT_BUSY) so that two calls can not be made on the same component at the same time. The activity dialog is show prior to starting the Task. The Execute method is synchronous but it is inside of the Task so it doesn't block the app UI and the activity dialog displays nicely over it. Once the Execute method completes the code checks that the response code from the call is the HTTP 200 code. If it is then is proceeds to save out the contents of the response to a JSON file. TThread.Synchronize() is then used to make sure that any changes to the UI take place within the main thread. In this case the JSON file is loaded into a TFDMemTable and then the dynamic survey form is built using the GenerateSurvey() procedure from the contents of the TFDMemTable.

After all of the data is loaded or an exception is encountered the activity dialog is hidden again and the hide activity dialog procedure is within a TThread.Synchronize call as well so that the changes to the UI are main from within the main thread.

As I previously started there are a lot of different ways to do this but this is one way I found that worked for me. Check out the source code below!

//
//
  const
    BUSY = 1;
    NOT_BUSY = 0;
//
procedure TMainForm.TakeSurveyActionExecute(Sender: TObject);
var
  SL: TStringList;
begin
  if BackendFrame.BackendEndpointGet.Tag = NOT_BUSY then
  begin
    BackendFrame.BackendEndpointGet.Tag := BUSY;
    ShowActivity;
    ITask(TTask.Create(
      procedure
      begin
        try
          BackendFrame.BackendEndpointGet.Execute;
          if BackendFrame.BackendEndpointGet.Response.StatusCode = 200 then
          begin
            SL := TStringList.Create;
            SL.Text := BackendFrame.BackendEndpointGet.Response.Content;
            SL.SaveToFile(SettingsFilePath + 'surveys.json');
            SL.Free;
            TThread.Synchronize(nil,
              procedure
              begin
                FDMemTableForm.LoadFromFile(SettingsFilePath + 'surveys.json', sfJSON);
                FDMemTableForm.Open;
                FDMemTableForm.First;
                SurveyVSB := TVertScrollBox.Create(Self);
                SurveyVSB.Parent := SurveyTabItem;
                SurveyVSB.Align := TAlignLayout.Client;
                GenerateSurvey(SurveyVSB);
                ChangeTabAction.Tab := SurveyTabItem;
                ChangeTabAction.ExecuteTarget(Self);
              end);
          end;
        finally
          TThread.Synchronize(nil,
            procedure
            begin
              HideActivity;
            end);
          BackendFrame.BackendEndpointGet.Tag := NOT_BUSY;
        end;
      end)).Start;
  end;
end;

Want more info about how the Hospitality Survey App template works? Check out the full Developers Guide in this video.