Custom formatting for JSON from a Rails controller - javascript

I have two rails models:
A Milestone has many Tasks
A Task belongs to a Milestone
In my controller I call the following:
#milestones = Milestone.all
render :json => #milestones.to_json(:include => :tasks)
Which gives me:
[ {
"id": 5,
"name": "This is milestone #1",
"tasks": [{
"complete": false,
"id": 60,
"name": "aaaaa",
"milestone_id": 5,
}, {
"complete": false,
"id": 62,
"name": "ccccc",
"milestone_id": 5,
}
]
}, {
"id": 6,
"name": "This is milestone #2",
"tasks": [{
"complete": false,
"id": 65,
"name": "ffffff",
"milestone_id": 5,
}, {
"complete": false,
"id": 66,
"name": "gggggg",
"milestone_id": 5,
}
]
}
]
But I need to be able to easily navigate through the JSON, so I'd like to be able to format it like this (notice each "sub array" is labeled with "milestone_ID" or "task_ID"):
[
"milestone_5": {
"id": 5,
"name": "This is milestone #1",
"tasks": [
"task_60":{
"complete": false,
"id": 60,
"name": "aaaaa",
"milestone_id": 5,
},
"task_62":{
"complete": false,
"id": 62,
"name": "ccccc",
"milestone_id": 5,
}
]
},
"milestone_6":{
"id": 6,
"name": "This is milestone #2",
"tasks": [
"task_65":{
"complete": false,
"id": 65,
"name": "ffffff",
"milestone_id": 5,
},
"task_66":{
"complete": false,
"id": 66,
"name": "gggggg",
"milestone_id": 5,
}
]
}
]
Does anybody have any idea how to get Rails to custom format JSON. Even if I have to lose the "milestone_" part and just spit out the ID, that would be very helpful.
Thanks!

Take a look at the json_builder gem.
What you're asking is certainly doable, but personally when you start doing anything remotely useful with json output from controllers, the default to_json method becomes unwieldy. It's best to explicitly output exactly what you want the json to look like.
Specifically in your json_builder file...
milestone.json.json_builder
#milestones.each do |milestone|
key "milestone_#{milestone.id}" do
id milestone.id
name milestone.name
end
end
etc etc. I believe that would do the trick.
Edit: I tend to only include the exact fields from the model that I need for whatever resource is consuming my json. This will improve performance and can make things easier to debug when something goes wrong. It's also very obvious which fields are going to show up where.

Related

TypeORM Select Column from relation without using QueryBuilder

If anyway to select columns from relation without using querybuilder ???
This is my current query:
const areas = await this.areaRepository.find({
where: { ...isActive },
relations: ["division"],
});
Output :
{
"id": 1,
"version": 9,
"isActive": 1,
"createdBy": null,
"updatedBy": 1,
"createAt": "2022-04-18T15:42:12.000Z",
"updatedAt": "2022-09-23T11:04:53.000Z",
"name": "Dhaka",
"division": {
"id": 3,
"version": 1,
"isActive": 1,
"createdBy": null,
"updatedBy": null,
"createAt": "2022-04-18T15:42:00.000Z",
"updatedAt": "2022-04-18T15:42:00.000Z",
"name": "Dhaka"
}
},
But is there anything like:
const areas = await this.areaRepository.find({
select: ['id','division.id division_id']
where: { ...isActive },
relations: ["division"],
});
And the output will be:
{
"id": 1,
"division_id": 3
}
This is a duplicated question of: How to select fields from joined table using TypeORM repository?
You can check the answer here. Also this depends on which TypeOrm version you are currently using, as far as I know on version under 0.3 this doesn't work.

How to groupby with multiple keys in javascript

