nested json data minipulation for ngx datatable in angualr -6 / js - javascript

I am trying to create a ngx datatable that creates columns dynamically from nested arrays, which with some research is not possible - so to achieve my desired result, I must flatten my nested arrays with the key / values that i need from each nested object into my parent object.
I need to manipulate my data so that my end result is a flat array and contains a line item for each object in the nested array earnings with 'abbreviation' being the key and 'amount' being the value..
I.e
[
{
employee_uuid: 978f37df-7e07-4118-be93-d82507ce5c46,
employee_code: JB00024,
full_name: Thulisile Sandra,
last_name: Bhekiswayo
earnings:[{
abbreviation: "NT HRS"
amount: "45.00"
money: false
name: "Normal Time HRS"
time: true
unique: "7d783469-717e-408a-bc3c-93115cb632dd_true"
uuid: "7d783469-717e-408a-bc3c-93115cb632dd"
value: "45.00"
},
{
abbreviation: "OT HRS"
amount: "25.00"
money: false
name: "Normal Time HRS"
time: true
unique: "7d783469-717e-408a-bc3c-93115cb632dd_true"
uuid: "7d783469-717e-408a-bc3c-93115cb632dd"
value: "45.00"
}],
terminated false
}
...
]
I'd like to look like this:
[
{
employee_uuid: 978f37df-7e07-4118-be93-d82507ce5c46,
employee_code: JB00024,
full_name: Thulisile Sandra,
last_name: Bhekiswayo,
NT HRS: '45.00',
OT HRS, '25.00',
terminated:false
}
...
]
I am not sure how to go about this, I've tried reducing and map functions but no success.. I can add the nested arrays to the parent object with Object.assign but that takes the whole object, I need to create a new parameter from that object..
Any help would be hugely appreciated..

