URL GET parameter representing and parsing embedded objects - javascript

I'm working on an API that consists of several collections that have relations to each other. I want to give users the opportunity to eagerly fetch records from associated collections via a GET url parameter.
For instances
/api/clients/
Would return an array of objects, each representing a client.
But clients have "employees" and "templates". "Templates" also have "revisions." And lastly, "revisions" have "groups"
My strategy for the format of the url parameter is something like this:
/api/clients?expand=[employees][templates[revisions[groups]]]
Which represents:
clients
+ employees
+ templates
+ revisions
+ groups
My question is, what is a good way to go about parsing a string in this format: [employees][templates[revisions[groups]]]
to arrive at an object like this:
{
"employees": {},
"templates": {
"revisions": {
"groups": {}
}
}
}
Or something similar that's easy to work with. I'm working in NodeJS so any answers specific to that environment are a plus. Regex?

Going off #Kovge 's suggestion, I'm going to handle this situation with a JSON string passed in my URL get request. It's a bit verbose, but should be acceptable.
Here's how I'd represent my eager-fetching associated collection records:
[
{
"resource": "employees"
},
{
"resource": "templates",
"extend": [
{
"resource": "revisions",
"extend": [
{
"resource": "groups"
}
]
}
]
}
]
Basically using arrays of objects with "resource" parameters and optional "extend" parameters. My request will end up looking like this: (url encoded)
http://example.com/api/clients?extend=%5B%7B%22resource%22%3A%22employees%22%7D%2C%7B%22resource%22%3A%22templates%22%2C%22extend%22%3A%5B%7B%22resource%22%3A%22revisions%22%2C%22extend%22%3A%5B%7B%22resource%22%3A%22groups%22%7D%5D%7D%5D%7D%5D
EDIT:
This is what my result ended up looking like, still playing with things.

Related

How to use Map-Reduce for Groupbased Filtering?

I am pretty new to this map-reduce thing and I am using this to filter out users on my site.
What I want to ask is how can I do the group based filtering in it?
Let me explain you the scenario:- I want to filter out the queries ask by users between particular dates e.g> from:-1/01/2016 To:-03/02/2016.
I am getting the data given below by running a MR function I further want to run a Reduce function again over it on Cloudant so that i can get the queries made between particular dates
I am using Cloudant, Mongodb, Couchdb and JavaScript.
Thanks for replying and giving your precious time to read my query. Sorry for the trouble if you had in understanding query as I am really new to all this.
If the dates in your query are dynamically provided at runtime then a view may not be the right approach. You can use Cloudant Query to run dynamic queries at runtime. For example, you can create an index on your date field like so:
{
"index": {
"fields": [
"mydate"
]
},
"type": "json"
}
and then use the following selector in a Cloudant Query:
"selector": {
"$and": [
{"mydate" : { "$gt": 1506874127 }},
{"mydate": { "$lt": 1506960651 }}
]
}
I am using unix timestamps in this example.
Alternatively, you can use Cloudant Search. Create a search index in Cloudant similar to the following:
{
"_id": "_design/allDocs",
"views": {},
"language": "javascript",
"indexes": {
"byMyDate": {
"analyzer": "standard",
"index": "function (doc) {\n if (doc.mydate) {\n index(\"mydate\", doc.mydate);\n }\n}"
}
}
}
This corresponds to the following when using the Cloudant dashboard:
design doc = allDocs
index name = byMyDate
index function =
function (doc) {
if (doc.mydate) {
index("mydate", doc.mydate);
}
}
Then you can run a search using a range. For example,
https://<YOUR_INSTANCE>.cloudant.com/<YOUR_DB>/_design/allDocs/_search/byMyDate?q=mydate%3A[1506874127%20TO%201506960651]
Here the search query is:
mydate:[1506874127 TO 1506960651]
Again, I am using unix timestamps. You could also use date strings I believe.
Cloudant Query: https://console.bluemix.net/docs/services/Cloudant/api/cloudant_query.html
Cloudant Search: https://console.bluemix.net/docs/services/Cloudant/api/search.html#search

JavaScript / JSON - Access array element using a key name as index

I want to be able to access an array element by using a unique key name instead of a numeric index. In my situation, I'm making a Discord bot and each servers have their own settings. When someone sends a message on a server, I want to access some of this server's settings (such as a message prefix). IMPORTANT: Right now, the only way I can do this is looping through all the servers that the bot is in, which in long-term, could slow it down if there's hundreds of active servers sending messages. So looping through all the servers is already being done right now, but I want a direct way without having to do this.
conf.json:
{
"Settings": [
"358262452343013386" {
"prefix": "$",
"Admins": [
"155444308395294720"
],
"NotificationChannel": "358772856282284033",
"robotpieces": []
}
]
}
What I want to be able to do in my bot.js:
console.log(conf.Settings[message.guild.id].prefix); // outputs the prefix
// message.guild.id is the id of the server, which in this case, would translate to this:
console.log(conf.Settings["358262452343013386"].prefix) // outputs '$'
Any ideas of how I can achieve a similar goal WITHOUT having to loop through all of the array?
EDIT:
I know the following JSON is invalid, but I want a solution which would give the same result.
Aside from the fact that the JSON you posted is invalid, you could store the server settings as an object rather than an array, and access is just like you are trying to:
{
"Settings": {
"358262452343013386": {
"prefix": "$",
"Admins": [
"155444308395294720"
],
"NotificationChannel": "358772856282284033",
"robotpieces": []
}
}
}