Thank you in advance to whoever can help me. I am trying to show data in expandable rows in tabular format. How can i groupby with multiple keys like height,type and rank.
I know stackoverflow is not for asking for code but being noob and beginner, stackoverflow is the only option i have. Please show your talent to help me out.
I need this for First semester 1 credit college project.
i have a object
const sensorData = [{
"id": 19,
"height": 3.0,
"orientation": null,
"rank": "Primary",
"relativeHeight": 4,
"stat": "min",
"type": "wdir",
},
{
"id": 19,
"height": 3.0,
"orientation": null,
"rank": "Primary",
"relativeHeight": 6,
"stat": "min",
"type": "wdir",
},
{
"id": 19,
"height": 1.0,
"orientation": null,
"rank": "Primary",
"relativeHeight": 6,
"stat": "min",
"type": "wdir",
}]
The output i want is:
[
{
"isExpandable":true,
"common":{
"height":3.0,
"rank":"Primary",
"type":"wdir"
},
"data":[
{
"id":19,
"orientation":null,
"relativeHeight":4,
"stat":"max"
},
{
"id":19,
"orientation":null,
"relativeHeight":6,
"stat":"min"
}
]
},
{
"isExpandable":false,
"id":19,
"height":1.0,
"orientation":null,
"rank":"Primary",
"relativeHeight":6,
"stat":"min",
"type":"wdir"
}
]
I found reduce and lodash (_groupBy) very difficult to achieve this.
Updated:
isExpandable is decided if any attribute are matched or object can be grouped.
Thanks

coding watson conversation for complex inputs?

I would like to know how can I integrate some coding (python or javascript) in my dialog, in order to avoid the very limited bluemix interface for example for loops, or text mining.
EX : I am creating a pizza chatbot and I need to be able to process this kind of request :
I would like 2 margarita whose one with extra cheese and the other with pepperoni and a regina, with 3 diet cokes and two beers
It is just impossible to do it with bluemix.
If anyone has a solution I would be very grateful.
Thanks
So the first thing to understand is that Conversation has good and bad use cases.
If your user can enter in structured data, then it is better to use a form. Be that in the conversation window (like Watson Virtual Agent), or a form on your site/app.
So your example doesn't look like a good use case.
That said...
With your example it's possible if your main items are entities, and you haver #sys-number system entity enabled. You can then check the entities array to see distance from each other.
Example
Created the following entities.
#PizzaType
#PizzaTopping
#Drinks
When I ask your question, the entities object returns the following:
[
{
"entity": "Drinks",
"location": [
104,
114
],
"value": "diet coke",
"confidence": 1
},
{
"entity": "PizzaType",
"location": [
72,
81
],
"value": "Pepperoni",
"confidence": 1
},
{
"entity": "Drinks",
"location": [
123,
128
],
"value": "beer",
"confidence": 1
},
{
"entity": "PizzaType",
"location": [
88,
94
],
"value": "Regina",
"confidence": 1
},
{
"entity": "PizzaTopping",
"location": [
46,
52
],
"value": "cheese",
"confidence": 1
},
{
"entity": "PizzaType",
"location": [
15,
24
],
"value": "Margarita",
"confidence": 1
},
{
"entity": "sys-number",
"location": [
13,
14
],
"value": "2",
"confidence": 1,
"metadata": {
"numeric_value": 2
}
},
{
"entity": "sys-number",
"location": [
31,
34
],
"value": "1",
"confidence": 1,
"metadata": {
"numeric_value": 1
}
},
{
"entity": "sys-number",
"location": [
101,
102
],
"value": "3",
"confidence": 1,
"metadata": {
"numeric_value": 3
}
},
{
"entity": "sys-number",
"location": [
119,
122
],
"value": "2",
"confidence": 1,
"metadata": {
"numeric_value": 2
}
}
]
A summary of that is:
You can see straight away there are some issues there. If the user doesn't mention a number, you have to account for that. Also something like this question would break it as well (unless you cater for it).
I would like margarita pizzas (two).
But the important point is to build your system with representative questions. Your example question may never be asked by an end user, or you can even shape the conversation to prevent such an input.

Modifying Embers expected json api response

