Rearranging JSON output in Laravel - json

There are a few very similar questions, but not this exact thing. Let's start with my model:
Contest (hasMany Event, belongsToMany Player)
Player (hasMany Event, belongsToMany Contest, belongsToMany Event)
Event (belongsTo Contest, belongsToMany Players->withPivot('score)) (actually called ContestEvent since Event is a Laravel class)
I'm writing an API to do other stuff with the data. Right now I get this output from a given Contest:
{
"id": "1",
"owner_id": "1",
"name": "Some Contest",
"start_date": "2013-08-09",
"end_date": "2013-08-31",
"is_public": "1",
"is_finished": "0",
"players": [
{
"id": "1",
"first_name": "Bob",
"last_name": "Smith",
"initial_name": "Bob S",
"pivot": {
"contest_id": "1",
"user_id": "1"
}
}
],
"events": [
{
"id": "1",
"name": "Stage 1",
"date": "2013-08-01",
"players": [
{
"id": "1",
"first_name": "Bob",
"last_name": "Smith",
"initial_name": "Bob S",
"pivot": {
"contest_event_id": "1",
"user_id": "1",
"score": "5"
}
}
]
}
]
}
The pivot part is junk data, except for the score part under events. I can hide the whole pivot part with $hidden, but I want to access the score value one step up, outside of the pivot array.
I've messed around with $append and getFooAttribute(), but no success so far -- I can't quite figure out how to get Eloquent to do what I want. Any suggestions?

Rather than rearranging my model, I discovered Fractal, which made creating custom JSON output exactly the way you want it really easy.

Related

Convert Nested JSON to Flat JSON using jolt Spec based on multiple inputs (if else)

I need to convert the nested json to flat json by given type of input, if its flat json or nested json gives output as flat json respectively. I haven't seen any correct resource related to the this topic. I given the inputs and outputs below.
I am having some trouble with converting the nested JSON to flat JSON, and didn't get any closer as to what is mentioned problem. I need to transform a JSON structure by using a JOLT spec. I use https://jolt-demo.appspot.com to test the following below. Help me, how can i get the expected out, with this code
Input-1:
{
"MessageType": "CREATION",
"Number": "123",
"Status": "created sucessfully",
"StopSequence": "1",
"Code": [
{
"CodeName": "ABC",
"ShortDescription": "short description about ABC",
"TimeImpact": 234,
"Rank": 1
},
{
"ReasonCodeName": "XYZ",
"ShortDescription": "short description about ABC",
"TimeImpact": 123,
"Rank": 2
}
]
}
Input-2:
{
"MessageType": "UPDATE",
"Number": "345",
"PNumber": "P123",
"Status": "updated sucessfully",
"StopSequence": "2",
"Id": 1234,
"LNumber": "34565",
"DeviceID": "7645235",
"Timestamp": "2015-10-01T16:00:00-05:00",
"Timezone": "US/New_York",
"TimezoneShortName": "EST",
"Unlocode": "XXXX",
}
Expected Output-1 if input 1 passes:
[
{
"MessageType": "CREATION",
"Number": "123",
"Status": "created sucessfully",
"StopSequence": "1",
"Code": "1",
"CodeName": "ABC",
"ShortDescription": "short description about ABC",
"TimeImpact": 234,
"CodeRank": 1
},
{
"MessageType": "CREATION",
"Number": "123",
"Status": "created sucessfully",
"StopSequence": "1",
"Code": "2",
"ReasonCodeName": "XYZ",
"ShortDescription": "short description about ABC",
"TimeImpact": 123,
"Rank": 2
}
]
Expected Output-2 if input 2 passes:
{
"MessageType": "UPDATE",
"PNumber": "P123",
"Status": "updated sucessfully",
"StopSequence": "2",
"Id": 1234,
"Timestamp": "2015-10-01T16:00:00-05:00",
"Timezone": "US/New_York",
}
What you need is to repeat as much as the number of objects of the Code array. So, walk through by them as picking the related values from the out of the array such as
[
{
"operation": "shift",
"spec": {
"Code": {
"*": {
"#(2,MessageType)": "[&1].MessageType", // "#(2,MessageType)" means going up the tree 2 levels to reach the position of "MessageType" , [&1] means combining the values as array of objects depending on the indexes of the array
"#(2,Number)": "[&1].Number",
"#(2,Status)": "[&1].Status",
"#(2,StopSequence)": "[&1].StopSequence",
"#(0,Rank)": "[&1].Code", // to copy the values of the "Rank" to "Code"
"*": "[&1].&"
}
},
"MessageT*|PNu*|St*|Id|Times*|Timezone": "&"
}
}
]

How to group by? Django Rest Framework

I am developing an API Rest based on Django, I have two models:
Album
Track
I am trying to get the right format on this JSON (this is what I am getting now):
[
{
"album": "album-123kj23mmmasd",
"track": {
"id": 6,
"uuid": "2c553219-9833-43e4-9fd1-44f536",
"name": "song name 1",
},
"duration": 2
},
{
"album": "album-123kj23mmmasd",
"track": {
"id": 7,
"uuid": "9e5ef1da-9833-43e4-9fd1-415547a",
"name": "song name 5",
},
"duration": 4
},
This is what I would like to reach, I would like to group by 'albums':
[
{
"album": "album-123kj23mmmasd",
"tracks": [{
"id": 6,
"uuid": "2c553219-9833-43e4-9fd1-44f536",
"name": "song name 1",
"duration": 2
},
{
"id": 7,
"uuid": "9e5ef1da-9833-43e4-9fd1-415547a",
"name": "song name 5",
"duration": 4
},
]
},
]
EDIT 1: I am using Foreign Key instead ManyToMany
class Track(models.Model:
name, creation_date, etc...
class Album(models.Model):
track = models.Foreignkey(Track, on_delete=models.CASCADE)
Thanks in advance
SOLUTION:
Due the model complexity, I decided to user BaseSerializer, which allows to create custom response.

Filter API by its Key

Heys guys have some JSON data and API trying to figure out what the API would be to filter its category, currently only have 'food and items'. here the data.
{
"id": 1587428052314,
"_id": "5e9e5599a3f3e540e9c6553c",
"Title": "Home Cleaning Sanitiser Box",
"Description": "This box has everything you need - right now!"
"Phone": "021881821921",
"Category": "food"
}
Here is api: localhost:4000/api/user-listing/
Could I filter it somehow within my .then of promise chain?
Axios.get("localhost:4000/api/user-listing")
.then((res) => {
// in here ?? this.setState({ listings: res.data });
});
Cheers
There are multiple ways to do this as you expected. If you expect that one endpoint should exist to retrieve all the data with "Category": "food" there is nothing you can do about it with frontend tools (actually there are a couple of ways but they ain't come from backend anymore).
Problem illustration
So we suppose when we call localhost:4000/api/user-listing/ we will receive an array of objects which includes multiple objects with "Category": "food", then we suppose we have retrieved the following data from the above endpoint.
[{
"id": 1,
"_id": "5e9e5599a3f3e540e9c6553c-1",
"Title": "coke",
"Description": "This box has everything you need - right now!",
"Phone": "021881821921",
"Category": "drink"
},
{
"id": 2,
"_id": "5e9e5599a3f3e540e9c6553c-2",
"Title": "salmon",
"Description": "This box has everything you need - right now!",
"Phone": "021881821921",
"Category": "food"
},
{
"id": 3,
"_id": "5e9e5599a3f3e540e9c6553c-3",
"Title": "soda",
"Description": "This box has everything you need - right now!",
"Phone": "021881821921",
"Category": "drink"
},
{
"id": 4,
"_id": "5e9e5599a3f3e540e9c6553c-4",
"Title": "rice",
"Description": "This box has everything you need - right now!",
"Phone": "021881821921",
"Category": "food"
}
]
NOTE: I just made this example array of data for more illustration. You should replace it with your res.data in your code.
Filtering data
To get all the data with "Category": "food" we can simply do the following:
const arrayOfData = [{
"id": 1,
"_id": "5e9e5599a3f3e540e9c6553c-1",
"Title": "coke",
"Description": "This box has everything you need - right now!",
"Phone": "021881821921",
"Category": "drink"
},
{
"id": 2,
"_id": "5e9e5599a3f3e540e9c6553c-2",
"Title": "salmon",
"Description": "This box has everything you need - right now!",
"Phone": "021881821921",
"Category": "food"
},
{
"id": 3,
"_id": "5e9e5599a3f3e540e9c6553c-3",
"Title": "soda",
"Description": "This box has everything you need - right now!",
"Phone": "021881821921",
"Category": "drink"
},
{
"id": 4,
"_id": "5e9e5599a3f3e540e9c6553c-4",
"Title": "rice",
"Description": "This box has everything you need - right now!",
"Phone": "021881821921",
"Category": "food"
}
]
const newArray = arrayOfData.filter(data => data.Category === "food")
console.log(newArray)
UPDATE
So as you update the question if you want to deal with your data in .then it will be something like this:
Axios.get("localhost:4000/api/user-listing")
.then((res) => {
this.setState({
listing: res.data.filter(data => data.Category === "food")
})
});

Menu using AngularJS

I need to create menu using AngularJS based on JSON file that looks like:
{
"menu": [{
"id": "1",
"name": "Movies",
"parent_id": "0"
}, {
"id": "2",
"name": "Trailers",
"parent_id": "1"
}, {
"id": "3",
"name": "Action And Adventure",
"parent_id": "1"
}, {
"id": "4",
"name": "Animation",
"parent_id": "3"
}, {
"id": "5",
"name": "Kids",
"parent_id": "0"
}]
}
The list should looks like:
Movies
Trailers
Action And Adventure
Animation
Kids
I really don't know how to create this, any help would be great.
Please go through this link, you just need to have the tree structure in angularjs. Go through this link, Hope this would help!

How do i check my Json

I'm using Titanium Appcelerator to develop an Android application..I getting an error while using 'ACS JSON' .. I trying to use posts query, But i getting different kinds of array ..i need to check is whether the string is available or not before access..
For Example:
"response": {
"posts": [
{
"id": "52e7800340b4b0aa134",
"title": "test",
"created_at": "2014-01-28T10:01:39+0000",
"updated_at": "2014-01-30T11:59:54+0000",
"content": "#hi all",
"reviews_count": 3,
"ratings_count": 3,
"ratings_average": 3.67,
"ratings_summary": {
"5": 1,
"3": 2
},
"user": {
"id": "52e5e87f08a3e70b3309c3e3",
"first_name": "aa",
"last_name": "ss",
"created_at": "2014-01-27T05:02:55+0000",
"updated_at": "2014-01-30T11:58:49+0000",
"external_accounts": [
],
"confirmed_at": "2014-01-27T05:02:55+0000",
"username": "ss",
"role": "a",
"admin": "false"
},
"custom_fields": {
"postedby": "aa",
}
},
{
"id": "52e7908a3e70b3d0a9614",
"title": "bb",
"tags": [
"sdf",
],
"created_at": "2014-01-28T11:46:00+0000",
"updated_at": "2014-01-30T11:09:17+0000",
"content": "#hi# #kWh v #sdf",
"user": {
"id": "52e5e87f08a3e70b3309c3e3",
"first_name": "bb",
"last_name": "bbc",
"created_at": "2014-01-27T05:02:55+0000",
"updated_at": "2014-01-30T11:58:49+0000",
"external_accounts": [
],
"confirmed_at": "2014-01-27T05:02:55+0000",
"username": "b",
"role": "b",
"admin": "false"
},
"custom_fields": {
"postedby": "b"
}
},
See I getting *ratings_count* in my first post..while trying access this inside for loop i getting error..
Now i need to check is whether the string is available or not before access..!
In titanium you can check anything whether it exist or not by using if statment.You can do this
if(ratingcount){
//Do here whatever you want to do
}
Thanks
Try:
for (var i in response.posts) {
post = response.posts[i];
if (post.ratings_count) {
/* Do operations for post with ratings */
} else {
/* Do operations for post without ratings */
}
}
This is pretty basic operation in JavaScript, so before you dive deeper into Titanium it's good to catch up with plain JS before.