AWS CloudSearch - Getting results of a search in JSON format

I am performing a search on my AWS CloudSearch domain from a Lambda function in node.js:
I uploaded a document such as this:
{
“some_field”: “bla bla“,
“some_date_field”: 1.466719E9,
"number_field”: 4,
“some_string”: "some long string blabla"
}
And I perform a search like this
var params = {
query: 'bla bla',
};
cloudsearchdomain.search(params, function(err, data) {
if (err) {
console.log(err, err.stack); // an error occurred
context.fail(err);
}
else {
context.succeed(data); // successful response
}
});
The search works and as documented here CloudSearch returns document
info in fields property of a hit. Here is an example:
{
"status": {
"timems": 2,
"rid": “blabla”
},
"hits": {
"found": 1,
"start": 0,
"hit": [
{
"id": “452545-49B4-45C3-B94F-43524542352-454352435.6666-8532-4099-xxxx-1",
"fields": {
“some_field”: [
“bla bla“
],
“some_date_field”: [
"1.466719E9"
],
"number_field”: [
"4"
],
“some_string”: [
"some long string blabla"
],
}
}
]
}
}
As you can see all the fields are returned as strings in an array.
Is there anyway to get the results as a JSON that preserves the
type of all the fields?
After submitting a report about this to AWS I received this reply:
Hello, This is actually the intended behavior. The SDK team chose to implement the "fields" property as a dictionary of string keys and string-array values to maintain consistency across the various languages in which the AWS SDK exists. They place the responsibility for handling the various response formats (HTTP request vs. SDK method) on the client. For more details, please see: https://github.com/aws/aws-sdk-js/issues/791
Unfortunately the only current solutions to the problem I describe above is:
1) Create a parser that will parse the results as needed based on your expected response which takes into account your data types
2) Add a new field to your cloudsearch index (text type) containing a stringified version of your entire json object/document. You can then just use JSON.parse() on this to get the document in JSON format. This solution is not ideal because it adds an unnecessary chunk of text to your document but it proved a quick solution to my problem above.
I'd love to hear of any more solutions if anyone knows of any.
CloudSearch does preserve the field type; the results imply that you've configured these fields as arrays.
You can confirm this by going to Indexing Options for your domain on the AWS web console. You should see fields that are text-array, literal-array, etc as in the screenshot below. Those will be returned as arrays. You can change them to non-array types if you will only ever be submitting a single value for each field in each document and you'll get back non-array values.

How to structure and parse JSON

