How to optimize JsonResult after solving Self Referencing? - json

The following image describes my model relationship between User and Room.
There is a Many to Many relationship between them,
and I have resolved the Self Reference issue by JSON.NET
and adding some configurations to the Application_Start function.
It looks like:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RouteConfig.RegisterRoutes(RouteTable.Routes);
JsonConvert.DefaultSettings = () => new JsonSerializerSettings
{
Formatting = Newtonsoft.Json.Formatting.Indented,
ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
};
}
I defined a API like this to return All the users in database as Json.
public ActionResult Index()
{
return Content(JsonConvert.SerializeObject(db.UserSet), "application/json");
}
The point is , when I get a JsonResult , it looks like
(Every "User" has a navigation attribute "Room" )
[
{
"Room": [
{
"User": [
{
"Room": [],
"Id": 3,
"Name": "waterball",
"Account": "pppaass",
"Password": "123"
}
],
"Id": 1,
"Name": "sadafsa"
}
],
"Id": 2,
"Name": "waterball",
"Account": "safasfasd",
"Password": "123"
},
{
"Room": [
{
"User": [
{
"Room": [],
"Id": 2,
"Name": "waterball",
"Account": "safasfasd",
"Password": "123"
}
],
"Id": 1,
"Name": "sadafsa"
}
],
"Id": 3,
"Name": "waterball",
"Account": "pppaass",
"Password": "123"
}, ........
Obviously , the result looks complex ,
How can I get only the Id,Name but NO User attributes of each Room ?
Or what exactly is the common way people handle with this problem?
===========================================================
I have changed my codes to reach my requirement,
but is this actually the common way to resolve this...?
Or does it have some potential problems?
public ActionResult Index()
{
var result = from u in db.UserSet
select new
{
Id = u.Id,
Account = u.Account,
Password = u.Password,
Room = from r in u.Room
select new
{
Id = r.Id,
Name = r.Name
}
};
return Content(JsonConvert.SerializeObject(result), "application/json");
}

Related

How to return specific fields from a JSON object array in angular http service as response

My Interface is like this:
export interface User {
id: number;
name: string;
}
Response i received from api is:
[
{
"id": 1,
"name": "Leanne Graham",
"username": "Bret",
"email": "Sincere#april.biz"
},
{
"id": 2,
"name": "Ervin Howell",
"username": "Antonette",
"email": "Shanna#melissa.tv"
}
]
I wish to extract only id and name fields and return as response
[
{
"id": 1,
"name": "Leanne Graham"
},
{
"id": 2,
"name": "Ervin Howell"
}
]
getdata(): Observable<User[]>{
return this.http.get<User[]>('https://jsonplaceholder.typicode.com/users').pipe(
map((data: User[])=> {
//how to extract id and name here
})
)
}
I need to return only id and name fields from
the whole api response. How can i achieve that using map
or any other techniques inside service, Please guide me
getdata(): Observable<User[]>{
return this.http.get<User[]>('https://jsonplaceholder.typicode.com/users').pipe(
map((data: User[])=> {
// just map the data
return data.map(u => ({id: u.id, name: u.name}))
})
)
}

Mapping data that contains dots in React

I am trying to map the data in React that is coming from the API but I am having problems mapping the object that contains dots for example this: name.en_US.
What is the proper way to map this object and keeping the data structure that I have?
I am getting the date in this format from the API:
{
"user": "User",
"employeeId": "0000",
"businessCustomer": "customer",
"endCustomer": {
"name": "",
"address": "",
"place": ""
},
"device": {
"shipmentIds": "23",
"name.en_US": "wasi",
"name.fi_FI": " masi"
},
"task": {
"time": "2019-02-10T16:55:46.188Z",
"duration": "00:00:24",
"sum": "75€"
}
},
And then I am trying to map it using the following code.
const {
user,
employeeId,
businessCustomer,
endCustomer,
device,
task
} = task;
const{
endCustomerName,
address,
place
} = endCustomer;
const {
shipmentIds,
names
} = device;
const{
en_US,
fi_FI
} = names;
const {
time,
duration,
summa
} = task;
const data = {
"user": "User",
"employeeId": "0000",
"businessCustomer": "customer",
"endCustomer": {
"name": "",
"address": "",
"place": ""
},
"device": {
"shipmentIds": "23",
"name.en_US": "wasi",
"name.fi_FI": " masi"
},
"task": {
"time": "2019-02-10T16:55:46.188Z",
"duration": "00:00:24",
"sum": "75€"
}
};
const { device } = data;
const {
shipmentIds,
'name.en_US': name_en_US,
'name.fi_FI': name_fi_FI
} = device;
const nameUS = device['name.en_US'];
console.log(name_en_US, nameUS);
Use [ ] notation like, device['name.en_US'] .
You can destructure your propery as #Vishnu mentioned, or you could also destructure it by providing a valid key name
const {
shipmentIds,
'name.en_US': name_en_US,
'name.fi_FI': name_fi_FI
} = device;
And then you could access your variable with name_en_US.

How to Check a value in a nested JSON using Postman

I have a nested JSON returned from an API that I am hitting using a GET request, in POSTMAN chrome app. My JSON looks like this.
{
"resultset": {
"violations": {
"hpd": [
{
"0": {
"ViolationID": "110971",
"BuildingID": "775548",
"RegistrationID": "500590",
"Boro": "STATEN ISLAND",
"HouseNumber": "275",
"LowHouseNumber": "275",
"HighHouseNumber": "275",
"StreetName": "RICHMOND AVENUE",
"StreetCode": "44750",
"Zip": "10302",
"Apartment": "",
"Story": "All Stories ",
"Block": "1036",
"Lot": "1",
"Class": "A",
"InspectionDate": "1997-04-11",
"OriginalCertifyByDate": "1997-08-15",
"OriginalCorrectByDate": "1997-08-08",
"NewCertifyByDate": "",
"NewCorrectByDate": "",
"CertifiedDate": "",
"OrderNumber": "772",
"NOVID": "3370",
"NOVDescription": "§ 27-2098 ADM CODE FILE WITH THIS DEPARTMENT A REGISTRATION STATEMENT FOR BUILDING. ",
"NOVIssuedDate": "1997-04-22",
"CurrentStatus": "VIOLATION CLOSED",
"CurrentStatusDate": "2015-03-10"
},
"count": "1"
}
]
}
},
"count": "1",
"total_page": 1,
"current_page": 1,
"limit": [
"0",
"1000"
],
"status": "success",
"error_code": "",
"message": ""
}
I am trying to test whether my response body has "ViolationID":"110971".
I tried the below code in postman:
var jsonData =JSON.parse(responseBody);
tests["Getting Violation Id"] = jsonData.resultset.violations.hpd[0].ViolationID === 110971;
Two issues I noticed in the provided data. The following suggestions might help you:
Add missing closing braces at the end.
Add missing 0 in the index like this: resultset.violations.hpd[0].0.ViolationID
If the hpd array always contains only 1 member, the test might be pretty straightforward:
pm.test('Body contains ViolationID', () => {
const jsonBody = pm.response.json();
const violationId = jsonBody.resultset.violations.hpd[0]["0"].ViolationID;
pm.expect(parseInt(violationId)).to.eql(110971);
})
However, if hpd array might contain more than one member, it gets a bit trickier. I would suggest mapping only ViolationID keys from nested objects:
pm.test('Body contains ViolationID', () => {
const jsonBody = pm.response.json();
const violationIds = jsonBody.resultset.violations.hpd.map(hpd => hpd["0"].ViolationID);
pm.expect(violationIds).to.contain('110971');
})

Dynamically Parsing JSON with Groovy

I have a JSON document pulled back from a support system API. With my code, I want to pull out the pre-configured fields dynamically, presuming that the JSON may have more or fewer of the desired fields when my program calls the API.
I have some code that works, though it seems very convoluted and inefficient.
Here is a snippet of the pieces of JSON that I'm interested in:
{
"rows": [
{
"assignee_id": 1,
"created": "2017-01-25T14:13:19Z",
"custom_fields": [],
"fields": [],
"group_id": 2468,
"priority": "Low",
"requester_id": 2,
"status": "Open",
"subject": "Support request",
"ticket": {
"description": "Ticket descritpion",
"id": 1000,
"last_comment": {
"author_id": 2,
"body": "Arbitrary text",
"created_at": "2017-02-09T14:21:38Z",
"public": false
},
"priority": "low",
"status": "open",
"subject": "Support request",
"type": "incident",
"url": "Arbitrary URL"
},
"updated": "2017-02-09T14:21:38Z",
"updated_by_type": "Agent"
},
{
"assignee_id": 1,
"created": "2017-02-09T14:00:18Z",
"custom_fields": [],
"fields": [],
"group_id": 3579,
"priority": "Normal",
"requester_id": 15,
"status": "Open",
"subject": "Change request",
"ticket": {
"description": "I want to change this...",
"id": 1001,
"last_comment": {
"author_id": 20,
"body": "I want to change the CSS on my website",
"created_at": "2017-02-09T14:12:12Z",
"public": true
},
"priority": "normal",
"status": "open",
"subject": "Change request",
"type": "incident",
"url": "Arbitrary URL"
},
"updated": "2017-02-09T14:12:12Z",
"updated_by_type": "Agent"
}
]
}
I have an ArrayList called wantedFields that I build up from a config to define which information I want to pull out from the JSON:
["id","subject","requester_id","status","priority","updated","url"]
The complexity is that data is replicated in the API, and I only want to pull out data once, with a preference for the data in "rows" where applicable. My method for doing this is below. It feels like I'm repeating code but I can't really see how to make this work more efficiently. The JSON is held as "viewAsJson".
def ArrayList<Map<String,Object>> assignConfiguredFields(viewAsJson, wantedFields) {
//Pull out configured fields from JSON and store as Map to write as CSV later
ArrayList<Map<String,Object>> listOfDataToWrite = new ArrayList<Map<String,Object>>()
ArrayList<String> rowKeyList = new ArrayList<String>()
def validationRow = viewAsJson.rows.get(0)
//Compare one row object to config first
validationRow.each { k, v ->
if (wantedFields.contains(k)) {
wantedFields.remove(k)
rowKeyList.add(k)
}
}
ArrayList<String> ticketKeyList = new ArrayList<String>()
def validationTicket = viewAsJson.rows.ticket.get(0)
//Compare one ticket object to config first
validationTicket.each { k, v ->
if (wantedFields.contains(k)) {
wantedFields.remove(k)
ticketKeyList.add(k)
}
}
def rows = viewAsJson.rows
def tickets = viewAsJson.rows.ticket
//Pull matching ticket objects from JSON and store in Map
ArrayList<Map<String,Object>> tickList= new ArrayList<>()
ArrayList<Map<String,Object>> rowList= new ArrayList<>()
rows.each { row ->
Map<String,Object> rowMap = new HashMap<>()
row.each { k, v ->
if(rowKeyList.contains(k))
rowMap.put(k,v)
}
rowList.add(rowMap)
}
tickets.each { ticket ->
Map<String,Object> ticketMap = new HashMap<>()
ticket.each { k, v ->
if(ticketKeyList.contains(k))
ticketMap.put(k, v)
}
tickList.add(ticketMap)
}
for (int i = 0; i < rowList.size(); i++) {
HashMap<String,Object> dataMap = new HashMap<>()
dataMap.putAll(rowList.get(i))
dataMap.putAll(tickList.get(i))
listOfDataToWrite.add(dataMap)
}
println listOfDataToWrite
return listOfDataToWrite
}
I know there should be some validation for if the wantedFields ArrayList is still populated. I've iterated on this code so many times I just forgot to re-add that this time.
I don't know if you still need this code but why not try something like this.
Have a translation map and run each row through it.
Object tranverseMapForValue(Map source, String keysToTranverse, Integer location = 0){
List keysToTranverseList = keysToTranverse.split(/\./)
tranverseMapForValue(source, keysToTranverseList, location)
}
Object tranverseMapForValue(Map source, List keysToTranverse, Integer location = 0){
if(source.isEmpty() || keysToTranverse.isEmpty()){
return null
}
String key = keysToTranverse[location]
if(source[key] instanceof Map){
return tranverseMapForValue(source[key], keysToTranverse, location + 1)
}
else{
return source[key]
}
}
Map translation = [
"ticket.id": "id",
"ticket.subject": "subject",
"requester_id": "requester_id",
"ticket.status": "status",
"priority": "priority",
"updated": "updated",
"ticket.url": "url"
]
List rows = []
json.rows.each{ row ->
Map mapForRow = [:]
translation.each{ sourceKey, newKey ->
mapForRow << [(newKey): tranverseMapForValue(row, sourceKey)]
}
rows.add(mapForRow)
}

RethinkDB filter on nested objects

I need the solution for filter data by nested objects.
So, this is my JSON data:
{
"create_datetime": 1431000977 ,
"creator": {
"company": {
"id": 0 ,
"name": "Some name"
} ,
"manager": {
"id": 0 ,
"name": ""
}
} ,
"finished_datetime": 1431615600 ,
"id": "00949296-cbea-4d4a-a780-7c8d918a7fd6" ,
"participants": [ ],
"status": "created" ,
"tender_categories": [
1285
] ,
"views": [ ]
},
{
"create_datetime": 1431416740 ,
"creator": {
"company": {
"id": 70922233 ,
"name": "Some company name"
} ,
"manager": {
"id": 1003546168 ,
"name": "Some manager name"
}
} ,
"finished_datetime": 1432857600 ,
"id": "28e0936b-84e0-4ffc-9ad1-78a1d34e9033" ,
"participants": {
"788190": {
"creator": {
"company": {
"id": 788190 ,
"name": "Company name"
} ,
"manager": {
"id": 1003546168 ,
"name": "Manager Name"
}
} ,
"dt_applied": 1431416778 ,
"viewed": false
}
} ,
"status": "created" ,
"tender_categories": [1303] ,
"views": [788190]
}
I need select one record from this JSON where we have participants, that not viewed. I wrote a lot of code, but one one work.
r.db('test').table('tenders').filter(function(tender) {
return tender('participants').coerceTo('array').map(function(participant) {
return participant('viewed').eq(false)
});
});
and
r.db('pm').table('b2b_tenders').map(function(tender) {
return tender('participants').filter(function(key) {
return tender(key)('viewed').eq(false)
});
});
and so one. Help pls some one.
Any type of filtering with nested objects is perfectly doable. In your case, it seems you want all documents, where all participants have the property view set to false.
Here's a very long, yet complete and safe way of checking for something like this:
r.db('test').table('tenders')
// Only get all documents with `participants` property
.hasFields('participants')
// Only get documents where the `participants` property is an object
.filter(function (row) {
return row('participants').typeOf().eq('OBJECT')
})
// Only get documents where all participants have a `viewed` property
.filter(function (row) {
return row('participants').coerceTo('array')
.map(function (row) {
return row(1).hasFields('viewed')
})
.distinct()
.eq([true])
})
// Only get documents where all participants have a `viewed` property set to `true`
.filter(function (row) {
return row('participants').coerceTo('array')
.map(function (row) {
return row(1)('viewed').eq(false)
})
.distinct()
.eq([true])
})
You can probably take out or change parts of this query to fit your needs and depending on how much you know about the documents that are coming in. But, this query shows how to deal with nested properties.