Jump to content

Jean Vandromme

Members
  • Content Count

    12
  • Joined

  • Last visited

Posts posted by Jean Vandromme


  1. You were right (again, like always 🙂

    I add in my GET call in angular an option for content:

     

      httpOptions = {
        headers: new HttpHeaders({
          'Content-Type': 'application/json',
          'Accept': 'application/json'
        })
      }  

      getEmployees(): Observable<any> {
        return this.http.get<any>('http://localhost:8080/rest/default/maindata/employees', this.httpOptions)
        .pipe(
          tap(data => console.log(data))
        );
      }

     

    and now, I get a correct json array in angular:

    image.thumb.png.4fb928422f56473a53400cc81fea16f2.png

     

    I still don't understand why it is necessary in one case and not the other ?

     

    Thanks again,

    Hope it will help others

      


  2. I try since several days now to get a json array from a dataset query from a MARS server (FiredacBasic demo)

    If I use a simple dataset like this:

    [GET, Path('/employees'), Produces(TMediaType.APPLICATION_JSON), IsReference]
    function getEmployees: TFDDataSet;

     

    function TMainDataResource.getEmployees: TFDDataSet;
    begin
      Result := qEmployees;
    end;

     

    I get this in chrome:

    employeesJSON.thumb.JPG.d8fa0dc82bd9bba7a5710b241b8490bf.JPG

     

    this in Postman:

    employeesJSONPostman.JPG.c773a483bc891a21dfac065a13b3f405.JPG

     

    this error in Angular with a simple call like this:

      getEmployees(): Observable<Employee> {
        return this.http.get<Employee>('http://localhost:8080/rest/default/maindata/employees')
        .pipe(
          tap(data => console.log(data))
        );
      }

     employeesJSONAngular.thumb.JPG.dc7e22067d23c1b6d7941128f494e6bb.JPG

     

    If I use a datasets array:

    [GET, Path('/employees'), Produces(TMediaType.APPLICATION_JSON), IsReference]
     function getEmployees: TArray<TFDDataSet>;

     

    function TMainDataResource.getEmployees: TArray<TFDDataSet>;
    begin
      Result := [qEmployees];
    end;

     

    I get this in chrome:

    arrayEmployeesJSON.JPG.353d527ee835b5694b26606317c5f67b.JPG

     

    this in postman:

    arrayEmployeesJSONPostman.JPG.2ce8aa394ef65aaecde505b6fef6d0b3.JPG

     

    and no error in angular:

    arrayEmployeesJSONAngular.thumb.JPG.0bb712705ec687e736073b68932cb7a2.JPG

     

    Any clue how to solve this ?

     

    Thanks


  3. Hi,

    It seems I have the same problem you had but can't solve it.

    How did you pratically get it solved ?

    CORS is activated but I keep getting an internal server error in angular but not in Postman

    I get my json array in chrome also without any issues, so ...

     

    Thanks a lot

     

    Jean


  4. Thanks Andrea but it seems I have to do something more to get rid of a 500 server error.

    I try to acces the FireDac server demo through an angular frontend. I had first a CORS problem which is now resolved. But now I have a 500 internal error server when a I try a simple get for the employee table.

    I can access it with Postman without any problem. 

    I add this in the Form.create of server.forms.main.pas:

     

      // MARS-Curiosity Engine
      FEngine := TMARSEngine.Create;
      try
        FEngine.Parameters.LoadFromIniFile;
        FEngine.AddApplication('DefaultApp', '/default', ['Server.*']);
        PortNumberEdit.Text := FEngine.Port.ToString;
        TMARSFireDAC.LoadConnectionDefs(FEngine.Parameters, 'FireDAC');

        FEngine.BeforeHandleRequest :=
        function (const AEngine: TMARSEngine;
          const AURL: TMARSURL; const ARequest: IMARSRequest; const AResponse: IMARSResponse;
          var Handled: Boolean
        😞 Boolean
        begin
          //Result := True;
          if SameText(AURL.Document, 'favicon.ico') then
          begin
            Result := False;
            Handled := True;
          end;

          // Handle CORS and PreFlight
          if SameText(ARequest.Method, 'OPTIONS') then
          begin
            Handled := True;
            Result := False;
          end;

          Result := True;
        end;

        StartServerAction.Execute;
      except
        FreeAndNil(FEngine);
        raise;
      end;
     

    This is the headers response in POSTMAN

     

    Connection close
    Content-Type application/json
    Content-Length 2420
    Date Tue, 14 May 2019 13:25:39 GMT
    Access-Control-Allow-Origin *
    Access-Control-Allow-Methods HEAD,GET,PUT,POST,DELETE,OPTIONS
    Access-Control-Allow-Headers X-Requested-With,Content-Type,Authorization
    In chrome, I have a 500 internal error server

  5. Hi Andrea,

    Thanks a lot, I know where I have to go now. I will loose some interesting MARS features doing so but if it's the only way.

    The problem with the 2d approach is that I have tables with a lot of columns (more than 100), and I thought I could avoid making models for all of them.

    One thing though, what do you mean by TRecord<TItem>.ToDataset implementation ? Is it a Firedac thing or a MARS thing ?

     

    Thanks

     

    Jean


  6. Hi,

    I would like to develop a frontend using Angular.

    I have a MARS server, which works well for GET calls with a FB FireDac DB. Since my frontend isn't a delphi client, I use a simple json format and not json/firedac input/output.

    I struggle a little bit with the POST calls. I try to post with POSTMAN. Which json format do I have to use to get an update of my DB ?

    For now, I have a 'Database not found' from my server.

     

    Part of my code:

    type
      [Path('/maindata')]
      TMainDataResource = class(TMARSFDDataModuleResource)
        FDGUIxWaitCursor1: TFDGUIxWaitCursor;
        qItems: TFDQuery;
        qOneItem: TFDQuery;
        conDB: TFDConnection;
      private
      protected
        [Context] FD: TMARSFireDAC;
      public
        [GET, Path('/allItems'), Produces(TMediaType.APPLICATION_JSON), IsReference]
        function getAllItems: TArray<TFDDataSet>;
        [POST, Path('/allItems'), Consumes(TMediaType.APPLICATION_JSON), IsReference]
        function postAllItems([BodyParam] const ADeltas: TArray<TFDMemTable>):TArray<TMARSFDApplyUpdatesRes>;
        [GET, Path('/oneItem'), Produces(TMediaType.APPLICATION_JSON), IsReference]
        function getOneItem: TArray<TFDDataSet>;
        [POST, Path('/oneItem'), Consumes(TMediaType.APPLICATION_JSON), IsReference]
        function postOneItem([BodyParam] const ADeltas: TArray<TFDMemTable>):TArray<TMARSFDApplyUpdatesRes>;
      end;

    implementation

    {%CLASSGROUP 'Vcl.Controls.TControl'}

    {$R *.dfm}

    uses
      MARS.Core.Registry;

    { TMainDataResource }

    function TMainDataResource.getAllItems: TArray<TFDDataSet>;
    begin
      Result := [qItems];
    end;

    function TMainDataResource.postAllItems([BodyParam] const ADeltas: TArray<TFDMemTable>):TArray<TMARSFDApplyUpdatesRes>;
    begin
      Result:=FD.ApplyUpdates([qItems], ADeltas);
    end;

    function TMainDataResource.getOneItem: TArray<TFDDataSet>;
    begin
      FD.InjectParamValues(TFDAdaptedDataSet(qOneItem).Command);
      Result := [qOneItem];
    end;

    function TMainDataResource.postOneItem([BodyParam] const ADeltas: TArray<TFDMemTable>):TArray<TMARSFDApplyUpdatesRes>;
    begin
      Result:=FD.ApplyUpdates([qOneItem], ADeltas);
    end;

     

    The json structure for POST:

    {

      "qItems": [

      {

        "id": 1,

        "name": "stuff"

      },

      {

        "id": 2,

        "name": "other stuff"

      }

      ]

    }

     

    which is in fact the same structure I get from the GET calls.

    What can I do to get it work ?

     

    Thanks,

     

    Jean

     

×