Angular 7 HTTP GET send JSON object as a parameter - json

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

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);

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.

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

Related

typescript - load json from url and get access to array of json objects

I just can't find a working solution and implement in my format.
There is a JSON file which is returned to me by URL. Its format is:
{"success":true,
"data":[
{
"loadTimestamp":"2022-07-20T15:12:35.097Z",
"seqNum":"9480969",
"price":"45.7",
"quantity":"0.2",
"makerClientOrderId":"1658329838469",
"takerClientOrderId":"1658329934701"
},
{
"loadTimestamp":"2022-07-20T14:49:11.446Z",
"seqNum":"9480410",
"price":"46",
"quantity":"0.1",
"makerClientOrderId":"1658328403394",
"takerClientOrderId":"0"
}]
}
Due to the fact that it is returned via the URL, it is not possible to directly use the object, for example:
myobj['data']['price']
I have either a string of data that I can convert using JSON.parse() or an object right away.
But for some reason I can't use it directly.
As far as I understand, this is a JSON file inside which is an array of JSON data.
My goal is to display all the data from the array, while taking for example 2 values: price, quantity
How can I access the values that I want to get?
Ok I find, what I was looking for.
I return result not in json, but in text response.text()
After I did this, I create a new constant called res and put in it JSON.parse(data)
const url = 'https://myurl.com/'+pub_key
const response = await fetch(url)
let data = ''
if (response.ok) { data = await response.text() } else { console.log("Error HTTP: " + response.status) }
const res = JSON.parse(data)
After all this manipulations I can use my data with 2 ways:
console.log(res["data"][0]["price"])
console.log(res.data[0].price)
Or I can make a cocktail from it, by using my favorite blender :)))
if(res.success==true){
for(let item in res.data){
console.log(res.data[item].price,res.data[item].quantity)
}
}

json.stringify is adding extra backslashes in res.send()

