Push a new Object to an object nested Array in React - javascript

Am trying to add a new object into my Redux initial States that was dispatched and I cant seem to make it works because am new to it. this is my initial State value
const initialState = {
invoices: data,
filterInvoice: data,
toggleId: "",
singleInvoice: [],
};
the data in front of the invoices is a local Json data am using to populate the states. The Data is an Array of objects. see the data value below
[
{
"id": "RT3080",
"createdAt": "2021-08-18",
"paymentDue": "2021-08-19",
"description": "Re-branding",
"paymentTerms": 1,
"clientName": "Jensen Huang",
"clientEmail": "jensenh#mail.com",
"status": "paid",
"senderAddress": {
"street": "19 Union Terrace",
"city": "London",
"postCode": "E1 3EZ",
"country": "United Kingdom"
},
"clientAddress": {
"street": "106 Kendell Street",
"city": "Sharrington",
"postCode": "NR24 5WQ",
"country": "United Kingdom"
},
"items": [
{
"name": "Brand Guidelines",
"quantity": 1,
"price": 1800.9,
"total": 1800.9
}
],
"total": 1800.9
},
{
"id": "XM9141",
"createdAt": "2021-08-21",
"paymentDue": "2021-09-20",
"description": "Graphic Design",
"paymentTerms": 30,
"clientName": "Alex Grim",
"clientEmail": "alexgrim#mail.com",
"status": "pending",
"senderAddress": {
"street": "19 Union Terrace",
"city": "London",
"postCode": "E1 3EZ",
"country": "United Kingdom"
},
"clientAddress": {
"street": "84 Church Way",
"city": "Bradford",
"postCode": "BD1 9PB",
"country": "United Kingdom"
},
"items": [
{
"name": "Banner Design",
"quantity": 1,
"price": 156.0,
"total": 156.0
},
{
"name": "Email Design",
"quantity": 2,
"price": 200.0,
"total": 400.0
}
],
"total": 556.0
},
]
going on, an object of the same data format would be dispatched into my reducer. so my problem is I dont get how I will add the object to the invoices initialState. My reducer
if (action.type === ActionTypes.DynamicInput) {
let tempInvoice;
//calculate totalValues
const totalAmount = action.payload.items.reduce((acc, curr) => {
const { itemTotal } = curr;
acc += parseFloat(itemTotal);
return acc;
}, 0);
if (action.payload.createdAt) {
const newDate = new Date(action.payload.createdAt).toLocaleDateString();
const paymentDue = addDays(
newDate,
action.payload.paymentTerms
).toLocaleDateString();
if (action.isDraft === true) {
tempInvoice = {
...action.payload,
createdAt: newDate,
paymentDue: paymentDue,
status: "draft",
total: totalAmount,
};
} else {
tempInvoice = {
...action.payload,
createdAt: newDate,
paymentDue: paymentDue,
status: "pending",
total: totalAmount,
};
}
}
// then initalizie the currentStates to add new action.payload objects coming from new invoice
return {
...state,
invoices: { ...state.invoices, tempInvoice },
};
}
I tried using the spread operator to get existing values and assign but it din work
return {
...state,
invoices: [ ...state.invoices, tempInvoice ],
};

after so much debugging and why invoice array is changing, I noticed that TempInvoice is returning empty Objects. I.e It not been populated, Its null. so I refactored my code to look like this
if (action.payload.createdAt) {
const newDate = new Date(action.payload.createdAt).toLocaleDateString();
const paymentDue = addDays(
newDate,
action.payload.paymentTerms
).toLocaleDateString();
if (action.isDraft === false) {
tempInvoice = {
...action.payload,
createdAt: newDate,
paymentDue: paymentDue,
id: getRandomAlphabet(),
status: "draft",
total: totalAmount,
};
} else {
tempInvoice = {
...action.payload,
createdAt: newDate,
paymentDue: paymentDue,
id: getRandomAlphabet(),
status: "pending",
total: totalAmount,
};
}
} else {
if (action.isDraft === false) {
tempInvoice = {
...action.payload,
status: "draft",
id: getRandomAlphabet(),
total: totalAmount,
};
} else {
tempInvoice = {
...action.payload,
status: "pending",
id: getRandomAlphabet(),
total: totalAmount,
};
}
}
return {
...state,
invoices: [...state.invoices, tempInvoice],
}
};

