I have telemetry events send to playfab. In those events I want to query the content of the Payload. I'm able to do it, but nested properties are all in the same column. I can use the following to extract everything in my event BUT for the SuperProperties nested in Payload. Superproperties are all in the same column
Here is the structure of my event
SchemaVersion": xxxx
"FullName_Namespace": xxxx,
"FullName_Name": xxxx,
"Entity_Id": xxxxx,
"Entity_Type": txxxxx,
"EntityLineage_title": xxxxxx,
"EventData": {
"Timestamp": "xxxxxxx",
"PayloadContentType": "Json",
"EntityLineage": {
"master_player_account": "xxxxxx",
"title_player_account": "xxxxxx",
"namespace": "xxxxx",
"title": "xxxxxx"
},
"SchemaVersion": "xxxxxx",
"Originator": {
"Type": "xxxxxx",
"Id": "xxxxxx"
},
"OriginInfo": {
"Timestamp": "xxxxxx"
},
"FullName": {
"Namespace": "xxxxxx",
"Name": "xxxxxx"
},
"Payload": {
"TimeToCompleteSubStage": xxxxxx,
"TimeToCompleteStage": xxxxxx,
"SuperProperties": {
"GameSessionID": "xxxxxx",
"PlayFabId": "xxxxxx",
"Version": "xxxxxx",
"Index": xxxxxx,
"Time": "xxxxxx"
},
"IdStageFrom": "xxxxxx",
"SubStageId": xxxxxx,
"IdStageTo": "xxxxxx"
},
"Id": "xxxxxx",
"Entity": {
"Type": "xxxxxx",
"Id": "xxxxxx"
}
},
"EventId": xxxxxx,
"Timestamp": xxxxxx,
"EntityLineage_title_player_account": xxxxxx,
"EntityLineage_master_player_account": xxxxxx,
"EntityLineage_namespace": xxxxxx,
"ExperimentVariants": xxxxxx
What I've tried
If found a similar question here, but i'm not sure to fully understand the question OR the answer. Even after looking at this documentation which seems to maybe explain how to do it. The reason ? Because my knowledge in Kusto and even programming in general is basic.
So, is there someone that could try to explain if this is possible to get all the properties under Payload, even the superproperties which are nested in Payload in their specific column ? If so, how to do it ? It does not matter if I query anything else outside the Payload or not
Here are my attempts
['events.all']
| where FullName_Name == 'FTUE_Funnel'
| project Payload = parse_json(EventData.Payload)
| evaluate bag_unpack(Payload)
['events.all']
| where FullName_Name == 'FTUE_Funnel'
| project Payload = parse_json(EventData.Payload.SuperProperties)
| evaluate bag_unpack(Payload)
These ones work, but they are queried separately, which is no ideal.
['events.all']
| where FullName_Name == 'FTUE_Funnel'
| extend Payload = parse_json(EventData.Payload)
| project-away EventData
| evaluate bag_unpack(Payload,'extra_')
This one also work, it queries Payload content BUT put Superproperties in one column + query anything outside payload, which is fine with me
Thank you !
bag_unpack()
datatable(event:dynamic)
[
dynamic
(
{
"SchemaVersion": 1,
"FullName_Namespace": 2,
"FullName_Name": 3,
"Entity_Id": 4,
"Entity_Type": 5,
"EntityLineage_title": 6,
"EventData": {
"Timestamp": 7,
"PayloadContentType": "Json",
"EntityLineage": {
"master_player_account": 8,
"title_player_account": 9,
"namespace": 10,
"title": 11
},
"SchemaVersion": 12,
"Originator": {
"Type": 13,
"Id": 14
},
"OriginInfo": {
"Timestamp": 15
},
"FullName": {
"Namespace": 16,
"Name": 17
},
"Payload": {
"TimeToCompleteSubStage": 18,
"TimeToCompleteStage": 19,
"SuperProperties": {
"GameSessionID": 20,
"PlayFabId": 21,
"Version": 22,
"Index": 23,
"Time": 24
},
"IdStageFrom": 25,
"SubStageId": 26,
"IdStageTo": 27
},
"Id": 28,
"Entity": {
"Type": 29,
"Id": 30
}
},
"EventId": 31,
"Timestamp": 32,
"EntityLineage_title_player_account": 33,
"EntityLineage_master_player_account": 34,
"EntityLineage_namespace": 35,
"ExperimentVariants": 36
}
)
]
| extend Payload = event.EventData.Payload
| project-away event
| evaluate bag_unpack(Payload)
| evaluate bag_unpack(SuperProperties, "SuperProperties_")
IdStageFrom
IdStageTo
SubStageId
TimeToCompleteStage
TimeToCompleteSubStage
SuperProperties_GameSessionID
SuperProperties_Index
SuperProperties_PlayFabId
SuperProperties_Time
SuperProperties_Version
25
27
26
19
18
20
23
21
24
22
Fiddle
Related
I have this result from ansible:
{
"count": 745,
"next": "/api/v2/inventories/xxxx/hosts/?page=160",
"previous": "/api/v2/inventories/xxxx/hosts/?page=14",
"results": [
{
"id": 3932944,
"type": "host",
"url": "/api/v2/hosts/39329/",
"created": "2021-02-16T20:21:58.104406Z",
"modified": "2021-03-16T23:59:28.688226Z",
"name": "machine1",
"description": "imported",
"enabled": true,
"instance_id": "",
"variables": "{\"VirtualMachine\": \"100\", \"CloneFrom\": \"mrzzzzz\", \"BuildingMachine\": \"*\", , \"__DailyCost\": \"{\\\"type\\\":\\\"TimeRate\\\",\\\"cost\\\":{\\\"type\\\":\\\"money\\\",\\\"currencyCode\\\":\\\"dz\\\",\\\"amount\\\":1.274599998125},\\\"basis\\\":{\\\"type\\\":\\\"timeSpan\\\",\\\"unit\\\":\\\"DAYS\\\",\\\"amount\\\":1}}\", \"virtualMachineState\": \"On\", \"vmDescription\": \"testj\"}",
"has_active_failures": false,
"has_inventory_sources": true,
"last_job": 862532,
"last_job_host_summary": 6309369,
},
{
"id": 3932945,
"type": "host",
"url": "/api/v2/hosts/39329/",
"created": "2021-02-16T20:21:58.104406Z",
"modified": "2021-03-16T23:59:28.688226Z",
"name": "machine2",
"description": "imported",
"enabled": true,
"instance_id": "",
"variables": "{\"VirtualMachine\": \"100\", \"CloneFrom\": \"mrzzzzz\", \"BuildingMachine\": \"*\", , \"__DailyCost\": \"{\\\"type\\\":\\\"TimeRate\\\",\\\"cost\\\":{\\\"type\\\":\\\"money\\\",\\\"currencyCode\\\":\\\"dz\\\",\\\"amount\\\":1.274599998125},\\\"basis\\\":{\\\"type\\\":\\\"timeSpan\\\",\\\"unit\\\":\\\"DAYS\\\",\\\"amount\\\":1}}\", \"virtualMachineState\": \"On\", \"vmDescription\": \"testj\"}",
"has_active_failures": false,
"has_inventory_sources": true,
"last_job": 862532,
"last_job_host_summary": 6309369,
},
]
}
I can get the value of results.name when use json_query, but I can't get value of results.varaibles.VirtualMachine for example using json,query because of '"' , so How can I format variables to be a json format , In other world I want someting like :
...
"variables": {
"VirtualMachine": "100",
"CloneFrom": "mrzzzzz",
"BuildingMachine": "*",
"DailyCost": "{"type":"TimeRate","cost":
{"type":"money","currencyCode":"dz","amount":1.274599998125},
"basis":{"type":"timeSpan","unit":"DAYS","amount":1}}",
"virtualMachineState": "On",
"vmDescription": "testj"
}
...
thank for your help at advance.
Update:
I used this Idea posted by #mdaniel (thanks a lot):
{{whatever.results | map(attribute='variables') | map('from_json') | list}}
Iget output that I need, but when I tried to filter like that:
- name: get id, name, hq_os, hq_site and hq_zone
debug:
var: dictresult_format | json_query(jmesquery)
vars:
jmesquery: "[?VirtualMachine: `100`].{From: CloneFrom, description: vmDescription}"
it output nothing :
TASK [task1t : get data from variables*********
Wednesday 17 March 2021 11:28:53 -0400 (0:00:00.049) 0:00:06.842 *******
ok: [hosttower] => {
"dictresult_format | json_query(jmesquery)": ""
}
Can I missed somting, because that "{{whatever.results | map(attribute='variables') | map('from_json') | list}}" return a list not a json?
I just started using jq and json files, and I'm trying to parse a specific file.
I'm tring to do it with jq in command line, but if there's any other way to do it properly, I'm in to give it a try.
The file itself looks like this :
{
"Status": "ok",
"Code": 200,
"Message": "",
"Result": [
{
"ID": 123456,
"Activity": 27,
"Name": Example1",
"Coordinate": {
"Galaxy": 1,
"System": 22,
"Position": 3
},
"Administrator": false,
"Inactive": false,
"Vacation": false,
"HonorableTarget": false,
"Debris": {
"Metal": 0,
"Crystal": 0,
"RecyclersNeeded": 0
},
"Moon": null,
"Player": {
"ID": 111111,
"Name": "foo",
"Rank": 4
},
"Alliance": null
},
{
"ID": 223344,
"Activity": 17,
"Name": "Example2",
"Coordinate": {
"Galaxy": 3,
"System": 44,
"Position": 5
},
"Administrator": false,
"Inactive": false,
"Vacation": false,
"StrongPlayer": false,
"HonorableTarget": false,
"Debris": {
"Metal": 0,
"Crystal": 0,
"RecyclersNeeded": 0
},
"Moon": null,
"Player": {
"ID": 765432,
"Name": "Player 2",
"Rank": 3
},
"Alliance": null
},
(...)
]
}
I would need to extract information based on the galaxy/system/position.
For example, having a script with the proper filters in it and execute something like that :
./parser --galaxy=1 --system=22 --position=3
And it would give me :
ID : 123456
Name : Example1
Activity : 27
...
I tried to do that with curl to grab my json file and jq to parse my file, but I have no idea how I can make that kind of request.
The following should be sufficient to get you on your way.
First, let's assume the JSON is in a file name galaxy.json; second, let's assume the file galaxy.jq contains the following:
.Result[]
| select(.Coordinate | (.Galaxy==$galaxy and .System==$system and .Position==$position))
Then the invocation:
jq -f so-galaxy.jq --argjson galaxy 1 --argjson system 22 --argjson position 3 galaxy.json
would yield the corresponding object:
{
"ID": 123456,
"Activity": 27,
"Name": "Example1",
"Coordinate": {
"Galaxy": 1,
"System": 22,
"Position": 3
},
"Administrator": false,
"Inactive": false,
"Vacation": false,
"HonorableTarget": false,
"Debris": {
"Metal": 0,
"Crystal": 0,
"RecyclersNeeded": 0
},
"Moon": null,
"Player": {
"ID": 111111,
"Name": "foo",
"Rank": 4
},
"Alliance": null
}
Key: Value format
If you want the output to be in key: value format, simply add -r to the command-line options, and append the following to the jq filter:
| to_entries[]
| "\(.key): \(.value)"
Output
ID: 123456
Activity: 27
Name: Example1
Coordinate: {"Galaxy":1,"System":22,"Position":3}
Administrator: false
Inactive: false
Vacation: false
HonorableTarget: false
Debris: {"Metal":0,"Crystal":0,"RecyclersNeeded":0}
Moon: null
Player: {"ID":111111,"Name":"foo","Rank":4}
Alliance: null
I've used pymongo to connect to mongo replica set and print the status of replica set using json dump. I want to parse this output and display "name" and "stateStr" into a list or array for the user to be able to pick a particular host.Here is my json dump output:
{
{
"replSetGetStatus": {
"date": "2016-10-07T14:21:25",
"members": [
{
"_id": 0,
"health": 1.0,
"name": "xxxxxxxxxxx:27017",
"optime": null,
"optimeDate": "2016-10-07T13:50:11",
"self": true,
"state": 1,
"stateStr": "PRIMARY",
"uptime": 32521
},
{
"_id": 1,
"health": 1.0,
"lastHeartbeat": "2016-10-07T14:21:24",
"lastHeartbeatRecv": "2016-10-07T14:21:24",
"name": "xxxxxxxxxxxx:27017",
"optime": null,
"optimeDate": "2016-10-07T13:50:11",
"pingMs": 0,
"state": 2,
"stateStr": "SECONDARY",
"syncingTo": "xxxxxxxxxxxx:27017",
"uptime": 27297
},
{
"_id": 2,
"health": 1.0,
"lastHeartbeat": "2016-10-07T14:21:24",
"lastHeartbeatRecv": "2016-10-07T14:21:24",
"name": "xxxxxxxxxxxxx:27020",
"pingMs": 0,
"state": 7,
"stateStr": "ARBITER",
"uptime": 32517
}
],
"myState": 1,
"ok": 1.0,
"set": "replica1"
}
}
Please try below Javascript code. It worked for me.
use admin;
var result = rs.status();
var length = result.members.length;
for (var i=0;i<length;i++){
print ("Server Name-" +result.members[i].name);
print ("Server State-" +result.members[i].stateStr);
}
My response from backend is not in form which ember store. I am not able to serialize the response.
response.json
[{
"pk": 127,
"url": "http://example.com/api/galleries/127/",
"gallery_name": "Faces",
"thumbnail_url": "https://example.cloud.net/galleryThumbs/2656a05c-4ec7-3eea-8c5e-d8019454d443.jpg",
"time": "1 month ago",
"description": "Created by user",
"is_following": true,
"feedPhotos": [{
"pk": 624,
"url": "http://example.com/api/photos/624/",
"profilePic": "https://example.cloud.net/userDPs/50906ce2-394d-39c8-9261-8cf78e3611c2.jpg",
"userName": "Nabeela",
"userKarma": 915,
"caption": "Old woman spinning her 'chhos-khor' ...a rotation of which is equivalent to the recitation of a mantra.",
"numComments": 0,
"owner": "http://example.com/api/users/44/",
"time": "1 month ago",
"photo_url": "https://example.cloud.net/photos/9cbd6423-3bc5-36e0-b8b4-d725efb3249a.jpg",
"comments_url": "http://example.com/api/photos/624/comments/",
"numFives": 4,
"fivers_url": "http://example.com/api/photogalleries/1362/fivers/",
"fivers_pk": 1362,
"fullphoto_url": "http://example.com/api/photogalleries/1362/photo/",
"fullphoto_pk": 1362,
"is_fived": true,
"hiFiveKarma": 1,
"owner_pk": 44,
"userFirstName": "Nabeela",
"is_bookmarked": false
}, {
"pk": 574,
"url": "http://example.com/api/photos/574/",
"profilePic": "https://example.cloud.net/userDPs/b6f69e4e-980d-3cc3-8b3e-3eb1a7f21350.jpg",
"userName": "Rohini",
"userKarma": 194,
"caption": "Life # Myanmar!",
"numComments": 0,
"owner": "http://example.com/api/users/45/",
"time": "2 months ago",
"photo_url": "https://example.cloud.net/photos/eeae72d5-d6af-391e-a218-b442c0c7e34e.jpg",
"comments_url": "http://example.com/api/photos/574/comments/",
"numFives": 2,
"fivers_url": "http://example.com/api/photogalleries/1303/fivers/",
"fivers_pk": 1303,
"fullphoto_url": "http://example.com/api/photogalleries/1303/photo/",
"fullphoto_pk": 1303,
"is_fived": false,
"hiFiveKarma": 0,
"owner_pk": 45,
"userFirstName": "Rohini",
"is_bookmarked": false
}
]
}, {
"pk": 65,
"url": "http://example.com/api/galleries/65/",
"gallery_name": "Royal",
"thumbnail_url": "https://example.cloud.net/galleryThumbs/d8a900af-1f1d-3977-8cc8-b8bb36e32be5.jpg",
"time": "2 months ago",
"description": "This is a gallery about Royal",
"is_following": false,
"feedPhotos": [{
"pk": 347,
"url": "http://example.com/api/photos/347/",
"profilePic": "https://example.cloud.net/userDPs/50906ce2-394d-39c8-9261-8cf78e3611c2.jpg",
"userName": "Nabeela",
"userKarma": 915,
"caption": "I cannot forget the name of this palace - Moti Mahal (translation: Pearl Palace). Indescribably beautiful, ainnit! at Mehrangarh fort, Jodhp",
"numComments": 0,
"owner": "http://example.com/api/users/44/",
"time": "2 months ago",
"photo_url": "https://example.cloud.net/photos/958ed406-708e-3f01-a2f4-9467cd709fdd.jpg",
"comments_url": "http://example.com/api/photos/347/comments/",
"numFives": 4,
"fivers_url": "http://example.com/api/photogalleries/759/fivers/",
"fivers_pk": 759,
"fullphoto_url": "http://example.com/api/photogalleries/759/photo/",
"fullphoto_pk": 759,
"is_fived": false,
"hiFiveKarma": 0,
"owner_pk": 44,
"userFirstName": "Nabeela",
"is_bookmarked": false
}, {
"pk": 593,
"url": "http://example.com/api/photos/593/",
"profilePic": "https://example.cloud.net/userDPs/95ac6974-f7df-338c-ab84-99fa1df7514c.jpg",
"userName": "Vikanshu",
"userKarma": 932,
"caption": "Marvelous architecture!! in Florence, Italy",
"numComments": 0,
"owner": "http://example.com/api/users/48/",
"time": "1 month ago",
"photo_url": "https://example.cloud.net/photos/7a86eb37-6c68-3d6c-b6cf-2e3b74d330dd.jpg",
"comments_url": "http://example.com/api/photos/593/comments/",
"numFives": 4,
"fivers_url": "http://example.com/api/photogalleries/1363/fivers/",
"fivers_pk": 1363,
"fullphoto_url": "http://example.com/api/photogalleries/1363/photo/",
"fullphoto_pk": 1363,
"is_fived": false,
"hiFiveKarma": 0,
"owner_pk": 48,
"userFirstName": "Vikanshu",
"is_bookmarked": false
}]
}]
How do I serialize this using JSONPISerailizer or any other serializer in ember-cli so that it gets stored in ember store
Reference jsonapi.org
++++Top Level:
Root:
A JSON object must be root of every JSON API request response.
A document must contain at least one top-level members:
1. data: documents "primary data"
2. errors: an array of error objects (id,status,code,title....)
3. meta: a meta object that contains non-standard meta-information (copyright,author...)
member data and errors must not co-exist together.
"data"{}
+++++Resource Objects
1. A resource object MUST contain atleast following top-level member
*id
*type
```
//structure-1
//for galleries
{
"data": {
"type": "galleries",
"id": "1"
}
}
//for photos
{
"data": {
"type": "photos",
"id": "1"
}
}
```
In addition, a resource object may contain any of these top-level members
*attributes
*relationship
*links
*meta
//added attributes first
```
//structure-2
//for galleries
{
"data": {
"type": "galleries",
"id": "1",
"attributes": {
"galleryName": "Faces"
"thumbnailUrl:"https://example.cloud.net/galleryThumbs/2656a05c-4ec7.jpg",
"description": "Created by user",
}
}
}
//for photos
{
"data": {
"type": "photos",
"id": "1",
"attributes":{
userName: "Nabeela",
userKarma: 915
}
}
}
```
//Adding relationship
Relationship object must contain atleast one of the following
*links (containing atleast one of "self" or "related" resource link
*data
*meta
//link in relationship (minimum one required from link,data,meta).
//
```
//structure-3
//for galleries
{
"data":[{ //Array(square bracket as adding relationship one more item to data
"type": "galleries",
"id": "1",
"attributes": {
"galleryName": "Faces"
"thumbnailUrl:"https://example.cloud.net/galleryThumbs/2656a05c-4ec7.jpg",
"description": "Created by user",
},
"relationships":{
"links":{
"self": "https://example.cloud.net/photos/9cbd6423.jpg //"photo_url" in your payload
},
}]
}
}
```
//data in relationship
```
//structure-4
//for galleries
{
"data": [{
"type": "galleries",
"id": "1",
"attributes": {
"galleryName": "Faces"
"thumbnailUrl:"https://example.cloud.net/galleryThumbs/2656a05c-4ec7.jpg",
"description": "Created by user",
},
"relationships":{ //This has all your photo stuff
"links":{
"self": "https://example.cloud.net/photos/9cbd6423.jpg //"photo_url" in your payload
},
"data": { //picked it up from structure-1
"type": "photos",
"id": "77"
}
}]
}
}
```
//Adding related resource "included"
```
//for galleries
{
"data": [{
"type": "galleries",
"id": "1",
"attributes": {
"galleryName": "Faces"
"thumbnailUrl:"https://example.cloud.net/galleryThumbs/2656a05c-4ec7.jpg",
"description": "Created by user",
},
"relationships":{ //This has all your photo stuff
"links":{
"self": "https://example.cloud.net/photos/9cbd6423.jpg //"photo_url" in your payload
},
"data": { //picked it up from structure-1
"type": "photos",
"id": "77"
}
}],
"included":[{
"type": "photos",
"id": "77",
"attributes":{
userName: "Nabeela",
userKarma: 915
},
{
"type": "photos",
"id": "78",
"attributes":{
userName: "Nabeela",
userKarma: 915
}
}]
}
}
```
For collections. I am not confident but try this
Now for collection of galleries.
//for galleries
{
"data": [{
"type": "galleries",
"id": "1",
"attributes": {
"galleryName": "Faces"
"thumbnailUrl:"https://example.cloud.net/galleryThumbs/2656a05c-4ec7.jpg",
"description": "Created by user",
},
"relationships":{ //This has all your photo stuff
"links":{
"self": "https://example.cloud.net/photos/9cbd6423.jpg //"photo_url" in your payload
},
"data": { //picked it up from structure-1
"type": "photos",
"id": "77"
}
},{
"type": "galleries",
"id": "2",
"attributes": {
"galleryName": "Faces"
"thumbnailUrl:"https://example.cloud.net/galleryThumbs/2656a05c-4ec7.jpg",
"description": "Created by user",
},
"relationships":{ //This has all your photo stuff
"links":{
"self": "https://example.cloud.net/photos/9cbd6423.jpg //"photo_url" in your payload
},
"data": { //picked it up from structure-1
"type": "photos",
"id": "79"
}
}],
"included":[{
"type": "photos",
"id": "77",
"attributes":{
userName: "Nabeela",
userKarma: 915
},{
"type": "photos",
"id": "78",
"attributes":{
userName: "Nabeela",
userKarma: 915
},{
"type": "photos",
"id": "79",
"attributes":{
userName: "Nabeela",
userKarma: 915
}
}]
}
}
============Implementation part =================================
JSONSerializer normalization process follows these steps
*normalizeResponse : entry method.
*normalizeCreateRecordResponse : a normalizeResponse for specific operation.
*normalizeSingleResponse|normalizeArrayResponse:
- for methods like createRecord. we expect a single record back.
- for methods like findAll we expect multiple records back.
+normalize =
normalizeArray iterates and calls normalize for each of it's records
normalizeSingle call its once.
+extractID | extractAttributes | extractRelationships
= normalize delegates to these method to turn record payload into jsonAPI format
Starting with normalizeResponse method. If you open and see normalizeResponse method
in json-serializer
link normalizeResponse: https://github.com/emberjs/data/blob/v2.2.1/packages/ember-
data/lib/serializers/json-serializer.js#L192
you with find a switch case switch(requestType). If requestType if
"findRecord" then "normalizeFindRecordResponse" is called
"queryRecord" then "normalizeQueryRecordResponse" is called
"findAll" then "normalizeFindAllResponse" is called
...so on and so forth.
if you notice the parameter passed to all the methods are same as that of normalize
(...arguments) :)
**Lets start for findAll
i.e normalizeResponse -> normalizeFindAllResponse -> normalizeArrayResponse
as normalizeFindAllResponse method has only one line that call
normalizeArrayResponse.
normalizeFindAllResponse
normalizeResponse -> normalizeFindAllResponse -> normalizeArrayResponse ->
_normalizeResponse{ extractMeta,normalize }
extractMeta [extract meta information like pagination and stuff ]
if single: normalize []
example of normalize method in emberjs docs
```
import DS from 'ember-data';
export default DS.JSONSerializer.extend({
normalize: function(typeClass, hash) {
var fields = Ember.get(typeClass, 'fields');
fields.forEach(function(field) {
var payloadField = Ember.String.underscore(field);
if (field === payloadField) { return; }
hash[field] = hash[payloadField];
delete hash[payloadField];
});
return this._super.apply(this, arguments);
}
});
```
"normalizeArrayResponse calls `return this._normalizeResponse
(store,primaryModelClass,payload,id,requestType,false).
so isSingle is false for _normalizeResponse method. so we will have to push all the
related records of included array
in our case the photos which is done by below snippet from "_normalizeRespose"
method.
_normalizeResponse
```
else{
documentHash.data = payload.map((item) => {
let { data, included } = this.normalize(primaryModelClass,item);
if(included){
documentHash.included.push(...included);
}
return data;
});
return documentHash;
}
```
Things are still unclear in the context of our JSON reponse from server
but atleast we know the flow now.
Lets try to apply it for findAll ( as per the flow above).
run "ember g serializer application" //assuming you are using ember-cli and you
intend to make this serializer generic for application.
As of now I have no information how and when normalizeResponse is called. :(
I just scanned through and guess on recieving data from server the store calls
normalizeResponseHelpers which in turn calls normalizeResponse.
In any case "normalizeResponse" is going to send payload and other necessar
information to normalizeFindAllResponse(...arguments) which in turn will call
normalizeArrayResponse(...arguments) which in turn will call "_normalizeRespone".
Here is where we need to take action
for extraMeta and normalize.
+extraMeta
I am not sure if there is any meta information in you json response.
in case there is you can refer to the example mentioned in docs
extractMeta
So I guess you can directly user the normalize method from example in your application ;).
please try and check. Since i am learning ember myself I cannot guarantee it will work but it should. the lonngggg explation is my thought while i was learning the problem/solution
//app/serializers/application.js
+normalize
```
import DS from 'ember-data';
export default DS.JSONSerializer.extend({
normalize: function(typeClass, hash) {
var fields = Ember.get(typeClass, 'fields');
fields.forEach(function(field) {
var payloadField = Ember.String.underscore(field);
if (field === payloadField) { return; }
hash[field] = hash[payloadField];
delete hash[payloadField];
});
return this._super.apply(this, arguments);
}
});
```
The primary key in the JSON from server is pk. You will have to mention that too
http://emberjs.com/api/data/classes/DS.JSONSerializer.html#property_primaryKey
app/serializers/application.js
import DS from 'ember-data';
export default DS.JSONSerializer.extend({
primaryKey: 'pk'
});
I'm trying to get a Map where there are a 'number' with the number of actions and 'actions' with a list of actions.
I've checked the list of actions in java and it works just fine.
I have 4 actions and in json file I'm getting right just the first one.
Controller in java
#RequestMapping(value = "/getactions/{idTask}", method = RequestMethod.GET, produces = "application/json")
#ResponseBody
public Map<String, Object> getActions(Principal principal,
#PathVariable Long idTask) {
logger.info("Task controller get actions...");
List<TaskAction> actions = null;
if (principal == null) {
actions = new ArrayList<TaskAction>();
} else {
actions = taskActionService.getAllTaskActions(idTask);
}
System.out.println(">>>>>>>>Task Controller - Actions>>>>>>>>>>>>> "
+ actions.size());
for (TaskAction ta : actions) {
System.out.println(">>>>>>>>ta: " + ta.getActionname());
}
System.out.println(">>>>>>>>END getAllActions()>>>>>>>>>>>>> ");
Map<String, Object> data = new HashMap<String, Object>();
data.put("actions", actions);
data.put("number", actions.size());
return data;
}
Sysout
>>>>>>>>Task Controller - Actions>>>>>>>>>>>>> 4
>>>>>>>>ta: tacometer
>>>>>>>>ta: hola
>>>>>>>>ta: hi there
>>>>>>>>ta: other action
>>>>>>>>END getAllActions()>>>>>>>>>>>>>
I'm not getting any error, but the json result only gets the first element in the action list and the id of the rest of actions.
json that I get from http...getactions/8
{
"number":4,
"actions":[
{ ... },
3,
4,
5
]
}
The ... is the first action that is well recovered. (I've avoided to write the code for clearity)
Any ideas about what could it be?
Thanks in advance.
Example of json with 2 actions
{
"number": 2,
"actions": [{
"idTaskAction": 4,
"task": {
"idTask": 8,
"taskname": "abbbbbbbbbbbbbb",
"description": "fffffffffffffffqqqqq",
"date": 1389569940000,
"deadline": -23918633280000,
"category": {
"idTaskCategory": 1,
"sortOrder": 0,
"categoryname": "cat1",
"timestamp": 1402437394000
},
"priority": {
"idTaskPriority": 1,
"sortOrder": 0,
"aka": "none",
"priorityname": "low",
"timestamp": 1402437527000
},
"state": {
"idTaskState": 1,
"statename": "pending"
},
"user": {
"idUser": 1,
"username": "joe"
},
"userResponsible": {
"idUser": 1,
"username": "joe"
},
"evaluation": "12345678saad",
"pending": 0,
"actions": [{
"idTaskAction": 2,
"task": 8,
"date": 1402652358000,
"actionname": "tacometer",
"description": "asfdafa",
"duration": 12,
"user": {
"idUser": 1,
"username": "joe"
},
"timestamp": 1411493866000
},
{
"idTaskAction": 3,
"task": 8,
"date": 1404207558000,
"actionname": "hola",
"description": "un dos tres",
"duration": 20,
"user": {
"idUser": 1,
"username": "joe"
},
"timestamp": 1405022827000
},
4,
{
"idTaskAction": 5,
"task": 8,
"date": 1412164741000,
"actionname": "other action",
"description": "ya me my",
"duration": 22,
"user": {
"idUser": 1,
"username": "joe"
},
"timestamp": 1411733131000
}],
"timestamp": 1411733131000
},
"date": 1412074440000,
"actionname": "hi there",
"description": "lkjñlkj ya",
"duration": 25,
"user": {
"idUser": 1,
"username": "joe"
},
"timestamp": 1411733090000
},
5]
}
The problem was that the classes Task, User... has #JsonIdentityInfo with ObjectIdGenerator.PropertyGenerator.class option so when Jackson try to serialize the object into json, if the object it is already in the file, then it is not added again. This way avoid to serialize json file with infinite recursions.
To solve this we need to change ObjectIdGenerator.PropertyGenerator.class for ObjectIdGenerator.None.class so that the objects are serialized even if they are already part of other objects.
Change
#JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "#id")
for
#JsonIdentityInfo(generator = ObjectIdGenerators.None.class, property = "#id")