My API needs to return the following data in it's response.
{ users: 'All users are as follows: [{id: 1}, {id: 2}]'}
It should be a json object with one of the key values is a json array. However, the json array is turned into a string because it needs to be appended onto another string. My code is like this:
const array = [{id: 1}, {id:2}]
const string = 'All users are as follows: ' + JSON.stringify(array)
res.send({users: string})
I use Express for my API. When I check the response in postman it add many backslashed onto the string. However, when I do console.log({a: string}) locally, I don't see any of those slashes.
this is what I see:
{users: "[{\"id\":1}, {\"id\":2}]"}
{users: "[{\"id\":1}, {\"id\":2}]"}
is the json representation of response , in json string is represented by enclosing it with double quotes (") and so if the string itself contains double quotes then it should be escaped.
{ "user": " "name" " } , is invalid you should use { "user" : "\"name\""}
when you print it in console it prints only the escaped charater thats why you don't see " but ".
learn more about javascript grammer at :
https://www.crockford.com/mckeeman.html
when you use JSON.stringify() it converts it into valid JSON string , you cannot send it without it because it will send it as javascript object and not as valid json. using
res.send ({name:"test"}} will send response as [object][object]
so the only way to get what you want is to send the response as text and not JSON:
const array = [{id: 1}, {id:2}]
const string = 'All users are as follows: ' + JSON.stringify(array)
res.send(`{users: "${string}" }`)
here in res.send isntead of {users:string} , we are using "users:string" .
NOTE: its not valid JSON
Output:
Could you please post your code on returning your response.
Anyways, I do it this way.
let object = {name: "Juan Dela Cruz"}
res.send(object)

How to read a JSON object with a full-stop in the name using POSTMAN?

I have a problem trying to check a JSON value in the response body using POSTMAN because the JSON object name has a full-stop in it
Usually a JSON response body would be something like this:
{
"restapi": "Beta",
"logLevel": "INFO"
}
So normally we can do a test on the JSON value like this using POSTMAN:
pm.test("Your test name", function () {
var jsonData = pm.response.json();
pm.expect(jsonData.restapi).to.eql(Beta);
});
But the problem I'm having now is that the JSON object name has a full stop like this
{
"restapi.name": "Beta",
"logLevel.sleep": "INFO"
}
So if I try to do read the object like this, it will come out with an error
pm.test("Your test name", function () {
var jsonData = pm.response.json();
pm.expect(jsonData.restapi.name).to.eql(Beta);
});
You can just reference the key value by using brackets around the name:
jsonData["restapi.name"]
object properties can be accessed with . operator or with associative array indexing using []. ie. object.property is equivalent to object["property"]
this should do the trick
jsonData["restapi.name"]

Alamofire string parameter hardcoded works but passing as string parameter does not

I'm attempting to make a Alamofire service call to retrieve a list of items in JSON. The issue I am having is that anytime I type in a special character: such as ' it somewhere resolves the string a unicode string while sending the request. When I type in o'sheas its coming back that I'm searching O\U2019sheas
func sendGetRequest(passedInString: String) {
PARAMETERS["searchTxt"] = passedInString
Alamofire.request(URL, method: .get , parameters: PARAMETERS, headers: HEADER)
.validate(statusCode: 200..<400)
.responseJSON { response in
debugPrint(response.request!)
switch response.result {
// GETTING NO RESULTS BECAUSE THE REQUEST IS TURNING the o'sheas into O\U2019sheas
But the odd thing is, if I just replace this:
PARAMETERS["searchTxt"] = passedInString
with a hardcoded string (the one I'm typing initially and getting no results)
PARAMETERS["searchTxt"] = "o'sheas"
...it works just fine and does not convert this to O\U2019sheas. Any idea how to fix this, and more importantly, why this is happening when passed in as a String parameter as opposed to hard coded string?
UPDATE:
I've tried adding the URLEncoding.default as the encoding parameter, same results.
I've also tried creating a Swift String Extension to be used on the searchTxt as passing it as parameter like so:
PARAMETERS["searchTxt"] = passedInString.escapeSpecialCharacters()
extension String {
mutating func escapeSpecialCharacters() {
// 1. Define replacements
let replacementCharacters = ["'" : "\'"]
// 2. Cycle through each replacement defined in the replacementCharacters array and remodify the string accordingly.
replacementCharacters.keys.forEach {
// 3. Replacing self with new modified string
self = self.replacingOccurrences(of: $0, with: replacementCharacters[$0]!)
}
}
}
But same results.
If you are sure about this Unicode problem, then you can use Encoder and Decoder functionality to handle this.
Or if you know the your String always will be same, then use Regex expression to append '\'
I think the problem is with the "get" - cause it will use your string in the URL as parameter, the "'" can't be handelt so well.
Try to create a url with URLComponents
var urlComponents = URLComponents()
urlComponents.scheme = scheme
urlComponents.host = host
urlComponents.path = path
urlComponents.queryItems = [queryItem]
then use urlComponents.url in
Alamofire.request(urlComponents.url, method: .get, headers: HEADERS) {...}
URLQueryItem(name: "Param", value: "eter")
Try below lines of code. May help you.
originalString = "o'sheas"
var escapedString = originalString.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)
PARAMETERS["searchTxt"] = escapedString

Accessing JSON response

I am storing the response of a REST Get request and trying to access as below,
final JSONObject receivedItem = new JSONObject(response.readEntity(String.class));
This is the sample response,
[
{
"timeStamp": 1511136000000,
"contextKeys": [
{
"tKey": "Test1",
"contextKey": "Location",
"contextValue": "San Jose",
"eCount": 3
},
{
"tKey": "Test1",
"contextKey": "Name",
"contextValue": "User1",
"eCount": 3
}
}
]
And i am getting the below error,
org.json.JSONException: A JSONObject text must begin with '{' at character 1
at org.json.JSONTokener.syntaxError(JSONTokener.java:496)
at org.json.JSONObject.<init>(JSONObject.java:180)
at org.json.JSONObject.<init>(JSONObject.java:403)
Any clues ?
Thanks
As Rajkumar pointed out, in your example there is a missing close bracket - but this may just be a simple typing error.
The actual error message is saying A JSONObject text must begin with '{' which is because JSON objects are exactly that, objects. You need to use a JSONArray to parse your example JSON as follows:
final JSONArray receivedItem = new JSONArray(response.readEntity(String.class));
This may change some of your other code to handle this as an array vs an object.
If your problem is with storing and accessing json response try this response instead;
I am presuming that you are using javascript; Anyways, core idea is the same;
var jsonStorage;
$.getJSON('your url',(json) => {
jsonStorage = json;
});
console.log(jsonStorage) //your jsonresponse is now available here;