Related

Javascript group data and append additional data

I am looking to solve 2 problems here
Group the orders to create an items array based on based on orderNo
Include the tracking-information from the tracking array in tracking.json into the orders array.
So far I have only managed to get started with the grouping.
//orders.json
const orders = [
{
"orderNo": "1",
"tracking_number": "001",
"courier": "FedEx",
"street": "1745 T Street Southeast",
"zip_code": 20020,
"city": "Louisville",
"destination_country": "USA",
"email": "test#test.com",
"articleNo": "A",
"articleImageUrl": "watch.jpg",
"quantity": 1,
"product_name": "Watch"
},
{
"orderNo": "1",
"tracking_number": "001",
"courier": "FedEx",
"street": "1745 T Street Southeast",
"zip_code": 20020,
"city": "Louisville",
"destination_country": "USA",
"email": "test#test.com",
"articleNo": "B",
"articleImageUrl": "belt.jpg",
"quantity": 2,
"product_name": "Belt"
},
{
"orderNo": "2",
"tracking_number": "002",
"courier": "FedEx",
"street": "637 Britannia Drive",
"zip_code": 94591,
"city": "Vallejo",
"destination_country": "USA",
"email": "test#test.com",
"articleNo": "",
"articleImageUrl": "",
"quantity": "",
"product_name": ""
}
];
//tracking.json
const tracking = [{
"tracking_number": "001",
"location": "",
"timestamp": "2018-04-01T00:00:00.000Z",
"status": "OrderProcessed",
"status_text": "Order processed",
"status_details": "The order has been processed."
},
{
"tracking_number": "002",
"location": "",
"timestamp": "2018-04-06T05:58:00.000Z",
"status": "OrderProcessed",
"status_text": "Order processed",
"status_details": "The order has been processed."
}
]
//expected output data.json
const data = [
{
"orderNo":"1",
"tracking_number":"001",
"courier":"FedEx",
"street":"1745 T Street Southeast",
"zip_code":"20020",
"city":"Louisville",
"destination_country":"USA",
"email":"test#test.com",
"articleNo":"A",
"articleImageUrl":"watch.jpg",
"quantity":"1",
"product_name":"Watch",
"items":[
{
"articleNo":"A",
"articleImageUrl":"watch.jpg",
"quantity":"1",
"product_name":"Watch"
},
{
"articleNo":"B",
"articleImageUrl":"belt.jpg",
"quantity":"2",
"product_name":"Belt"
}
],
"tracking":{
"tracking_number":"001",
"location":null,
"timestamp":"2018-04-01T00:00:00.000Z",
"status":"Scheduled",
"status_text":"Order processed",
"status_details":"The order has been processed."
}
},
{
"orderNo": "2",
"tracking_number": "002",
"courier": "FedEx",
"street": "637 Britannia Drive",
"zip_code": 94591,
"city": "Vallejo",
"destination_country": "USA",
"email": "test#test.com",
"articleNo": "",
"articleImageUrl": "",
"quantity": "",
"product_name": "",
"items":[
],
"tracking":{
"tracking_number": "002",
"location": "",
"timestamp": "2018-04-06T05:58:00.000Z",
"status": "OrderProcessed",
"status_text": "Order processed",
"status_details": "The order has been processed."
}
}
]
const groupBy = key => array =>
array.reduce(
(objectsByKeyValue, obj) => ({
...objectsByKeyValue,
[obj[key]]: (objectsByKeyValue[obj[key]] || []).concat(obj)
}),
{}
);
const groupByOrders = groupBy('orderNo');
I am looking to get the data in the format shown in data.json
This is the current code along with the data
Code
Below is one possible way to achieve the target.
Code Snippet
const groupAndInclude = (base, delta) => {
const result = []; // result array
base.forEach( // iterate over the "orders"
({ // de-structure to directly access specific props
orderNo, tracking_number, articleNo,
articleImageUrl, quantity, product_name,
...rest // remaining props not directly-accessed
}) => {
const foundOrder = result.find( // find if "order" already in "result"
ob => ob.orderNo === orderNo
);
if (foundOrder) { // found a match, simply push "article"-info
if (articleNo.length > 0) { // push to "items" only if not "empty"
foundOrder.items.push({ // to the "items" array
articleNo, articleImageUrl, quantity, product_name
})
}
} else { // match not-found. Add new entry to "result"
const resObj = { // construct the result-object "resObj"
...rest, orderNo // using all relevant "order" props
};
if (articleNo.length > 0) { // do not add "empty" item
resObj.items = [{ // add "items" as an array
articleNo, articleImageUrl, quantity, product_name
}];
} else {
resObj.items = [];
};
const foundTracker = delta.find( // look for "tracking_number"
ob => ob.tracking_number === tracking_number
);
// if "tracking_number" found, add to result-object
if (foundTracker) resObj.tracking = {...foundTracker};
result.push(resObj); // push the result-object to the "result" array
}
}
);
return result; // explicitly return the "result" array
};
const orders = [{
"orderNo": "1",
"tracking_number": "001",
"courier": "FedEx",
"street": "1745 T Street Southeast",
"zip_code": 20020,
"city": "Louisville",
"destination_country": "USA",
"email": "test#test.com",
"articleNo": "A",
"articleImageUrl": "watch.jpg",
"quantity": 1,
"product_name": "Watch"
},
{
"orderNo": "1",
"tracking_number": "001",
"courier": "FedEx",
"street": "1745 T Street Southeast",
"zip_code": 20020,
"city": "Louisville",
"destination_country": "USA",
"email": "test#test.com",
"articleNo": "B",
"articleImageUrl": "belt.jpg",
"quantity": 2,
"product_name": "Belt"
},
{
"orderNo": "2",
"tracking_number": "002",
"courier": "FedEx",
"street": "637 Britannia Drive",
"zip_code": 94591,
"city": "Vallejo",
"destination_country": "USA",
"email": "test#test.com",
"articleNo": "",
"articleImageUrl": "",
"quantity": "",
"product_name": ""
}
];
//tracking.json
const tracking = [{
"tracking_number": "001",
"location": "",
"timestamp": "2018-04-01T00:00:00.000Z",
"status": "OrderProcessed",
"status_text": "Order processed",
"status_details": "The order has been processed."
},
{
"tracking_number": "002",
"location": "",
"timestamp": "2018-04-06T05:58:00.000Z",
"status": "OrderProcessed",
"status_text": "Order processed",
"status_details": "The order has been processed."
}
];
console.log(groupAndInclude(orders, tracking));
.as-console-wrapper { max-height: 100% !important; top: 0 }
Explanation
Inline comments added in the snippet above.
You could take two objects as reference to same orderNo and tracking_number.
For adding an oder to the result set remove item properties and take a new object of this properties.
const
orders = [{ orderNo: "1", tracking_number: "001", courier: "FedEx", street: "1745 T Street Southeast", zip_code: 20020, city: "Louisville", destination_country: "USA", email: "test#test.com", articleNo: "A", articleImageUrl: "watch.jpg", quantity: 1, product_name: "Watch" }, { orderNo: "1", tracking_number: "001", courier: "FedEx", street: "1745 T Street Southeast", zip_code: 20020, city: "Louisville", destination_country: "USA", email: "test#test.com", articleNo: "B", articleImageUrl: "belt.jpg", quantity: 2, product_name: "Belt" }, { orderNo: "2", tracking_number: "002", courier: "FedEx", street: "637 Britannia Drive", zip_code: 94591, city: "Vallejo", destination_country: "USA", email: "test#test.com", articleNo: "", articleImageUrl: "", quantity: "", product_name: "" }],
tracking = [{ tracking_number: "001", location: "", timestamp: "2018-04-01T00:00:00.000Z", status: "OrderProcessed", status_text: "Order processed", status_details: "The order has been processed." }, { tracking_number: "002", location: "", timestamp: "2018-04-06T05:58:00.000Z", status: "OrderProcessed", status_text: "Order processed", status_details: "The order has been processed." }],
keys = ["articleNo", "articleImageUrl", "quantity", "product_name"],
items = {},
trackings = {},
result = [];
for (let order of orders) {
const item = {};
for (const key of keys) {
let value;
({ [key]: value, ...order } = order);
item[key] = value;
}
if (!items[order.orderNo]) result.push(items[order.orderNo] = { ...order, items: [] });
if (Object.values(item).some(Boolean)) items[order.orderNo].items.push(item);
trackings[order.tracking_number] = items[order.orderNo];
}
for (const transfer of tracking) trackings[transfer.tracking_number].tracking = transfer;
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Group and count the nested json response - Angular

