I have a form where i collect the form data and when i serializeArray() this form i have this:
[
{
"name": "authenticity_token",
"value": "HRjaGFRSqX6EqTYnyohQbc9g6P6RTsDgV3qizYuoh+E="
},
{
"name": "test[form_meta][index]",
"value": "0"
},
{
"name": "test[form_meta][location]",
"value": "http://localhost/static/test/password.html"
},
{
"name": "test[form_meta][title]",
"value": "Passwords Form"
},
{
"name": "test[form_meta][id]",
"value": "form1"
},
{
"name": "test[data][email[]]",
"value": "arnel#personal.com"
},
{
"name": "test[field_meta][email[]]",
"value": "test.place_detail_email"
},
{
"name": "test[data][password[]]",
"value": "test"
},
{
"name": "test[field_meta][password[]]",
"value": "test.alarm_password"
},
{
"name": "test[type][email[]]",
"value": "text"
},
{
"name": "test[label][email[]]",
"value": "Email Address:"
},
{
"name": "test[type][password[]]",
"value": "text"
},
{
"name": "test[label][password[]]",
"value": "Password:"
},
{
"name": "rec[email[]]",
"value": "test.previous_address_category"
},
{
"name": "rec[password[]]",
"value": "c_test.password[]"
}
]
This is OK. But when i send it to my controller like this:
$.ajax({
type: "post",
data: data,
success: function(){<code>},
error: function(){<code>}
});
I get this on my controller:
{
"authenticity_token"=>"HRjaGFRSqX6EqTYnyohQbc9g6P6RTsDgV3qizYuoh+E=",
"test"=>{
"form_meta"=>{
"index"=>"0",
"location"=>"http://localhost/static/test/password.html",
"title"=>"Passwords Form",
"id"=>"form1"
},
"data"=>{
"email"=>[
nil
],
"password"=>[
nil
]
},
"field_meta"=>{
"email"=>[
nil
],
"password"=>[
nil
]
},
"type"=>{
"email"=>[
nil
],
"password"=>[
nil
]
},
"label"=>{
"email"=>[
nil
],
"password"=>[
nil
]
}
},
"rec"=>{
"email"=>[
nil
],
"password"=>[
nil
]
},
"controller"=>"test",
"action"=>"create"
}
The [nil] arrays are killing me here. What can i do so don't have to change the form and to get the real entered value and not the [nil] values.
Is there any solution for this problem
Related
I would like to know if there is a better way to deal with nested forEach when it comes to dealing with objects with properties that are nested arrays themselves.
My object (summarized):
{
...,
"tx_responses": [
{
...
"logs" : [
{
...,
"events": [
{
"type": "coin_received",
"attributes": [
{
"key": "receiver",
"value": "somesome"
},
{
"key": "amount",
"value": "somesome"
}
]
},
...
{
"type": "transfer",
"attributes": [
{
"key": "recipient",
"value": "somesome"
},
{
"key": "sender",
"value": "somesome"
},
{
"key": "amount",
"value": "somesome"
}
]
},
{
"type": "withdraw_rewards",
"attributes": [
{
"key": "amount",
"value": "somesomesomehere"
},
{
"key": "validator",
"value": "somesome"
}
]
},
...
]
}
],
...
I am essentially trying to extract all { key: 'amount', value: 'somesomesomehere' } objects in the "attributes" array of the "type" : "withdraw_rewards" object in the "events" array.
Currently this is the code I wrote to carry out my task:
getWithdrawnAmounts: async(del_addr_) => {
let withdrawnAmounts = [];
const res = await axios.get("some_url_that_uses_del_addr_");
res.data.tx_responses.forEach(txr => {
txr.logs.forEach(log => {
log.events.forEach(evnt => {
if (evnt.type == "withdraw_rewards") {
evnt.attributes.forEach(attr => {
if (attr.key == "amount") {
withdrawnAmounts.push(attr);
}
})
}
})
})
});
return withdrawnAmounts;
}
The code helps me to get what I need, but I was wondering if there is a better way to write my code so that I dont have to use so many nested .forEach methods. I was wondering if I should use .flat() or .flatMap() but I'm curious to know how would people approach this?
Thank you!
You are going to have to call some kind of iteration for each level you're going deeper.
Now, there is a more functional way to get the desired data, using flatMap and filter:
const data = { "tx_responses": [{ "logs": [{ "events": [{ "type": "coin_received", "attributes": [{ "key": "receiver", "value": "somesome" }, { "key": "amount", "value": "somesome" }]}, { "type": "transfer", "attributes": [{ "key": "recipient", "value": "somesome" }, { "key": "sender", "value": "somesome" }, { "key": "amount", "value": "somesome" }]}, { "type": "withdraw_rewards", "attributes": [{ "key": "amount", "value": "somesomesomehere" }, { "key": "validator", "value": "somesome" }]}]}]}]};
const result = data.tx_responses
.flatMap(r => r.logs
.flatMap(l => l.events.filter(e => e.type === 'withdraw_rewards')
.flatMap(e => e.attributes.filter(a => a.key === 'amount'))
)
);
console.log(result);
I am trying to the values from my data.json which consists of array of objects. I am trying to get the values by using map method on json data. My Json dat structure is like Array->Object->Array-Object([{[{}]}]). This is how the data is structured in Json. I have written down the Json data and logic to get the values down. Whenever I am trying to get the values from (inner array of object) I am ending up with undefined. Any one could assist me how to resolve this issue. Thanks in advance!
[
{
"key": "row-0",
"cells": [
{
"key": "cell-0",
"id": "ID-0",
"headerName": "Name",
"CustomerName": "ABC"
},
{
"key": "cell-1",
"id": "ID-1",
"headerName": "RegID",
"CustomerID": "P-01"
},
{
"key": "cell-2",
"id": "ID-2",
"headerName": "Detail",
"Deatil": "Abc"
}
]
},
{
"key": "row-1",
"cells": [
{
"key": "cell-1",
"id": "ID-1",
"headerName": "Name",
"CustomerName": "CDE"
},
{
"key": "cell-2",
"id": "ID-2",
"headerName": "RegID",
"CustomerID": "P-02"
},
{
"key": "cell-3",
"id": "ID-3",
"headerName": "Detail",
"Deatil": "CDE"
}
]
}
]
//Logic
{mockData.map((values, index) => {
console.log("VALUES", values);
return values.cells.map(({ headerName, ...rest }) => {
console.log("JSON", JSON.stringify(rest));
console.log("REST", rest.CustomerName);---> getting undefined(I tried many approach everything is giving me undefined)
});
})}
I have created an example for you
As mentioned in the above comment.. elements without customerName will give undefined.
let mockData = [{
"key": "row-0",
"cells": [{
"key": "cell-0",
"id": "ID-0",
"headerName": "Name",
"CustomerName": "ABC"
},
{
"key": "cell-1",
"id": "ID-1",
"headerName": "RegID",
"CustomerID": "P-01"
},
{
"key": "cell-2",
"id": "ID-2",
"headerName": "Detail",
"Deatil": "Abc"
}
]
},
{
"key": "row-1",
"cells": [{
"key": "cell-1",
"id": "ID-1",
"headerName": "Name",
"CustomerName": "CDE"
},
{
"key": "cell-2",
"id": "ID-2",
"headerName": "RegID",
"CustomerID": "P-02"
},
{
"key": "cell-3",
"id": "ID-3",
"headerName": "Detail",
"Deatil": "CDE"
}
]
}
];
mockData.map((values, index) => {
console.log("VALUES", values);
return values.cells.map(({
headerName,
...rest
}) => {
console.log("JSON",rest);
console.log("Key:", rest.key);
console.log("ID:", rest.id);
console.log("CustomerName:", rest.CustomerName ? rest.CustomerName : 'NA' );
});
})
I have an array like this
[
{
"id": 1,
"name": "Personal Information",
"TabFields": [
{
"name": "First Name",
"field": {
"code": "personFirstName"
}
},
{
"name": "Gender",
"field": {
"code": "personGenderD"
}
},
{
"name": "Last Name",
"field": {
"code": "personLastName"
}
},
{
"name": "Mobile Number",
"field": {
"code": "mobileNumber"
}
},
{
"name": "Email Address",
"field": {
"code": "emailAddress"
}
}
]
}
]
What I need is to group the objects inside the TabFields to their respective TAB (PERSONAL_INFORMATION, CONTACT_DETAILS) by code value inside the field object
The object
"name": "First Name",
"field": {
"code": "personFirstName"
}
"name": "Gender",
"field": {
"code": "personGenderD"
}
"name": "Last Name",
"field": {
"code": "personLastName"
}
is belong to PERSONAL_INFORMATION and the object
"name": "Mobile Number",
"field": {
"code": "mobileNumber"
}
"name": "Email Address",
"field": {
"code": "emailAddress"
}
is belong to CONTACT_DETAILS. So the output would be
[
{
"id": 1,
"name": "Personal Information",
"TabFields": [
{
"label": "PERSONAL_INFORMATION",
"code": "PERSONAL_INFORMATION",
"fields": [
{
"name": "First Name",
"field": {
"code": "personFirstName"
}
},
{
"name": "Gender",
"field": {
"code": "personGenderD"
}
},
{
"name": "Last Name",
"field": {
"code": "personLastName"
}
}
]
},
{
"label": "CONTACT_DETAILS",
"code": "PERSONAL_INFORMATION",
"fields": [
{
"name": "Mobile Number",
"field": {
"code": "mobileNumber"
}
},
{
"name": "Email Address",
"field": {
"code": "emailAddress"
}
}
]
}
]
}
]
How to do it in javascript?
You can also do this with map:
var arr=[ { "id": 1, "name": "Personal Information", "TabFields": [ { "name": "First Name", "field": { "code": "personFirstName" } }, { "name": "Gender", "field": { "code": "personGenderD" } }, { "name": "Last Name", "field": { "code": "personLastName" } }, { "name": "Mobile Number", "field": { "code": "mobileNumber" } }, { "name": "Email Address", "field": { "code": "emailAddress" } } ] }];
personalContact = ["Mobile Number", "Email Address"];
result = arr.map(val=>{
personalInfo = { label:'personal', code:val.name, fields:val.TabFields.filter(k=>!personalContact.includes(k.name))};
contactInfo = { label:'contact', code:val.name, fields:val.TabFields.filter(k=>personalContact.includes(k.name))};
val.TabFields = [personalInfo, contactInfo];
return val;
});
console.log(result);
Idea would be to have an array which should distinguish between the contact details and personal details using which you can apply filter to get the data.
You can express transformations simply with a library I created, rubico.
const { pipe, fork, assign, get, map, filter } = require('rubico')
const PERSONAL_INFORMATION_FIELDS = new Set(['First Name', 'Gender', 'Last Name'])
const CONTACT_DETAILS_FIELDS = new Set(['Mobile Number', 'Email Address'])
// [datum] => [datum_with_grouped_TabFields]
const groupTabFields = assign({ // reassign TabFields to new grouped TabFields
TabFields: fork([
fork({
label: () => 'PERSONAL_INFORMATION',
code: () => 'PERSONAL_INFORMATION',
fields: pipe([
get('TabFields'), // datum => datum.TabFields
filter(pipe([ // FILTER: for each TabField of TabFields
get('name'), // TabField => TabField.name
field => PERSONAL_INFORMATION_FIELDS.has(field), // check if PERSONAL_INFORMATION_FIELDS has name
])),
]),
}),
fork({ // same as above but with contact details
label: () => 'CONTACT_DETAILS',
code: () => 'CONTACT_DETAILS',
fields: pipe([
get('TabFields'),
filter(pipe([
get('name'),
field => CONTACT_DETAILS_FIELDS.has(field)
])),
]),
}),
]),
})
x = map(groupTabFields)(data)
console.log(JSON.stringify(x, null, 2)) // output is what you wanted
I've added some comments, but for a deeper understanding of the library and code I've given you, I recommend reading the intuition and then reading the docs
I am using React/Typescript in my application but need help with basic JavaScript. I am trying to group the data coming from an api call (in this example i'll use mock data) without modifying the actual JSON. I need to group the data based on the 'deviceType' value. So if there are 4 objects, if two are ipad and two are iphone, I need to group those in order. Right now, the mock data is showing Ipad air, then Iphone 6plus, then Ipad air, and then Iphone 6plus again. I need to group these so the new object has the two ipadAir objects first and then the iphone 6plus object coming after. I believe this can be done by making a copy of the old object using spread operator and then modifying it before returning. Here is the data object:
{
"data": {
"DirectvNowDeviceNotifications": [
{
"AccountNumber": "180802190357553",
"AlertDescription": [
{
"AlertType": "BUFFERINGERRORS",
"AlertCode": "CRITICAL_ISFATAL",
"AlertInfo": "ACCOUNT_ALERT",
"SkipDismissal": false,
"DISMISSAL_EXPIRY_DATE": "",
"Content": {
"issueTitle": "Buffering Error Detected",
"issueDescription": "Buffering Error Detected"
},
"AlertAdditionalInfo": [
{
"Name": "reasonCodes",
"Value": "CRITICAL_ISFATAL"
},
{
"Name": "make",
"Value": "APPLE"
},
{
"Name": "deviceType",
"Value": "IPAD AIR"
},
{
"Name": "deviceID",
"Value": "F920BE29-1321-498A-B5D7-7FA84396DE16"
},
{
"Name": "osName",
"Value": "IOS"
},
{
"Name": "ISP",
"Value": "TIME WARNER CABLE INTERNET LLC"
},
{
"Name": "Mobile Carrier",
"Value": "AT&T"
},
{
"Name":"workflowName",
"Value":"CCE_ATTTV_Wifi_Setup"
}
],
"AdditionalContent": {
"longDescription": "You received this error message because the system has captured buffering errors on your device while streaming."
}
},
{
"AlertType": "BUFFERINGERRORS",
"AlertCode": "CRITICAL_FATALV",
"AlertInfo": "ACCOUNT_ALERT",
"SkipDismissal": false,
"DISMISSAL_EXPIRY_DATE": "",
"Content": {
"issueTitle": "Buffering Error Detected",
"issueDescription": "Buffering Error Detected"
},
"AlertAdditionalInfo": [
{
"Name": "reasonCodes",
"Value": "CRITICAL_FATALVIDEOERROR_CT"
},
{
"Name": "make",
"Value": "APPLE"
},
{
"Name": "deviceType",
"Value": "IPHONE 6 PLUS"
},
{
"Name": "deviceID",
"Value": "F920BE29-1321-498A-B5D7-7FA84396DE16"
},
{
"Name": "osName",
"Value": "IOS"
},
{
"Name": "ISP",
"Value": "TIME WARNER CABLE INTERNET LLC"
},
{
"Name": "Mobile Carrier",
"Value": "AT&T"
},
{
"Name":"workflowName",
"Value":"CCE_DTVN_PLAYER_ERRORS"
},
{
"Name":"workflowName",
"Value":"CCE_DTVN_PLAYER_ERRORS"
}
],
"AdditionalContent": {
"longDescription": "You received this error message because the system has captured buffering errors on your device while streaming"
}
},
{
"AlertType": "OSUNSUPPORTED",
"AlertCode": "N_NOT_SUPPORTED",
"AlertInfo": "ACCOUNT_ALERT",
"SkipDismissal": false,
"DISMISSAL_EXPIRY_DATE": "",
"Content": {
"issueTitle": "The device you are trying to use with DIRECTV NOW is not supported.",
"issueDescription": "The device you are trying to use with DIRECTV NOW is not supported."
},
"AlertAdditionalInfo": [
{
"Name": "reasonCodes",
"Value": "VSTB_UNSUPPORTED_DEVICE"
},
{
"Name": "make",
"Value": "APPLE"
},
{
"Name": "deviceType",
"Value": "IPAD AIR"
},
{
"Name": "deviceID",
"Value": "F920BE29-1321-498A-B5D7-7FA84396DE16"
},
{
"Name": "osName",
"Value": "IOS"
},
{
"Name": "ISP",
"Value": "TIME WARNER CABLE INTERNET LLC"
},
{
"Name": "Mobile Carrier",
"Value": "AT&T"
},
{
"Name":"workflowName",
"Value":"CCE_DTVN_PLAYER_ERRORS"
}
],
"AdditionalContent": {
"longDescription": "<a target='_blank' href='https://www.att.com/esupport/article.html#!/directv-now/KM1200941'>Here</a> is a list of supported devices."
}
},
{
"AlertType": "NA",
"AlertCode": "NA",
"AlertInfo": "NA",
"SkipDismissal": false,
"DISMISSAL_EXPIRY_DATE": "",
"Content": {
"issueTitle": "tell me more title",
"issueDescription": "tell me more description"
},
"AlertAdditionalInfo": [
{
"Name": "reasonCodes",
"Value": "NA"
},
{
"Name": "make",
"Value": "APPLE"
},
{
"Name": "deviceType",
"Value": "IPHONE 6 PLUS"
},
{
"Name": "deviceID",
"Value": "FB2468CF-BF73-4DBC-9600-C61553BB759F"
},
{
"Name": "osName",
"Value": "IOS"
},
{
"Name": "ISP",
"Value": "TIME WARNER CABLE INTERNET LLC"
},
{
"Name": "Mobile Carrier",
"Value": "AT&T"
}
],
"AdditionalContent": {
"longDescription": "tell me more long long long description"
}
}
]
}
]
},
"content": {
"code": 200,
"message": "OK"
}
}
Need objects to be grouped based on device type and return a new object with the proper grouping. Please if anyone can help I would greatly appreciate it, I have been struggling with this. Thank you
You could go through the keys of your object, in the following example I assume that you define this as a javascript object, the result will be two objects each with a key corresponding to the type of device
const newGroup = [];
const data = object["data"]["DirectvNowDeviceNotifications"];
(data).forEach((map, index) => {
Object(map['AlertDescription']).forEach((devices) => {
if(typeof devices['AlertAdditionalInfo'] !== 'undefined'){
const deviceType = devices['AlertAdditionalInfo'].find((type) => type.Name ==='deviceType');
if(typeof deviceType.Value !== 'undefined'){
if(typeof newGroup[deviceType.Value] === 'undefined'){
newGroup[deviceType.Value] = [];
}
newGroup[deviceType.Value].push(devices);
}
}
})
});
example working
this code is just an example you should optimize, the idea is to give you an idea of solution
I have an id and i to filter a multidimensional array with these. My code is:
service.fakedata.map(f=>{
f.results.map(r=>{
r = r.filter(m=> m.rId !== id)
})
})
and my array is :
"services": [
{
"id": "1839f72e-fa73-47de-b119-49fb971a5730",
"name": "In I/O Route",
"url": "http://wwww.in.io/[param1]/[param2]",
"inputParams": [
{
"id": "e74a6229-4c08-43a1-961f-abeb887fa90e",
"name": "in1",
"datatype": "string"
},
{
"id": "e74a6229-4c08-43a1-961f-abeb887fa90o",
"name": "in2",
"datatype": "string"
}
],
"isArrayResult": false,
"results": [
{
"id": "ef7c98db-9f12-45a8-b3fb-7d09a82abe3d",
"name": "out1",
"datatype": "string",
"fakedatatype": [
"address",
"city"
]
},
{
"id": "9b178ded-af27-43df-920f-daab5ad439b9",
"name": "out2",
"datatype": "string",
"fakedatatype": [
"internet",
"url"
]
}
],
"routeParameters": [
"param1",
"param2"
],
"fakedata": [
{
"id": "b0376694-9612-43d2-93ed-c74264df962e",
"url": "http://wwww.in.io/wood/good",
"params": [
{
"key": "param1",
"value": "wood"
},
{
"key": "param2",
"value": "good"
}
],
"inputParams": [
{
"iId":"e74a6229-4c08-43a1-961f-abeb887fa90e",
"key": "in1",
"value": "m"
},
{
"iId":"e74a6229-4c08-43a1-961f-abeb887fa90o",
"key": "in2",
"value": "z"
}
],
"results": [
{
"rId": "ef7c98db-9f12-45a8-b3fb-7d09a82abe3d",
"key": "out1",
"value": "result1",
"fakedatatype": [
"address",
"city"
]
},
{
"rId": "9b178ded-af27-43df-920f-daab5ad439b9",
"key": "out2",
"value": "result2",
"fakedatatype": [
"internet",
"url"
]
}
]
}
]
}
]
In this case filter is working (when I check with console.log) but it doesn't change fakedata array.
What was wrong with my code?
From https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/map
The map() method creates a new array with the results of calling a provided function on every element in the calling array.
base on #H77 suggestion i change my code and now my code is look like this and everything work well
const s = service.fakedata.map(f=>{
f.results = f.results.map(r=>{
return r.filter(m=> m.rId !== id)
})
})