Is there a standard for handling an array of integers like the following:
http://localhost:3001/?tag_ids=7,10,45
or
http://localhost:3001/?tag_ids=[7,10,45]
I feel like I've written boiler-plate every 6 months and would much rather use some library.
A number of server-side scripting languages like PHP expect each value to be in a separate parameter, with the parameter name ending with [].
tag_ids[]=7&tag_ids[]=10&tag_ids[]=45
They recognize this syntax and collect all the values into an array. In PHP this would be $_GET['tag_ids'] = [7, 10, 45].
You can also optionally put strings inside the []; in this case, the server language will put them into its keyed data structure (associative array in PHP, dictionary in Python) with those as the keys.
You should call encodeURIComponent on tag_ids[], so they'll actually end up looking like tag_ids%5B%5D.
Related
I have a JavaScript grid library (it creates a table on the page) that accepts a JavaScript array as input, for rendering in the grid. I'm not certain, however, how to convert a Linq-to-SQL query (against a SQL Server database) to a JavaScript array containing only values.
I tried this, but it included the table column names in the JSON key (and I don't want JSON anyway, I want a JavaScript string array, unless this can be converted to an array?):
JsonConvert.SerializeObject(query)
Example of the format I need to produce:
[1,2,3],[4,5,6]
Environment: .NET Core 3.1
edit: Here is a sample of what I've currently got, this returns the less than desirable JSON (due to the query results being so large, having a JSON key for very element is going to literally double the size of the query):
Devices Table
ID Name
1 iPhone7
2 iPhone8
3 iPhone9
Needed Array (Note: no column names)
[1, "iPhone7"],[2, "iPhone8"],[3, "iPhone9"]
Current C# code in the controller method (returns undesirable key for every element currently)
var query = db.Devices;
var formattedResult = JsonConvert.SerializeObject(query);
return Ok(formattedResult);
Technically, you could do this:
var query = db.Devices.AsEnumerable()
.Select(d => new object[]{d.ID, d.Name});
var formattedResult = JsonConvert.SerializeObject(query);
return Ok(formattedResult);
But then the code on the other end of your request is going to have to translate all those arrays back into objects.
It's rarely worthwhile to complicate your model like this in order to optimize the size of your network traffic. If you're pulling enough items over the wire to make this a performance issue, you're likely to encounter a variety of other performance issues. I would first consider other options, like implementing paging.
Did you try
var query = db.Devices.ToList();
var array = JArray.FromObject(query);
return Ok(formattedResult)
Consider a list of numpy arrays:
arr = [np.linspace(a1,a2,11) for a1,a2 in [(1,10),(20,30)]]
nparr = np.array(arr)
I would like to serialize this to transmit to a Javascript REST client. The preferred approach is
Efficiently serialize into a binary-safe format and bake that into a Base64 encoded field in a JSON object
Transmit the JSON object over http
Receive the JSON object into javascript listener.
Base64 decode the field and deserialize into binary array using an efficient javascript deserialization library
I have done an initial investigation into apache arrow that has support in both languages.
Note: I tried the following:
convert to two dimensional numpy array
convert to pyarrow
Following happened
pyarr = pya.array(nparr)
ArrowInvalid Traceback (most recent call last)
<ipython-input-11-68eb3e5f578f> in <module>
----> 1 pyarr = pya.array(nparr)
ArrowInvalid: only handle 1-dimensional arrays
So pyarrow seems pretty limited in terms of the structures of the data it can serialize. I also am looking into the apache parquet format : but that seems to require actually writing to disk/filesystem?
Working code for those two technologies or possibly a different library/approach would be welcome.
Arrow is capable of serializing list of arrays of float. But I think it needs a little help if the list is multi dimension numpy array:
pa.array(
arr.tolist(),
pa.list_(pa.float64())
)
But given your use case, since all arrays have got the same length, I'd recomment using a Table instead an Array
schema = pa.schema(
[
pa.field(str(i), pa.float64())
for i in range(len(nparr))
]
)
table = pa.Table.from_arrays(
nparr,
schema=schema
)
I have a JSON object which looks like this:
{
files: ['test.mp4'],
name: ['testFile'],
hints: ['%YES%_%MAYBE%_%NO%']
}
And I need to convert it to a String so the output looks like this:
[{files=test, name=testFile, hints= %YES%_%MAYBE%_%NO%}]
Is this possible to achieve in Node JS? Thanks
I tried the following:
var x = {
files: ['test.mp4'],
name: ['testFile'],
hints: ['%YES%_%MAYBE%_%NO%']
}
console.log(JSON.stringify(x));
But the output looks like this:
{"files":["test.mp4"],"name":["testFile"],"hints":["%YES%_%MAYBE%_%NO%"]}
Still with the square brackets. I may not 100% know the keys and values in the object above.
Try
JSON.stringify(obj)
then you get a string with quotes etc.
JavaScript has JSON.stringify() method which can convert an object into string:
var x = {
files: ['test.mp4'],
name: ['testFile'],
hints: ['%YES%_%MAYBE%_%NO%']
}
console.log(JSON.stringify(x));
// result: '{"files":["test.mp4"],"name":["testFile"],"hints":["%YES%_%MAYBE%_%NO%"]}'
This will result in a string which can be transformed back to JS object with JSON.parse() method. If you still want to remove all brackets and quotes, you can simply use JavaScript's replace() method (replacing characters [, ], and " with empty string), but this will replace those characters in all your values (if any) and will result in (sort of) non-reusable string.
TL;DR Don't do this unless you absolutely have to (ie. you're dealing with a messed up API written by someone else that must have the data in this format)
If you want exactly the format listed in your question, then you're going to have to write your own stringify function that recursively walks through the object you pass to it and applies whatever rules you want to use. You will have to consider all the possible permutations of your object and spell out those rules.
For example, you've converted arrays with single elements in the initial object into strings - what happens if there is more than one element in the array? Should it be delimited by a comma or some other character? Should we just throw away elements after the first?
And once you've written the stringify function, you'll also have to write the corresponding parse function to reverse it. And it should be mentioned that in your example, you're throwing away information (eg. the file extension on the .mp4 file) - how are you going to handle that?
A much, much better way to approach this would be to do what other people have suggested here: use JSON.stringify and rewrite your code to use standard JSON objects. Why? Because the format is well documented and well understood and because the functions to convert are well tested. You will save yourself a whole lot of time and pain if you don't try to reinvent the wheel here.
From JSON website:
JSON is built on two structures:
A collection of name/value pairs. In various languages, this is realized as an object, record, struct, dictionary, hash table, keyed list, or associative array.
An ordered list of values. In most languages, this is realized as an array, vector, list, or sequence.
Now I have a sample service that returns a boolean (this is in PHP, but it could be any server side language):
<?php
header('Content-Type: application/json');
echo 'true';
exit;
And when requesting this page with ajax (for example with jQuery):
$.ajax({
url: 'service.php',
dataType: 'json',
success: function (data) {
console.log(data);
console.log(typeof data);
}
});
The result would be:
-> true
-> boolean
My question is why it's allowed to return boolean as a JSON.
Doesn't it have conflict with JSON definition?
ALSO
Also I can return number or string in my service:
<?php
header('Content-Type: application/json');
echo '2013';
exit;
And the result is:
-> 2013
-> number
And for string:
<?php
header('Content-Type: application/json');
echo '"What is going on?"';
exit;
And the result is:
-> What is going on?
-> string
You are correct that a valid JSON text can only be an object or an array. I asked Douglas Crockford about this in 2009 and he confirmed it, saying "Strictly speaking, it is object|array, as in the RFC."
The JSON RFC specifies this in section 2:
A JSON text is a serialized object or array.
JSON-text = object / array
The original JSON syntax listed on json.org does not make this clear at all. It defines all of the JSON types, but it doesn't say anywhere which of these types may be used as a "JSON text" - a complete valid piece of JSON.
That's why I asked Doug about it and he referred me to the RFC. Unfortunately, he didn't follow up on my suggestion to update json.org to clarify this.
Probably because of this confusion, many JSON libraries will happily create and parse (invalid) JSON for a standalone string, number, boolean, etc. even though those aren't really valid JSON.
Some JSON parsers are more strict. For example, jsonlint.com rejects JSON texts such as 101, "abc", and true. It only accepts an object or array.
This distinction may not matter much if you're just generating JSON data for consumption in your own web app. After all, JSON.parse() is happy to parse it, and that probably holds true in all browsers.
But it is important if you ever generate JSON for other people to use. There you should follow the standard more strictly.
I would suggest following it even in your own app, partly because there's a practical benefit: By sending down an object instead of a bare string, you have a built-in place to add more information if you ever need to, in the form of additional properties in the object.
Along those lines, when I'm defining a JSON API, I never use an array at the topmost level. If what I have is an array of items of some sort, I still wrap it in an object:
{
"items": [
...
]
}
This is partly for the same reason: If I later want to add something else to the response, having the top level be an object makes that easy to do without disrupting any existing client code.
Perhaps more importantly, there's also a possible security risk with JSON arrays. (I think that risk only affects the use of eval() or the Function constructor to parse JSON, so you're safe with JSON.parse(), but I'm not 100% sure on this.)
Note, the answer from Michael Geary is outdated since rfc7158 in 2013 which does not limit JSON text to array or object anymore. The current RFC https://www.rfc-editor.org/rfc/rfc8259 says:
A JSON text is a serialized value. Note that certain previous
specifications of JSON constrained a JSON text to be an object or an
array. Implementations that generate only objects or arrays where a
JSON text is called for will be interoperable in the sense that all
implementations will accept these as conforming JSON texts.
I need to implement a simple way to handle localization about weekdays' names, and I came up with the following structure:
var weekdaysLegend=new Array(
{'it-it':'Lunedì', 'en-us':'Monday'},
{'it-it':'Martedì', 'en-us':'Tuesday'},
{'it-it':'Mercoledì', 'en-us':'Wednesday'},
{'it-it':'Giovedì', 'en-us':'Thursday'},
{'it-it':'Venerdì', 'en-us':'Friday'},
{'it-it':'Sabato', 'en-us':'Saturday'},
{'it-it':'Domenica', 'en-us':'Sunday'}
);
I know I could implement something like an associative array (given the fact that I know that javascript does not provide associative arrays but objects with similar structure), but i need to iterate through the array using numeric indexes instead of labels.
So, I would like to handle this in a for cycle with particular values (like j-1 or indexes like that).
Is my structure correct? Provided a variable "lang" as one of the value between "it-it" or "en-us", I tried to print weekdaysLegend[j-1][lang] (or weekdaysLegend[j-1].lang, I think I tried everything!) but the results is [object Object]. Obviously I'm missing something..
Any idea?
The structure looks fine. You should be able to access values by:
weekdaysLegend[0]["en-us"]; // returns Monday
Of course this will also work for values in variables such as:
weekdaysLegend[i][lang];
for (var i = 0; i < weekdaysLegend.length; i++) {
alert(weekdaysLegend[i]["en-us"]);
}
This will alert the days of the week.
Sounds like you're doing everything correctly and the structure works for me as well.
Just a small note (I see the answer is already marked) as I am currently designing on a large application where I want to put locals into a javascript array.
Assumption: 1000 words x4 languages generates 'xx-xx' + the word itself...
Thats 1000 rows pr. language + the same 7 chars used for language alone = wasted bandwitdh...
the client/browser will have to PARSE THEM ALL before it can do any lookup in the arrays at all.
here is my approach:
Why not generate the javascript for one language at a time, if the user selects another language, just respond(send) the right javascript to the browser to include?
Either store a separate javascript with large array for each language OR use the language as parametre to the server-side script aka:
If the language file changes a lot or you need to minimize it per user/module, then its quite archivable with this approach as you can just add an extra parametre for "which part/module" to generate or a timestamp so the cache of the javascript file will work until changes occures.
if the dynamic approach is too performance heavy for the webserver, then publish/generate the files everytime there is a change/added a new locale - all you'll need is the "language linker" check in the top of the page, to check which language file to server the browser.
Conclusion
This approach will remove the overhead of a LOT of repeating "language" ID's if the locales list grows large.
You have to access an index from the array, and then a value by specifying a key from the object.
This works just fine for me: http://jsfiddle.net/98Sda/.
var day = 2;
var lang = 'en-us';
var weekdaysLegend = [
{'it-it':'Lunedì', 'en-us':'Monday'},
{'it-it':'Martedì', 'en-us':'Tuesday'},
{'it-it':'Mercoledì', 'en-us':'Wednesday'},
{'it-it':'Giovedì', 'en-us':'Thursday'},
{'it-it':'Venerdì', 'en-us':'Friday'},
{'it-it':'Sabato', 'en-us':'Saturday'},
{'it-it':'Domenica', 'en-us':'Sunday'}
];
alert(weekdaysLegend[day][lang]);