Im trying to bind value in Angular Material table, before that i need to process the GET response v
trying to achieve like below(just for understanding)
my faulty code
let filterByLocation = data.reduce((r, { group: location.country, ...object }) => {
var finalArry = r.find(o => o.location === location);
if (!finalArry) r.push(temp = { location, locationObj: [] });
finalArry.locationObj.push(object);
return r;
}, []);
console.log(filterByLocation);
thanks to #Nishant Dixit for his working snippet
const finalResponse = data.response.reduce((r, {
location: {
country: group
},
...object
}) => {
r[group] = r[group] || {
location: group,
locationObj: []
};
r[group].locationObj.push(object);
return r;
}, {});
console.log(finalResponse)
const data = {
"totalRec": 5,
"response": [
{
"employee": {
"uid": 1,
"empName": "Jade"
},
"location": {
"country": "UK",
"subLocation": "London"
},
"department": {
"sector": "IT"
}
},
{
"employee": {
"uid": 2,
"empName": "Mike"
},
"location": {
"country": "UK",
"subLocation": "Manchester"
},
"department": {
"sector": "IT"
}
},
{
"employee": {
"uid": 3,
"empName": "Liya"
},
"location": {
"country": "UK",
"subLocation": "Southampton"
},
"department": {
"sector": "HR"
}
},
{
"employee": {
"uid": 3,
"empName": "Brad"
},
"location": {
"country": "USA",
"subLocation": "Texas"
},
"department": {
"sector": "IT"
}
},
{
"employee": {
"uid": 3,
"empName": "Brad"
},
"location": {
"country": "USA",
"subLocation": "Texas"
},
"department": {
"sector": "NON-IT"
}
}
]
};
but the problem is i'm getting result like
UK : {
location : "UK"
....
}
in html, i don't want to explicitly mention UK with dot operation like below, instead row.location
<ng-container matColumnDef="facility">
<mat-header-cell *matHeaderCellDef mat-sort-header> Facility</mat-header-cell>
<mat-cell *matCellDef="let row"> {{row.UK.location}} </mat-cell>
</ng-container>
could someone tell me how to convert this output like
location: {
country : 'UK'
}
or any random name like
obj: {
location: 'UK'
//rest of values for grouping
}
fiddle
Thanks to every one
You can do something like this:
const countryMap = {};
data.response.forEach(item => {
countryMap[item.location.country] = [ ...( countryMap[item.location.country] || [] ), item];
});
Now, this is how the countryMap will look like:
Now, further to map it to the format you want, you can do this:
const mappedData = Object.entries(countryMap).map(entry => ({
location: entry[0],
response: entry[1]
}));
This will produce mappedData in this format:

Reduce flat array to 2-level nested json object array

I have the following flat array:
{ "State": "New York", "Name": "Jane", "Product": "Apple" },
{ "State": "New York", "Name": "Jill", "Product": "Banana"},
{ "State": "California", "Name": "Jill", "Product": "Apple" },
{ "State": "California", "Name": "Jill", "Product": "Banana"}
Is it possible to create a 2-level nested array (i.e., Name > nested State Array > nested Product Array)? It would look like as follows:
{
"Name": "Jill",
"States": [
{
"State": "California",
"Products": [
{
"Product": "Apple"
},
{
"Product": "Banana"
}
]
},
{
"State": "New York",
"Products": [
{
"Product": "Banana"
}
]
}
]
},
{
"Name": "Jane",
"States": [
{
"State": "New York",
"Products": [
{
"Product": "Apple"
}
]
}
]
}
I have been able to get one level nested (States). How would you nest the second level?
Here is a stackblitz: https://stackblitz.com/edit/angular-lu6zj2
this.grouped_data = this.data.reduce((data, item) => {
data[item.Name] = data[item.Name] || { Name: item.Name, States: []}
data[item.Name].States.push(item)
return data;
}, {})
let data = [
{ "State": "New York", "Name": "Jane", "Product": "Apple" },
{ "State": "New York", "Name": "Jill", "Product": "Banana"},
{ "State": "California", "Name": "Jill", "Product": "Apple" },
{ "State": "California", "Name": "Jill", "Product": "Banana"}
];
let grouped = data.reduce((p, n) => {
// Create the Lady
if (!p[n.Name]) p[n.Name] = { States: [] };
// Check if the state exists, if not create it, then push product into it
if (!p[n.Name].States.some(state => state.State === n.State)) {
p[n.Name].States.push({ State: n.State, Products: [n.Product] });
} else {
!p[n.Name].States.find(state => state.State === n.State).Products.push(n.Product);
}
return p;
}, {});
console.log(grouped);
After that you can also remove duplicated products if you want to. I'll let you deal with it !
EDIT I didn't respect your model, what a dumbass am I ... Here it is :
let data = [
{ "State": "New York", "Name": "Jane", "Product": "Apple" },
{ "State": "New York", "Name": "Jill", "Product": "Banana"},
{ "State": "California", "Name": "Jill", "Product": "Apple" },
{ "State": "California", "Name": "Jill", "Product": "Banana"}
];
let grouped = data.reduce((p, n) => {
// Create the Lady
if (!p.some(lady => lady.Name === n.Name)) p.push({ Name: n.Name, States: [] });
let lady = p.find(lady => lady.Name === n.Name);
// Check if the state exists, if not create it, then push product into it
if (!lady.States.some(state => state.State === n.State)) {
lady.States.push({ State: n.State, Products: [n.Product] });
} else {
lady.States.find(state => state.State === n.State).Products.push(n.Product);
}
return p;
}, []);
console.log(grouped);