You can use es6 destructuring for this, simply expose whatever properties you need and then "recompose" then into the object shape you want.
For example:
return myEmployeeArray.map(employee => {
const {earn } = employee
earn.map(field => field.abbreviation)
myDesiredObject = { fieldA: employee.abbreviation....fieldE:field.abbreviation}
}
This would get you one of your nested fields

Related

Javascript: Spread array of an object in an object and change properties inside it only

I have a scenario where I want to change properties of object in an array. That array is wrapped inside another object.
const defaultData = {
title: "Title",
subtitle: "Subtitle",
books: [
{
bookId: "1",
imageSrc:
"any.png",
name: "Issue",
userOwnsData: true,
panelsCollected: 0,
totalPanels: 123,
link: "https://google.com",
},
],
bgColor: "black",
};
When I spread it like this:
{...defaultData, ...defaultData.books[0], panelsCollected:123} //previously it was 0
then it adds another extra object to parent object but not update it inside first index of books array
How can I just change that panelsCollected property without disturbing whole structure as we are using typescript.
Edit:
We can change it directly accessing the property too as we know index but that comes with a side effect of manipulating original dataset also which we should avoid and only copy needs to be updated.
Thanks
When spreading an object with nested properties with the intention of updating specific properties, think of it in two steps:
Spread the original object to copy it (...)
Redefine the new property values after the spread object
In your example we are doing the following:
Duplicating defaultData and assigning an updated books property (to be defined in the next step)
Duplicating the first book (defaultData.books[0]) and assigning an updated panelsCollected property to it. Then overwriting the existing books property with this updated array item
The result is as follows:
const defaultData = {
title: "Title",
subtitle: "Subtitle",
books: [
{
bookId: "1",
imageSrc:
"any.png",
name: "Issue",
userOwnsData: true,
panelsCollected: 0,
totalPanels: 123,
link: "https://google.com",
},
],
bgColor: "black",
};
const newBook = {
...defaultData,
books: [
{
...defaultData.books[0],
panelsCollected: 123
}
]
}
console.log(newBook)
/*
{
title: "Title",
subtitle: "Subtitle",
books: [
{
bookId: "1",
imageSrc:
"any.png",
name: "Issue",
userOwnsData: true,
panelsCollected: 123,
totalPanels: 123,
link: "https://google.com",
},
],
bgColor: "black",
};
*/
If for example the books property was 1000 items long, you would instead use have to find the specific book in your array using an array method (e.g. find / findIndex) and update it, e.g.
const bookToUpdateIndex = defaultData.books.findIndex(book => book.bookId === '1')
const updatedBooks = [...defaultData.books]
updatedBooks[bookToUpdateIndex] = {
...updatedBooks[bookToUpdateIndex],
panelsCollected: 123
}
const newBook = {
...defaultData,
books: updatedBooks
}
I think it is creating another parent object because you are using the spread twice. I tried to do 2 console logs. Please let me know if this is the result you are looking for.
console.log({...defaultData['books'][0]['panelsCollected'] = 10})
console.log(defaultData);
Instead of using find and the spread syntax an alternative approach (but not necessarily the most performant) might be to copy the object by stringifying it, and then reparsing that string. And then you can just update the object at the index you need.
const defaultData={title:"Title",subtitle:"Subtitle",books:[{bookId:"1",imageSrc:"any.png",name:"Issue",userOwnsData:!0,panelsCollected:0,totalPanels:123,link:"https://google.com"}],bgColor:"black"};
const copy = JSON.parse(JSON.stringify(defaultData));
copy.books[0].panelsCollected = 123;
console.log(defaultData);
console.log(copy);

Looping through an array of objects and mapping each object them to a single template object

I have a two sets of data, one formatted like so:
title: "Test Json",
showProgressBar: "top",
showQuestionNumbers: "off",
pages: [
{
questions: [
{
type: "",
name: "",
title: "",
hasOther: true,
isRequired: true,
colCount: 4,
choices: []
}
]
}
]
};
The other formatted like so:
{Answers: "“18-24”, “25-50”, “50+”",
​
Question: "How old are you?",
​
QuestionNumber: "1",
​
isRequired: "TRUE",
​
type: "radiogroup"}
This second set of data is multiple of these objects, which I am looping through using a forEach loop like so:
data.forEach((data, i)=>{
console.log(data)
// returns above object x3
})
What I want to do is use the first object and map values to the questions array using the values of the second object, so for example questions[0].type would be mapped to data.type.
I have managed to figure out mapping one object to the template doing this:
data.forEach((data, i)=>{
console.log(data)
questions[0].type = data.type
questions[0].name = data.Question
questions[0].title = data.Question
questions[0].choices = [data.Answers]
})
But this only maps the first object in the data array of objects, and I want to basically create a new template object based on the number of objects in the data array and create as many 'filled questions templates' as there is objects in data array
Any pointers and help would be lovely <3
Try this
data.forEach((data, i)=>{
console.log(data)
questions.push([{
type: data.type
name: data.Question
title: data.Question
choices: [data.Answers]
}])
})
Updated this answer with your additional question

Having trouble extracting value from Javascript object's multidimensonal array [duplicate]

This question already has answers here:
How can I access and process nested objects, arrays, or JSON?
(31 answers)
Closed 6 years ago.
I'm attempting to use Javascript objects to work with some data. Here is the object itself (parsed from JSON) which is defined as accounts:
{
startIndex: 0,
pageSize: 20,
pageCount: 1,
totalCount: 1,
items: [
{
id: 123456,
emailAddress: 'test#test.com',
userName: 'test#test.com',
firstName: 'John',
lastName: 'Hancock',
customerSet: 'default',
commerceSummary: [
Object
],
contacts: [
Object
],
userId: '92834439c29389fj292',
notes: [
],
attributes: [
Object
],
segments: [
Object
],
taxExempt: false,
externalId: '2100010368',
isAnonymous: false,
auditInfo: [
Object
],
isLocked: false,
isActive: true,
hasExternalPassword: false,
customerSinceDate: 2016-06-23T18: 26: 46.000Z
}
]
}
While I can retrieve accounts.items without issue, I'm having some trouble retrieving individual values such as id or emailAddress from the item itself. Doing accounts.items[id] or accounts.items[emailAddress] does not work but I believe it's due to the fact that items can be more than 1 so I should be specifying the "first result" for items from that list. If that is the case, how do I retrieve the emailAddress or id for the first items array? The desired result from the above JSON object should be "123456" if id and "test#test.com" if email. Thanks in advance.
Your items is an array. You have to fetch data from it by indexes (like items[0]). If you are looking for an item, with their properties, use Array.find method.
The find method executes the callback function once for each element
present in the array until it finds one where callback returns a true
value. If such an element is found, find immediately returns the value
of that element. Otherwise, find returns undefined. callback is
invoked only for indexes of the array which have assigned values; it
is not invoked for indexes which have been deleted or which have never
been assigned values.
var accounts = {
startIndex: 0,
pageSize: 20,
pageCount: 1,
totalCount: 1,
items: [
{
id: 123456,
emailAddress: 'test#test.com',
userName: 'test#test.com',
firstName: 'John',
lastName: 'Hancock',
customerSet: 'default'
}
]
};
var sampleAccount = accounts.items.find(function (item) {
return item.id == 123456;
});
if (sampleAccount) {
console.log(sampleAccount.emailAddress);
}
You are right, first you need to reference the first element of the array. Then you can query its properties.
For example, to get the ID and email address of the first item you would write
accounts.items[0].id
accounts.items[0].emailAddress
Arrays elements start at index 0 in JavaScript, so the first element of the array has index 0, the second 1, and so on.
Items is an array and emailAddress is a Key, then you can get the value using:
accounts.items[0].emailAddress