I'm new to Ember and from what I understand it has a very specific way it excepts its json api response to look like. Like so:
{
"post": {
"id": 1,
"title": "Node is not omakase",
"comments": [1, 2, 3]
},
"comments": [{
"id": 1,
"body": "But is it _lightweight_ omakase?"
},
{
"id": 2,
"body": "I for one welcome our new omakase overlords"
},
{
"id": 3,
"body": "Put me on the fast track to a delicious dinner"
}]
}
Now the api I've already built has an json response that looks like so:
{
"data": {
"id": 1,
"name": "Pansy Bednar",
"links": [
{
"rel": "self",
"uri": "/pansy-bednar15"
}
],
"players": {
"data": [
{
"id": 2,
"name": "Nicholas O'Reilly",
"position": "cad",
"age": 23,
"value": "640",
"links": [
{
"rel": "self",
"uri": "/team/nicholas-o-reilly71"
}
]
}
]
}
}
}
The api is pretty big and is working fine with the mobile app. So a code re write would be to costly I would just choose another js framework even though I like Ember the best.
So my question is is there any way I can adapt the expected json response in ember. If yes how hard is it? Worth the time or should I just go for Angular or Aurelia.
or am I completely wrong and there is no one expected response to ember?
The thing you can do with ember is to write your very own adapter for this there are already many questions+answers out there:
https://stackoverflow.com/a/17938593/1581725
https://stackoverflow.com/a/24411550/1581725
...
And there is also this blog entry here: http://eviltrout.com/2013/03/23/ember-without-data.html it's about using ember without ember-data.
Found this little gem called normalizePayload - maybe this would also work for your case: https://stackoverflow.com/a/21790093/1581725

Iterate through nested Javascript Objects from API response

I've tried 100 different things, and spend days looking through Google and Stackoverflow, but I can't find a solution to this problem. Everything I call after the body of this API response returns undefined!
The response from Facebook SDK looks like this:
[
{
"body": "[
"data": [
{
"name": "Larry Syid Wright",
"administrator": false,
"id": "xxx"
}, {
"name": "Melissa Long Jackson",
"administrator": false,
"id": "xxx"
}, {
"name": "Charlotte Masson",
"administrator": false,
"id": "xxx"
}
],
"paging": {
"next": "url"
}
]"
},{
"body": "{
"data": [
{
"id": "xxx_xxx",
"message": "In honor of Halloween, how many of you have your own ghost stories? Who believes in ghosts and who doesn't?",
"type": "status",
"created_time": "2014-10-31T20:02:01+0000",
"updated_time": "2014-11-01T02:52:51+0000",
"likes": {
"data": [
{
"id": "xxx",
"name": "Joe HerBatman Owenby Jr."
}
],
}
"paging": {
"cursors":
{
"after": "xxx",
"before": "xxx"
}
}
}
},{
"id": "xxx_xxx",
"from": {
"id": "xxx",
"name": "Jessica Starling"
},
"message": "Watching the "Campaign" and I can't help but notice what a fantastic job they did (Will ferrell and all) with that North Carolina accent! Ya'll know we sound different than other southern states ;)",
"type": "status",
"created_time": "2014-11-01T02:36:21+0000",
"updated_time": "2014-11-01T02:36:21+0000",
"likes": {
"data": [
{
"id": "xxx",
"name": "Scott Williams"n
}
]
}
}
],
"paging": {
"previous": "xxx",
"next": "xxx"
}
}"
}
]
This response is from a batch call. If I call them separately, I can easily iterate through the responses, and get everything from them. When I call them in the batch though, I can't get past "body", and I need to use a batch call.
console.log(response[0].body); will return the object inside the body of the first part of the response, but console.log(response[0].body.data); returns undefined. I just don't get it. This should be simple but it's like there's a lock on the door and I don't have the right key.
I normally have no issue iterating through objects, so I don't need a generalized answer. I need help seeing whatever it is here that I don't see. Why does the console show undefined when I call anything after the body, and what do I need to be doing to get any of these values?
That JSON contains nested JSON. body seems to be a string. Use
var body = JSON.parse(response[0].body);
The values from the body are just strings.which are embedded as json.So firstly you would need to parse them using JSON.parse.
The code would be like
var body = JSON.parse(response[0].body);

Categories