Sending array of objects trough x-www-form-urlencoded - arrays

I want to send an array of objects trough a fetch call in react native in x-www-form-urlencoded format
global.modifiedOffline.forEach((elem)=>{
data["array[]"] = elem;
});
alert(data);
const formBody = Object.keys(data).map(key => encodeURIComponent(key) +
'=' + encodeURIComponent(data[key])).join('&');
This is what i've been trying to do but in the back end server i get a list of:
['[object Object]' ... ] which i cannot parse or use.

Currently, you are encoding objects. When you try to do that, encodeURIComponent tries to get a string representation of the object you supply it and [Object object] is the string representation in JS.
In order to be able to encode it, first you need to get it into a proper string format such as JSON as suggested by #Val. However, this part depends on the server side implementation you have. encodeURIComponent will only transform your string into URI component by replacing characters such as space with their escape counterparts (for example, %20).

Related

proper way to get the last element of the array when split is used on the string within JSON

I have a JSON response from the server and I am using map to use only necessary key:valuepairs in Angular (typescript) that will be used to display on the Frontend side.
here bizStep is actually according to a standard (EPCIS) and has the following value:
urn:epcglobal:cbv:bizstep:receiving
I only want to the user to read receiving hence I used split and obtained the last value of the array to display the value.
The logic is shown below:
this.serv.getEpcisInfo(code) // HTTP GET Service from Angular
.subscribe(res => {
this.data = res.map(el => { // map only some key value pairs now!
return {
'business step': el.bizStep.split(':')[el.bizStep.split(':').length - 1]
});
});
But it is observed that in order to obtain the overall length of the splited string array I have to write the expression el.bizStep.split(':') twice.
Is there a shorthand or elegant expression to obtain the last string value of the array.
I did try to use el.bizStep.split(':')[-1] however this expression failed and did not provide me any value.
You can use Array.pop since you don't need to preserve the result of the split, i.e. el.bizStep.split(':').pop().
A more general approach would be to use an anonymous function, e.g.:
(s => s[s.length-1])(el.bizStep.split(':'))
You could modify this to get elements other than the last. Of course, this example has no error checking on the length or type of el.bizStep.

Load Delimiter Separated Values in D3

I am trying to load a pipe separated value file in D3 using the generic d3.dsvFormat() function. While I do not get an error, nothing happens which I think is because the callback function is not executed.
I did check the documentation here but did not find it that helpful: https://github.com/d3/d3-dsv/blob/master/README.md#dsvFormat
Is there a problem with my syntax?
var psv = d3.dsvFormat("|");
psv.parse("my_file.txt", function(error, data) {
Do a bunch of stuff with the data....
console.log(data); //nothing happens here
});
psv.parse wants text, you are passing text - just that it doesn't have any pipe in it: "my_file.txt". As this is one line of text and the first line of text translates into column names, you won't get any data with this.
Your problem is that psv.parse won't fetch a file for you like d3.csv or d3.tsv (Rather psv.parse() acts like d3.csvParse() or d3.tsvParse()). Luckily this is not too difficult to fix.
If we look at the API documentation for d3.csv we can recreate the same functionality for any delimited file. With d3.csv,
If a callback is specified, a GET request is sent, making it
equivalent to:
d3.request(url)
.mimeType("text/csv")
.response(function(xhr) { return d3.csvParse(xhr.responseText, row); })
.get(callback);
(from API docs)
We just have to emulate this for a pipe separated file:
var psv = d3.dsvFormat("|");
d3.request("my_file.txt")
.mimeType("text/plain")
.response(function(data) { return psv.parse(data.response) })
.get(function(data) {
console.log(data);
});
It's a little bit more verbose than a plain old d3.csv() or d3.tsv(), but achieves the same result with the callback function located in the get method.
You could also use data.responseText in the response method, I'm not sure what the difference is though, both appear identical in my quick testing.
You may have also noted that I did not specify a row function in the response method, this is an optional function that allows "conversion of row objects to a more-specific representation", eg: returning numbers rather than strings. API documentation).
One last note:
In relation to your original code, psv.parse("text") returns the data, you don't use a callback function for this method. The following snippet demonstrates how you might parse straight pipe delimited text:
var psv = d3.dsvFormat("|");
var data = psv.parse("a|b\n1|2\n4|3")
console.log(data);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"></script>

