Jump to content
Jean Vandromme

MARS, angular, firedac, json

Recommended Posts

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

Share this post


Link to post

Hi @Jean Vandromme,

I am sorry to have so little time to help you these days. Hope will get some more next week.

In the meantime, please try to examine the XHR request made by Angular in the Chrome development tools.

In the "Network" pane of Chrome's Development tools you should see the http call that fails.

Right click on the request (in the left panel) and select "Copy -> Copy as cURL") then paste it here. It should look like:

curl 'https://en.delphipraxis.net/topic/1091-mars-angular-firedac-json/' ' -H 'Origin: https://en.delphipraxis.net' -H 'Accept-Encoding: gzip, deflate, br' -H 'Accept-Language: it-IT,it;q=0.9,en-US;q=0.8,en;q=0.7' -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.131 Safari/537.36' -H 'Content-Type: application/x-www-form-urlencoded; charset=UTF-8' -H 'Accept: application/json, text/javascript, */*; q=0.01' -H 'Referer: https://en.delphipraxis.net/topic/1091-mars-angular-firedac-json/' -H 'X-Requested-With: XMLHttpRequest' -H 'Connection: keep-alive' --compressed

 

 

This may help as we can check together if there's some particularities in the actual request.

Another thing you should try is to debug the REST server in Delphi. Remember to select the "Debug" configuration for your Delphi project (this should also add some more specific informations to the error message you are getting).

 

Hope to hear from you soon.

 

Sincerely,

Andrea

Share this post


Link to post

Here is the XHR request

 

curl "http://localhost:8080/rest/default/maindata/employees" -H "Accept: application/json, text/plain, */*" -H "Referer: http://localhost:4200/employees-list" -H "Origin: http://localhost:4200" -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.131 Safari/537.36" --compressed

Share this post


Link to post

The differences between the 2 responses (array vs no array) from MARS is the content-type:

with array: Content-Type=*/*

without array: Content-Type=text/plain; charset=ISO-8859-1

Share this post


Link to post

Do you have a chance to debug the server (run the server application with the debugger)?

Or at least recompile the server in Debug configuration (that should give us some more error details, more than "Internal server error").

 

I think the problem may be that Accept value...

 

Sincerely,

Andrea 

Share this post


Link to post

There's a DOMException with message 'Microsoft MSXML is not installed' ?

MSXML 3,4,5 and 6 are installed

I run a Windows 10 Family OS

 

Share this post


Link to post

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

  

Share this post


Link to post

Glad you worked around this.

I believe (I need to replicate this and investigate a bit) the Accept header sent from Angular matches also some MARS XML serializer.

 

Will let you know here as soon as I figure out what's happening.

 

Thanks!

 

Andrea

Share this post


Link to post
On 5/16/2019 at 6:24 PM, Andrea Magni said:

I believe (I need to replicate this and investigate a bit) the Accept header sent from Angular matches also some MARS XML serializer.

Will let you know here as soon as I figure out what's happening.

 

 

It turned out it was the wildcard in the Accept header to cause this.

I just pushed a fix that should also apply to your case and you may no longer need to instruct the Accept header all the times.

Branch: develop, link to the commit: https://github.com/andrea-magni/MARS/commit/b8d5768b65072ff403de3c60e17688e8e95b1d9a

 

Sincerely,

Andrea

  • Like 1

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×