I'm creating a web RPG using HTML5 and JavaScript embedded directly into my website. The game will be a single player game against computer opponents... the design will be top-down 2D, Zelda style. It will be real time, but conversing with computer players will be scripted... they say something, and you're given some response options.
I was thinking of writing the dialog in XML, but I was told I should use JSON as it's easier to parse using JavaScript.
I saw Abstract Chaos' answer in XML...
<?xml version="1.0" encoding="UTF-8"?>
<npcs>
<npc name="Abstract">
<dialogue>
<text>Welcome #{PlayerName} to Stack Exchange, What would you like to know? </text>
<options>
<option action="dialogue5">Tell me about Stack Exchange?</option>
<option action="quest1">Give me quest</option>
<option action="object1">Give me object</option>
</options>
</dialogue>
<dialogue id="5">
<text>Stack Exchange is a fast-growing network of 87 question and answer sites on diverse topics</text>
<text>We build libraries of high-quality questions and answers, focused on the most important topics in each area of expertise</text>
</dialogue>
</npc>
</npcs>
And was wondering how I could achieve the same sort of layout in JSON...
My questions are:
How can I layout RPG dialog scripts in JSON to be parsed by JavaScript?
Can I have an example of how I could use JavaScript logic to parse JSON given certain conditions (ex: NPC asks question: "Can you help me?", JSON should have options "Yes" and "No", which could be based on if the player actually has that skill set to help).
The JSON dialog text will be stored in a separate "dialog" folder in my project folder... so it will need to be accessed externally
The only thing I've found on how to layout and parse JSON is:
var json = '{"result":true,"count":1}',
obj = JSON && JSON.parse(json) || $.parseJSON(json);
alert(obj.result);
But it doesn't have the neatness factor that XML seems to have.
Any help would be appreciated...
Thanks!
Trying to load and alert external JSON text file doesn't work:
HTML:
<html>
<head>
<title>Working with JSON</title>
<script src="jquery.js"></script>
<script>
(function() {
var data = "/JSON_TEXT.txt";
var first_q = data.npcs[0].dialogs[0];
alert(first_q.text);
}());
</script>
</head>
<body>
</body>
</html>
JSON plain text file: JSON_TEXT.txt
'npcs': [
{
'name': 'Abstract',
'dialogs': [
{
'text': 'Welcome',
'options': [
'df', 'f'
]
}
]
}
]
How can I layout RPG dialog scripts in JSON ?
The equivalent of the XML you gave us would be (without the comments):
// you might use a top wrapper object with a property "npcs" for this array
[
{
"name": "Abstract",
"dialogues": {
// I recommend on object with dialogues by id instead of an array
"start": {
"texts": [
"Welcome #{PlayerName} to Stack Exchange, What would you like to know?"
],
"options": [
{
"action": "dialogue 5",
"text": "Tell me about Stack Exchange?"
}, {
"action": "quest 1",
"text": "Give me quest"
}, {
"action": "object 1",
"text": "Give me object"
}
]
},
"5": {
"texts": [
"Stack Exchange is a fast-growing network of 87 question and answer sites on diverse topics",
"We build libraries of high-quality questions and answers, focused on the most important topics in each area of expertise"
]
}
}
// further properties of the NPC like objects and quests maybe
},
… // further NPCs
]
How to parse JSON?
See Parse JSON in JavaScript?.
var json = {…};
var data = JSON && JSON.parse(json) || $.parseJSON(json);
Ouch, no! That's no JSON, that's just an object literal in JavaScript. You can use it like
var data = {…};
and data will be your object. You need to parse JSON only when you have it as a string, for example when you've loaded a file via ajax.
JavaScript logic to parse JSON given certain conditions
That's your game logic, with which we can't help you. But you don't need to parse JSON there, you only need to access the data which you have already parsed. See Access / process (nested) objects, arrays or JSON for that.
Some find JSON harder to read than XML. I think it's much cleaner and easier to use, especially if you want to parse it with JS.
That said, I'm not really sure what your question is—you already have the data in XML, so just convert it to JSON. You can use arrays ([]) for lists and objects ({}) for when you need named keys:
{
'npcs': [
{
'name': 'Abstract',
'dialogs': [
{
'text': 'Welcome #{PlayerName} to Stack Exchange, What would you like to know?',
'options': [
//options here
]
},
//next dialog object here
]
},
//next npc object here
]
}
So, like you said, first you'll need to parse the JSON string:
var json; //contains the json string, perhaps retrieved from a URL via AJAX
data = JSON && JSON.parse(json) || $.parseJSON(json);
You could also assign the JSON object to a JS variable in the first place (say, in a .js file somewhere) and you won't need to parse at all. Just be sure not to pollute the global scope.
After parsing, data is a normal JS object. You can access its properties just like any other object. So, to access the first question from the first NPC, do:
var first_question = data.npcs[0].dialogs[0];
Let's alert the question itself:
alert(first_question.text);
You can access its options like this:
first_question.options;
You asked about how to load the JSON data from an external file. The usual approach is to load the file's URL via AJAX. Here is a nice tutorial for making AJAX requests with vanilla JavaScript: https://developer.mozilla.org/en-US/docs/AJAX/Getting_Started
But there's not much reason to hand-code AJAX requests with vanilla JavaScript. I recommend using a library like jQuery, which has handy AJAX functions such as .ajax and the shorthand function .get. Here's an example using .get:
var data; //will hold the parsed JSON object
var json_url = 'json.txt'; //URL of your JSON (just a plain text file)
$.get(json_url, function(json) {
data = JSON && JSON.parse(json) || $.parseJSON(json);
});
//use data here

How to translate Solr JSON response into HTML while JSON is different every time

I am using Solr 4 for searching in a java web application.Solr produces a JSON response from which i have to extract search results and translate them into html so user can read that.
I know one solution but it seems dumb an I think there must be intelligent ideas.
{
"responseHeader": {
"status": 0,
"QTime": 0,
"params": {
"fl": "id,title",
"indent": "true",
"q": "solr",
"wt": "json"
}
},
"response": {
"numFound": 3,
"start": 0,
"docs": [
{
"id": "1",
"title": "Solr cookbook"
},
{
"id": "2",
"title": "Solr results"
},
{
"id": "3",
"title": "Solr perfect search"
}
]
}
}
After that i eval this text as:
var obj = eval ("(" + txt + ")");
To generate html page i can use either
<script>
document.getElementById("id").innerHTML = obj.response.docs[1].id
document.getElementById("title").innerHTML = obj.response.docs[1].title
</script>
or
document.write(obj.response.docs[1].id);
But limitation is that every time solr gives response with different object structure i.e. an object may have age feild but other can not have because it depends on query.
I want to use a sigle JSP page to display search results(like Google)
for all search queries
is it possible to write a single code segment which works for any possible search results with different schema.
Javascript stops working after encountering any error which is likely in my case. that's also problem.if I use for loop to traverse the object hierarchy it is highly error -prone.
Is it possible with a single view page Thanks.
You might want to consider using ajax-solr - A JavaScript framework for creating user interfaces to Solr
I suggest using Velocity templating which is readily supported in Solr - instead of extracting data from the JSON and rendering the HTML via JS.
Docs here

Categories

Resources