Getting rates from an array - json

I am trying to get the rates from this website.
So I connect with website = Faraday.get('https://bitpay.com/api/rates')).status == 200 and then try to parse this.
A segment of the response I get is:
#<Faraday::Response:0x007fcf1ce25688
#env=
#<struct Faraday::Env
method=:get,
body=
"[{\"code\":\"BTC\",\"name\":\"Bitcoin\",\"rate\":1}, {\"code\":\"USD\",\"name\":\"US Dollar\",\"rate\":586.66},{\"code\":\"EUR\",\"name\":\"Eurozone Euro\",\"rate\":528.991322},{\"code\":\"GBP\",\"name\":\"Pound Sterling\",\"rate\":449.441986},{\"code\":\"JPY\",\"name\":\"Japanese Yen\",\"rate\":59907.95922},{\"code\":\"CAD\",\"name\"
When I do a website.body I get a String class of all these values found on that website. I want to parse them though (JSON?) so that I can get each rate as a float.
I tried something JSON.parse(website.body)["GBP"]["rate"].to_f but yet again it cannot work in a string.
The return I get is TypeError: no implicit conversion of String into Integer
I was having a similar (but not the same) format from a different rates website and this is how I was handling it. Do I need to change its format first or is there a different way around it?
You're trying to access to the parsed JSON with the key "GBP" but you have an array. It's like if you did
a = [1,2,3,4,5]
a['foo']
Try out
currencies = JSON.parse(website.body)
currencies.each { |currency| puts currency['rate'] }
and change it like you need

"no implicit conversion of Array into String" when trying to parse JSON data

I’m using Rails 4.2.3. I’m trying to parse JSON data, so I have
content = ["{\"sEcho\":3,\"timestamp\":1464705752942,\"iTotalRecords\":1242,\"iTotalDisplayRecords\":1242,\"aaData\":[{\"externalId\":\"4279\"}]}"]
my_object_times_array = JSON.parse(content)
Sadly, the second line gives the error
no implicit conversion of Array into String
The JSON is well-formed (at least as far as I can tell) so I’m not sure what is causing the error above and how to fix it. I would prefer not to change the JSON.
content is an array, but JSON.parse expects a JSON String.
Example of usage from the documentation:
require 'json'
my_hash = JSON.parse('{"hello": "goodbye"}')
puts my_hash["hello"] => "goodbye"
Check the documentation here
So you could do following:
content = "{\"sEcho\":3,\"timestamp\":1464705752942,\"iTotalRecords\":1242,\"iTotalDisplayRecords\":1242,\"aaData\":[{\"externalId\":\"4279\"}]}"
my_object_times_array = JSON.parse(content)
or
content = ["{\"sEcho\":3,\"timestamp\":1464705752942,\"iTotalRecords\":1242,\"iTotalDisplayRecords\":1242,\"aaData\":[{\"externalId\":\"4279\"}]}"]
my_object_times_array = JSON.parse(content[0])

Intermitent Base64 Task Conversion Errors

