lodash filter deeply nested objects returning array of those objects - lodash

I'm trying to return an array of objects that are deeply nested in another array. Here is a sample object with arrays:
payment = {
"id": 1,
"tickets" = [{
"id": 1,
"ticketItems": [{item1}, {item2}, {item3}]
},
{"id": 2",
"ticketItems": [{item4}, {item5}, {item6}]
}]}
Using lodash I would like to return an array of just items 1-6 without the parent objects. I've tried:
var items = _.filter(payment.tickets, {'ticketItems'});
But that doesn't return an array of ticketItems. All the examples I've found use a condition like "id: 1", but I want all of the ticketItems, not just those matching a condition.

You can use Array.flatMap() (or lodash's _.flatMap()) and return the ticketItems from each tickets object:
const payment = {"id":1,"tickets":[{"id":1,"ticketItems":[{"item1":1},{"item2":2},{"item3":3}]},{"id":2,"ticketItems":[{"item4":4},{"item5":5},{"item6":6}]}]}
const result = payment.tickets.flatMap(o => o.ticketItems)
console.log(result)
And the same solution with lodash's _.flatMap():
const payment = {"id":1,"tickets":[{"id":1,"ticketItems":[{"item1":1},{"item2":2},{"item3":3}]},{"id":2,"ticketItems":[{"item4":4},{"item5":5},{"item6":6}]}]}
const result = _.flatMap(payment.tickets, 'ticketItems')
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>

Related

How to edit the element inside the object of array in redux

This is my array object that is already stored in the redux state (attendanceClass)
I would like to update the studentAtt in the state after I perform an update action.
Array [
classAttendance {
"studentAtt": 0,
"studentID": "123",
"studentName": "User1",
},
classAttendance {
"studentAtt": 0,
"studentID": "456",
"studentName": "User2",
},
]
My reducer store over here.
case UPDATE_ATTENDANCE:
const index = state.attendanceClass.findIndex(student => student.studentID !== action.studentID )
console.log(index);
const updatedAtt = [...state.attendanceClass];
console.log(updatedAtt);
updatedAtt[index].studentAtt = action.studentAtt;
return{
...state,
attendanceClass:updatedAtt
};
I would like to access the index of the array and update the updated attendance and pass it to the exiting state.
However, it does not update and kept return error to me.
Look inside the test function that you're passing into findIndex(), the condition you're using is student.studentID !== action.studentID. That returns true if the student ID is not equal to the one provided in the action. Replace the !== with === to select the correct student.
const index = state.attendanceClass.findIndex(student => student.studentID === action.studentID )
However, there's a cleaner way to update a single item in an array: use .map() and the spread ... syntax.
case UPDATE_ATTENDANCE:
const attendanceClass = state.attendanceClass.map(
student => student.studentID === action.studentId ?
{
...student,
studentAtt: action.studentAtt
} :
student
);
return {
...state,
attendanceClass
};

Vuex getters forEach returns single value instead of multiple

I have a cart, and it's an array of products, I am trying to access every name in the cart.
I have forEach function in getters, but it returns just one name. I have tried.map() but it returns another array and I need multiple string values. Can you please help?
let cart = window.localStorage.getItem('cart')
const store = createStore({
state: {
cart: cart ? JSON.parse(cart) : [],
},
getters: {
setTitle: state =>{
let oneItem=''
state.cart.forEach((item)=>{
oneItem=item.ropeTitle
})
return oneItem
},
}
}
It's because you're returning just oneItem (let me guess, it's also the last item in the state.cart array as well?)
What you can try instead is using .join() to join the item together.
Let's say you want to join items by , , you can try
setTitle: state => state.cart.map(item => item.ropeTitle).join(', ')

Ramda - get ids from nested array of multiple objects

I am trying to get outgoingNodes IDs which are stored in array which is inside objects like in example below but I have no idea where to start...:
const nodes = {
"818": {
"id": "818",
"index": 1,
"outgoingNodes": [
"819"
],
},
"819": {
"id": "819",
"outgoingNodes": [
"820",
"821"
],
}
}
I would like to get an array of IDs as a result. Any help will be appreciated.
Get the values (sub objects), pluck the outgoingNodes arrays, and flatten to a single array:
const { pipe, values, pluck, flatten } = R
const fn = pipe(
values,
pluck('outgoingNodes'),
flatten
)
const nodes = {"818":{"id":"818","index":1,"outgoingNodes":["819"]},"819":{"id":"819","outgoingNodes":["820","821"]}}
const result = fn(nodes)
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.1/ramda.min.js" integrity="sha512-rZHvUXcc1zWKsxm7rJ8lVQuIr1oOmm7cShlvpV0gWf0RvbcJN6x96al/Rp2L2BI4a4ZkT2/YfVe/8YvB2UHzQw==" crossorigin="anonymous"></script>
Another option is to combine getting the outgoingNodes arrays, and flattening to a single array using R.chain with R.prop:
const { pipe, values, chain, prop } = R
const fn = pipe(
values,
chain(prop('outgoingNodes')),
)
const nodes = {"818":{"id":"818","index":1,"outgoingNodes":["819"]},"819":{"id":"819","outgoingNodes":["820","821"]}}
const result = fn(nodes)
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.1/ramda.min.js" integrity="sha512-rZHvUXcc1zWKsxm7rJ8lVQuIr1oOmm7cShlvpV0gWf0RvbcJN6x96al/Rp2L2BI4a4ZkT2/YfVe/8YvB2UHzQw==" crossorigin="anonymous"></script>

Lodash: filter when I have nested array property?

Consider below example. I am using Lodash
"home":[
{
"data":{
"interests":["sports", "travel", "boxing"],
"city":["x", "y", "z"],
"name":"test1"
},
"count":["1", "2"],
"country":"CA"
},
{
"data":{
"interests":["painting", "travel", "dancing"],
"city":["a", "y", "b"],
"name":"test2"
},
"count":["1","3"],
"country":"US"
}
]
If I'll try the function on key value pair example :
_.find(home, ['data.country', 'US']); // It is returning me the 2nd object
requirement :
I want all the objects where data.interests is 'dancing'.
Tried :
_.find(home, ['data.interests', 'dancing']) // It is returning []
I have also tried filter(), where() and map but unable to get the complete object.
Thanks in advance.
You can use vanilla JS or lodash funcntions - Filter the array, and for each item check if the data.interests array includes the requested word.
Vanilla:
const home = [{"data":{"interests":["sports","travel","boxing"],"city":["x","y","z"],"name":"test1"},"count":["1","2"],"country":"CA"},{"data":{"interests":["painting","travel","dancing"],"city":["a","y","b"],"name":"test2"},"count":["1","3"],"country":"US"}]
const result = home.filter(o => o.data.interests.includes('dancing'))
console.log(result)
Lodash:
const home = [{"data":{"interests":["sports","travel","boxing"],"city":["x","y","z"],"name":"test1"},"count":["1","2"],"country":"CA"},{"data":{"interests":["painting","travel","dancing"],"city":["a","y","b"],"name":"test2"},"count":["1","3"],"country":"US"}]
const result = _.filter(home, o => _.includes(o.data.interests, 'dancing'))
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>

How To Access All Indexes In Nested Array (Vue-chartjs)

so I am trying to display data on my doughnut chart and I am having issues accessing my data from a nested array. When I use the following it just gives me the selected index of the nested array.
So I am wondering is there something else I need to do the computed data or if there is something I am doing wrong.
here is the computed property
countEngagementsByStatus () {
const selectedWorkflow = this.allWorkflows.filter(workflow => workflow.id === this.workflowKey)
const res = selectedWorkflow.map(({statuses, id}) => ({
workflow_id: id,
statuses: statuses.reduce((acc, cur) => {
const count = this.allEngagements.filter(({workflow_id, status}) => workflow_id === id && status === cur.status).length;
acc.push(count);
return acc;
}, [])
}))
return res
},
And on my doughnut chart I am accessing the data. *note removed styling data to clean up the question
datasetsfull() {
return {
labels: this.mapStatuses[0].statuses,
datasets: [
{
label: 'Data One',
data: [
//this is the line I have issues with
this.countEngagementsByStatus[0].statuses[0]
]
}
]
}
},
here is an image of what I am getting
Now If I do this
data: [
this.countEngagementsByStatus[0]
]
I get this as a result however it cannot access the array of numbers shown
So my question is, am I doing something wrong with computed property or am I accessing the data incorrectly or both? Lol
Here is a Js Fiddle To give an idea
So my issue was I was wrapping the data in an array
data: [
this.countEngagementsByStatus[0].statuses
]
I changed it to this
data: this.countEngagementsByStatus[0].statuses