Group data by first char in JSON response

I want to group JSON by First char of first name but the resultant object should have two attributes "Key" & "Data"
I tried using lodash which has given me partial expected result but not the complete.
Following are the details with data, expected result, current result and current code implemented using lodash.
Any help will be appreciated.
JSON:
UserData = [
{
"gender":"male",
"name":{
"title":"mr",
"first":"landon",
"last":"gonzalez",
},
"location":{
"street":"7927 bollinger rd",
"city":"madison",
"state":"washington",
"postcode":24642
},
"email":"landon.gonzalez#example.com",
"dob":"1972-04-26 11:40:09",
"registered":"2013-07-04 17:42:44",
"phone":"(038)-931-4026",
"cell":"(808)-824-5320",
"nat":"US"
},
{
"gender":"male",
"title":"mr",
"first_name":"jonathan",
"last_name":"petersen",
"location":{
"street":"2583 brorsonsvej",
"city":"brøndby strand",
"state":"hovedstaden",
"postcode":87814
},
"email":"jonathan.petersen#example.com",
"dob":"1948-05-06 21:48:27",
"registered":"2009-03-09 17:04:40",
"phone":"03441612",
"cell":"73824887",
"nat":"DK"
},
{
"gender":"male",
"name":{
"title":"mr",
"first":"roméo",
"last":"marchand",
},
"location":{
"street":"9471 rue bony",
"city":"créteil",
"state":"maine-et-loire",
"postcode":30698
},
"email":"roméo.marchand#example.com",
"dob":"1969-08-18 16:41:01",
"registered":"2015-04-21 19:26:04",
"phone":"04-43-18-74-25",
"cell":"06-83-89-77-72",
"nat":"FR"
}
]
Expected:
[
{ key: 'A', data: [{...}, {...}, {...}] },
{ key: 'B', data: [{...}, {...}, {...}] },
{ key: 'C', data: [{...}, {...}, {...}] },
]
Current:
[
{ 'A': [{...}, {...}, {...}] },
{ 'B': [{...}, {...}, {...}] },
{ 'C': [{...}, {...}, {...}] },
]
Current Code:
sectionListData(users){
let sectionedUsers = _.groupBy(users, function(user) {
return user.first_name.charAt(0).toUpperCase();
});
alert(JSON.stringify(sectionedUsers));
}
Use lodash.chain and after grouping, map the results to create objects of your choice:
let UserData = [{
"gender": "male",
"name": {
"title": "mr",
"first": "landon",
"last": "gonzalez",
},
"location": {
"street": "7927 bollinger rd",
"city": "madison",
"state": "washington",
"postcode": 24642
},
"email": "landon.gonzalez#example.com",
"dob": "1972-04-26 11:40:09",
"registered": "2013-07-04 17:42:44",
"phone": "(038)-931-4026",
"cell": "(808)-824-5320",
"nat": "US"
},
{
"gender": "male",
"title": "mr",
"first_name": "jonathan",
"last_name": "petersen",
"location": {
"street": "2583 brorsonsvej",
"city": "brøndby strand",
"state": "hovedstaden",
"postcode": 87814
},
"email": "jonathan.petersen#example.com",
"dob": "1948-05-06 21:48:27",
"registered": "2009-03-09 17:04:40",
"phone": "03441612",
"cell": "73824887",
"nat": "DK"
},
{
"gender": "male",
"name": {
"title": "mr",
"first": "roméo",
"last": "marchand",
},
"location": {
"street": "9471 rue bony",
"city": "créteil",
"state": "maine-et-loire",
"postcode": 30698
},
"email": "roméo.marchand#example.com",
"dob": "1969-08-18 16:41:01",
"registered": "2015-04-21 19:26:04",
"phone": "04-43-18-74-25",
"cell": "06-83-89-77-72",
"nat": "FR"
}
];
let sectionedUsers = _.chain(UserData)
.groupBy(function(user) {
let firstName = _.get(user, 'name.first') || user.first_name;
return firstName.charAt(0).toUpperCase();
})
.map((data, key) => ({
key,
data
}))
.value();
console.log(sectionedUsers);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.min.js"></script>
You could _.map the grouped result.
var userData = [{ gender: "male", name: { title: "mr", first: "landon", last: "gonzalez" }, location: { street: "7927 bollinger rd", city: "madison", state: "washington", postcode: 24642 }, email: "landon.gonzalez#example.com", dob: "1972-04-26 11:40:09", registered: "2013-07-04 17:42:44", phone: "(038)-931-4026", cell: "(808)-824-5320", nat: "US" }, { gender: "male", title: "mr", name: { first: "jonathan", last: "petersen" }, location: { street: "2583 brorsonsvej", city: "brøndby strand", state: "hovedstaden", postcode: 87814 }, email: "jonathan.petersen#example.com", dob: "1948-05-06 21:48:27", registered: "2009-03-09 17:04:40", phone: "03441612", cell: "73824887", nat: "DK" }, { gender: "male", name: { title: "mr", first: "roméo", last: "marchand" }, location: { street: "9471 rue bony", city: "créteil", state: "maine-et-loire", postcode: 30698 }, email: "roméo.marchand#example.com", dob: "1969-08-18 16:41:01", registered: "2015-04-21 19:26:04", phone: "04-43-18-74-25", cell: "06-83-89-77-72", nat: "FR" }];
let sectionedUsers = _(userData)
.groupBy(user => user.name.first[0].toUpperCase())
.map((data, key) => ({ key, data }))
.value();
console.log(sectionedUsers);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.15.0/lodash.min.js"></script>