I'm experiencing a really weird situation when passing on a POJO java object within the payload of a Pull Queue task using Gson. Without changing the code or the POJO being set within the payload of a task, this will randomly succeed or fail.
This is the code I'm using:
PullQueueTaskPayLoad tqp = new PullQueueTaskPayLoad("id","name");
tqp.uploadURL = taskPayLoad.uploadURL;
tqp.urls = taskPayLoad.urls;
tqp.sliceQueryParameter = taskPayLoad.sliceQueryParameter;
TaskOptions task = TaskOptions.Builder.withMethod(TaskOptions.Method.PULL);
task.payload(new Gson().toJson(tqp));
q.add(task);
Using an external queue consumer I then retrieve the POJO as follows:
Type GSON_TYPE = new TypeToken<PullQueueTaskPayLoad>() {}.getType();
byte[] b = new Base64().decodeBase64(leasedTask.getPayloadBase64().getBytes());
String payload = new String(b);
logger.info("About to convert payload: "+payload);
PullQueueTaskPayLoad taskpayload = new Gson().fromJson(payload, GSON_TYPE);
So from the debugging I did, the problem seems to be happening when I'm decoding the payload bytes. While encoding the same POJO (with different Ids) I randomly get 2 different decoded payload Strings as follows:
Correct decoding:
{"id":"1786024566","sliceQueryParameter": {"queryId":786024566,"sliceStart":-1,"sliceNumber":1,"params":{"DefaultAnnotation":{"http://www.slicepedia.org/ontology#hasNumberOfBulletPoints_SIGN":["\u003d"],"http://www.slicepedia.org/ontology#hasNumberOfBulletPoints":["0"],"http://www.slicepedia.org/ontology#hasNumberOfTokens":["80"],"http://www.slicepedia.org/ontology#hasNumberOfTokens_SIGN":["\u003e"]},"VG":{"http://www.slicepedia.org/ontology#hastense":["?"],"http://www.slicepedia.org/ontology#hasroot":["?"]}}},"uploadURL":"http://3.linguabox0412.appspot.com/_ah/upload/AMmfu6YRjxX23Ks-yh-9AZs4-3I1p6hxrFd6d4ptxSQegUkQHN7y4hNZwX6u7PufIHJbwtsHLXFZJ5P-vs90mslZEOMw0T-amN2qhEOAj_6YdwuY50FXMi8/ALBNUaYAAAAAT7Towgs4M00M5RLI8xnEOMdIxouZzuGu/","status":"IN_PROGRESS","action":"SLICE_SEARCH_AND_CREATE"}
Incorrect decoding:
{"id":"1-1968382407","sliceQueryParameter":{"queryId":-1968382407,"sliceStart":-1,"sliceNumber":1,"params":{"DefaultAnnotation":{"http://www.slicepedia.org/ontology#hasNumberOfBulletPoints_SIGN":["\u003d"],"http://www.slicepedia.org/ontology#hasNumberOfBulletPoints":["0"],"http://www.slicepedia.org/ontology#hasNumberOfTokens":["80"],"http://www.slicepedia.org/ontology#hasNumberOfTokens_SIGN":["\u003e"]},"VG":{"http://www.slicepedia.org/ontology#hastense":["?K??????˜?X?\YXK?ܙ?????H?\ܛ????Ȃ%?????'W??EU$?#?&?GG???2?Ɩ?wV&??C"?7?B?6??????W??B???gSe????'u?U'd?D??6?S??4UV?D?e7?%U?&%F%f?D?$???$&vu6?fF$????EG?v??6?6դvt?D???G??&D?fdֵ6%?甦??GD????F???$?V?CuF?$?F?F֤֧f?D??u?wt?4?C$?W?"?'7FGW2#?$???$?u$U52"?&7F???#?%4Ĕ4U?4T$4???E?5$TDR'
So the second string obviously fails when using Gson to convert it back to a POJO. But I dont' understand why this happens in only some cases and not others. For what I've seen, it seems to always happen after a ["?"] character string. I tried replacing and ? with other strings but it didn't change anything.
I think what is happening here is that the payload is webSafe-base64 encoded. In practice, this means swapping + and / and = for - and _ and .. Most base64 libraries have native support for decoding websafe base 64 strings.
Probably you are meeting one of these chars at a certain point, and that kills the decoding.
Here is some info on WebSafeBase64
Word of warning, though: the taskqueue implementation is actually sending padding equals (=) that you will have to convert manually before parsing.

Resources