6

Im trying to send a json structure to a rest service from angular doing something like this

  let test5var = {
                    "test5var1": {
                        "test5var2": "0317",
                        "test5var3": "9556"
                    },
                    "test5var4": "123",
                    "test5var": "0000046"
                }
let dataPrincipalBlnc = {"test": {"test1": {"test2": "0317","test3": {"IDIOMA_ISO": " en","DIALECTO_ISO": "US"},"channel": "INT"},"input": {"test5": test5var}}};

let headers = new HttpHeaders();
    headers.append('Content-Type', 'application/json');

    let params = new HttpParams().set("requestData", dataPrincipalBlnc.toString()).set("authenticationType", this.authType);


    return this.http.get(this.url, {params: params}); 

The result of the request should look like follows:

https://example.com/test?authenticationType=cookie&requestData=%7B%test%22:%7B%22test1%22:%7B%22test2%22:%220317%22,%22test3%22:%7B%22IDIOMA_ISO%22:%22+en%22,%22DIALECTO_ISO%22:%22US%22%7D,%22channel%22:%22INT%22%7D,%22input%22:%7B%22test5%22:%7B%22test5var1%22:%7B%22test5var2%22:%220317%22,%22test5var3%22:%229556%22%7D,%22test5var4%22:%22123%22,%22test5var5%22:%220000986%22%7D%7D%7D%7D

But it is currently sent as:

https://example.com/test?requestData=%5Bobject%20Object%5D&authenticationType=cookie

Any ideas how can I send the json object to looks as the first request? Do I need to manually convert the json to a valid uri format?

In angularJS is working fine just using the following code:

var data = {
      "test1": {
        "test2": {
          "test3": "0317",
          "test4": {
            "IDIOMA_ISO": " en",
            "DIALECTO_ISO": "US"
          },
          "channel": "INT"
        },
        "input": {
          "test5": test5var
        }
      }
};
$http.get(url, {
      params: {
        authenticationType: authType,
        requestData: data
      }
    }).then(success(deferred), error(deferred));

I have also tried using the following code but the result is adding more characters and the backend is failling because it says the JSON is not in a valid format:

encodeURIComponent(JSON.stringify(dataPrincipalBlnc)

?requestData=%257B%2522test%2522%253A%257B%2522test1%2522%253A%257B%2522test2%2522%253A%25220317%2522%252C%2522test3%2522%253A%257B%2522IDIOMA_ISO%2522%253A%2522%2520en%2522%252C%2522DIALECTO_ISO%2522%253A%2522US%2522%257D%252C%2522channel%2522%253A%2522INT%2522%257D%252C%2522input%2522%253A%257B%2522test5%2522%253A%257B%2522test5var1%2522%253A%257B%2522test5var2%2522%253A%25220317%2522%252C%2522test5var4%2522%253A%25229556%2522%257D%252C%2522test5var4%2522%253A%2522123%2522%252C%2522test5var5%2522%253A%25220003303%2522%257D%257D%257D%257D&authenticationType=cookie

Thanks Regards

Coder
  • 2,153
  • 1
  • 16
  • 21
Endika
  • 347
  • 2
  • 5
  • 20

3 Answers3

6

Any JSON object being passed to the service should be sent via response body. You should add valid string parameters only in the url.

Also there is url size limitation for most browsers, so bigger object may lead you to the long url problem.

You are seeing the requestData=%5Bobject%20Object%5D&authenticationType=cookie because it cannot put a JSON object in url query string.

Some characters cannot be part of a URL (for example, the space) and some other characters have a special meaning in a URL: for example, the character # can be used to further specify a subsection (or fragment) of a document; the character = is used to separate a name from a value. A query string may need to be converted to satisfy these constraints. This can be done using a schema known as URL encoding.

Use JSON.stringify when you have a JavaScript Object and you want to convert it to a string (containing a JSON text). This is called serialization.

Regardless to JSON:

Use encodeURIComponent whenever you want to send "problematic" characters in the URL such as &, % etc. The opposite is decodeURIComponent.

Still i would prefer to send the object in the request body.

So in your case use:

 let params = new HttpParams()
                .set("requestData", encodeURIComponent(JSON.stringify(dataPrincipalBlnc)))
                .set("authenticationType", this.authType);
nircraft
  • 8,242
  • 5
  • 30
  • 46
  • As this is a get method I cannot send the information in the body also the backend is prepared to recieve the JSON as a parameter, I have tried what you said but the result is adding more characters and it makes the backend falis saying the JSON object is invalid. I have edited the question adding this information. Thanks – Endika Jan 15 '19 at 19:50
  • Yes, you can send a request body with GET but it should not have any meaning. If you give it meaning by parsing it on the server and changing your response based on its contents, then you are ignoring this recommendation in the HTTP/1.1 spec, section 4.3: – nircraft Jan 15 '19 at 20:06
2

Adding to @nircraft answer (which is very elaborate and good) this implementation seems to does the trick for you,

let test5var = {
                "test5var1": {
                    "test5var2": "0317",
                    "test5var3": "9556"
                },
                "test5var4": "123",
                "test5var": "0000046"
            }
let dataPrincipalBlnc = '{"test": {"test1": {"test2": "0317","test3": {"IDIOMA_ISO": " en","DIALECTO_ISO": "US"},"channel": "INT"},"input": {"test5": test5var}}}';

let headers = new HttpHeaders();
headers.append('Content-Type', 'application/json');

let params = new HttpParams().set("requestData", encodeURIComponent(dataPrincipalBlnc)).set("authenticationType", this.authType);


return this.http.get(this.url, {params: params}); 

In Javascript you can basically enclose a string in '' or "".

When you don't enclose the string specifically I believe it is enclosed with "", thus making your JSON response in need of escape characters when you use stringify.

Enclosing the string like this will make sure that the double quotes will make sure that it won't need escape characters.

Let me know if you have any questions.

Coder
  • 2,153
  • 1
  • 16
  • 21
  • I just made it worked by defining the data as an object and using later just the JSON.stringify – Endika Jan 15 '19 at 20:30
0

I just fixed the issue by defining the data as an object and using just the JSON.stringify:

let dataPrincipalBlnc: object;

let dataPrincipalBlnc = {"test": {"test1": {"test2": "0317","test3": {"IDIOMA_ISO": " en","DIALECTO_ISO": "US"},"channel": "INT"},"input": {"test5": test5var}}};

let params = new HttpParams().set("requestData", JSON.stringify(dataPrincipalBlnc)).set("authenticationType", this.authType);

Thanks for your help Regards

Endika
  • 347
  • 2
  • 5
  • 20