Best way to design a model for the store for a array?

I need to import the following into a store but I am confused about the correct model or models I need to create.
here is an example of the JSON that is returned from my server. Basically its an array with 2 items, with an array in each. The field names are different in each.
I suspect I need to have more than one model and have a relationship but I am unsure where to start. Any ideas? Thanks
[
firstItems: [
{
name : "ProductA",
key: "XYXZ",
closed: true
},
{
name : "ProductB",
key: "AAA",
closed: false
}
],
secondItems : [
{
desc : "test2",
misc: "3333",
},
{
desc : "test1",
misc: "123"
}
]
]
What you have is not JSON, your opening and ending [] can become JSON by changing them to {} and then using the following models
Then you can model it as
// Abbreviated definitions of Models, it has changed starting at Ext 5
Ext.define('FirstItem', fields: ['name', 'key', 'closed'])
Ext.define('SecondItem', fields: ['desc', 'misc'])
Ext.define('TopLevel', {
hasMany: [
{model: 'FirstItem', name: 'firstItems'},
{model: 'SecondItem', name: 'secondItems'}
]
})
Use the reader for store's proxy, it will create appropriate model on load.
If you need to load already loaded json into the store use loadRawData but reader you will need in any case.

When to use arrays within JavaScript objects (or mix them)? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
Very often I see data structures like this:
var settings = {
languages: [
{
language: 'English',
translation: 'English',
langCode: 'en',
flagCode: 'us'
},
{
...
}
]
};
Or this:
var settings = {
languages: [
{
'en' : {
language: 'English',
translation: 'English',
flagCode: 'us'
}
},
{
...
}
]
};
And this can go many levels deep (within an object there are often other arrays containing further objects)...
Adding arrays brings in another level of complexity when arrays have to be looped through to find a certain object, if we don't know its position in the array. But even if know its position it's still more complicated to use than using purely nested objects, where everything can easily be referred to, using dot notation. Like in this case:
var settings = {
languages: {
'en' : {
language: 'English',
translation: 'English',
flagCode: 'us'
},
'de' : {
...
}
}
};
So when is it a good idea to use arrays within objects and when not?
My simple answer
Use objects ({...}) when you need a collection of key:value pairs
Use arrays ([...]) when you need a collection of objects
Other differences
arrays are ordered, objects are not
arrays are automatically indexed with numbers, objects require you to specify an index
arrays have a .length property, objects do not
There can be multiple reason behind doing this. One of them is,
When you need object in specific order array is helpful here. i.e. in your first example
var settings = {
languages:
{
language: 'English',
translation: 'English',
langCode: 'en',
flagCode: 'us'
},
{
...
}
};
the inner object may shuffle it's position, when it's inside an array it will resides at it's index only.
How would you like your data structure to hold a list of things if not an array?
Lets say you have an object that describes a Person, How would you hold the persons Children?
var kid1 =
{
FirstName: "Abc",
LastName: "Def",
Children: null
};
var kid2 =
{
FirstName: "Abc",
LastName: "Def",
Children: null
};
var dad =
{
FirstName: "Abc",
LastName: "Def",
Children: [kid1,kid2]
};
Children must be an array since a person can have more than one child.

Categories

Resources