Nested Array in JSON Objects Conversion

I'm struggling with converting the nested JSON array that I have.
{
"Id": "1234",
"Company": {
"element": [{
"Name": "htc",
"Contacts": {
"element": [{
"name": "john",
"phone": "1234"
}, {
"name": "peter",
"phone": "5678"
}]
},
"Address": {
"element": {
"country": "us",
"state": "cali"
}
}
}, {
"Name": "samsung",
"Contacts": {
"element": [{
"name": "luke",
"phone": "0011"
}, {
"name": "james",
"phone": "2233"
}]
},
"Address": {
"element": {
"country": "us",
"state": "texas"
}
}
}]
}
}
As you'll notice, there's this "element" in the arrays "Company", "Contacts" and "Address". But the output that I need to provide should not contain the "element" such as this code:
{
"Id": "1234",
"Company": [{
"Name": "htc",
"Contacts": [{
"name": "john",
"phone": "1234"
}, {
"name": "peter",
"phone": "5678"
}],
"Address": [{
"country": "us",
"state": "cali"
}]
}, {
"Name": "samsung",
"Contacts": [{
"name": "luke",
"phone": "0011"
}, {
"name": "james",
"phone": "2233"
}],
"Address": [{
"country": "us",
"state": "texas"
}]
}]
}
I have no clue how to do in JavaScript. Any ideas/tips are appreciate.
Thank you
You can try something like this:
var data={Id:"1234",Company:{element:[{Name:"htc",Contacts:{element:[{name:"john",phone:"1234"},{name:"peter",phone:"5678"}]},Address:{element:{country:"us",state:"cali"}}},{Name:"samsung",Contacts:{element:[{name:"luke",phone:"0011"},{name:"james",phone:"2233"}]},Address:{element:{country:"us",state:"texas"}}}]}};
var keysToClean = ["Address", "Contacts"]
// Copy object instead of reference
var result = Object.assign({}, data);
result.Company = result.Company.element;
result.Company.forEach(x => {
keysToClean.forEach(k => {
x[k] = Array.isArray(x[k]) ? x[k].element : [x[k].element]
})
})
console.log(result);
Note: I have use Object.create and Arrow functions. They are not supported by old browsers. You can refer to following link for alternative to deep copy an object:
What is the most efficient way to deep clone an object in JavaScript?
The solution using Array.prototype.forEach() function:
var companyData = { "Id": "1234", "Company": { "element": [{ "Name": "htc", "Contacts": { "element": [{ "name": "john", "phone": "1234" }, { "name": "peter", "phone": "5678" }] }, "Address": { "element": { "country": "us", "state": "cali" } } }, { "Name": "samsung", "Contacts": { "element": [{ "name": "luke", "phone": "0011" }, { "name": "james", "phone": "2233" }] }, "Address": { "element": { "country": "us", "state": "texas" } } }] }
};
companyData.Company = companyData.Company.element;
var omitElement = function(o){
if (!o['element']) return o;
return (Array.isArray(o.element))? o.element : [o.element];
}
companyData.Company.forEach(function (o) {
o.Contacts = omitElement(o.Contacts);
o.Address = omitElement(o.Address);
});
console.log(companyData);
Please see this Plunker This should help.. it will generate desired result you need but be aware this is just a way to do this, and only meant for information purpose. It's not production grade...
function ParseData(data)
{
var newObject={Id:0, Company:[]};
newObject["Id"]=data["Id"];
newObject["Company"]=CreateCompanyObject(data["Company"]["element"]);
console.log(JSON.stringify(newObject));
}
function CreateCompanyObject(data)
{
var companies=[];
for(var i=0;i<data.length;i++)
{
companies.push({
name:data[i].Name,
contacts:CreateContactObject(data[i].Contacts.element),
Address:CreateAddressObject(data[i].Address.element)});
};
return companies;
}
function CreateContactObject(data){
var contacts=[];
for(var i=0;i<data.length;i++)
contacts.push(data[i]);
return contacts;
}
function CreateAddressObject(data){
var address=[];
if(typeof(data)=="array"){
for(var i=0;i<data.length;i++)
address.push(data[i]);
}
else
address.push(data);
return address;
}
You could check for element and move the content a step ahead to its parent.
function deleteElement(object){
Object.keys(object).forEach(function (k) {
if (object[k] && typeof object[k] === 'object') {
if ('element' in object[k]) {
object[k] = Array.isArray(object[k].element) ?
object[k].element :
[object[k].element];
}
deleteElement(object[k]);
}
});
}
var data = { Id: "1234", Company: { element: [{ Name: "htc", Contacts: { element: [{ name: "john", phone: "1234" }, { name: "peter", phone: "5678" }] }, Address: { element: { country: "us", state: "cali" } } }, { Name: "samsung", Contacts: { element: [{ name: "luke", phone: "0011" }, { name: "james", phone: "2233" }] }, Address: { element: { country: "us", state: "texas" } } }] } };
deleteElement(data);
console.log(data);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Categories

Resources