Related
I have an array of objects that is multi-leveled with different names that I need to populate a TreeView component :
export const application_group_one = [
{
id: uniqueId(),
name: "Application 1",
organizations: [
{
id: uniqueId(),
name: "Organization 1",
artifacts: [
{
id: uniqueId(),
name: "Artifact 1",
},
],
},
],
},
{
id: uniqueId(),
name: "Application 2",
organizations: [
{
id: uniqueId(),
name: "Organization 1",
artifacts: [],
},
],
},
];
export const application_group_two = [
{
id: uniqueId(),
name: "Application 3",
organizations: [
{
id: uniqueId(),
name: "Organization 1",
artifacts: [
{
id: uniqueId(),
name: "Artifact 1",
},
{
id: uniqueId(),
name: "Artifact 2",
},
{
id: uniqueId(),
name: "Artifact 3",
},
],
},
{
id: uniqueId(),
name: "Organization 2",
artifacts: [
{
id: uniqueId(),
name: "Artifact 1",
},
{
id: uniqueId(),
name: "Artifact 2",
},
{
id: uniqueId(),
name: "Artifact 3",
},
],
},
{
id: uniqueId(),
name: "Organization 3",
artifacts: [
{
id: uniqueId(),
name: "Artifact 1",
},
{
id: uniqueId(),
name: "Artifacy 2",
},
{
id: uniqueId(),
name: "Artifact 3",
},
],
},
{
id: uniqueId(),
name: "Organization 4",
artifacts: [
{
id: uniqueId(),
name: "Artifact 1",
},
{
id: uniqueId(),
name: "Artifact 2",
},
{
id: uniqueId(),
name: "Artifact 3",
},
],
},
],
},
];
I'm able to output the Organizations but not the artifacts. Having varying names for each children object is giving me a hard time. I would like a TreeView that can expand as many levels as I want with differing names for the nest objects. :
const getTreeItemsFromData = (treeItems) => {
return treeItems.map((treeItemData) => {
let organizations = undefined;
if (treeItemData.organizations && treeItemData.organizations.length > 0) {
organizations = getTreeItemsFromData(treeItemData.organizations);
}
return <TreeItem key={treeItemData.id} nodeId={treeItemData.id} label={treeItemData.name} children={organizations} />;
});
};
const DataTreeView = ({ treeItems }) => {
return (
<TreeView defaultCollapseIcon={<ExpandMoreIcon />} defaultExpandIcon={<ChevronRightIcon />}>
{getTreeItemsFromData(treeItems)}
</TreeView>
);
};
export const Tree = () => {
return (
<div className="App">
<DataTreeView treeItems={application_group_one} />
<br />
<DataTreeView treeItems={application_group_two} />
</div>
);
};
I have a problem with a query that I can't solve 100%
The fact is that when a user does not have any comment within the post. As inside the comments there is a "createdBy" and I need to make a lookup of that user inside the array. If there are no comments, it returns an array with an empty object, but it must return an empty array, not with empty objects.
Who can help me? Thank you very much in advance!
HERE MY USER collection (data)
[
{
_id: ObjectId("619d0f5df3f74665aff1a551"),
name: "Test Name",
surname: "Test Surname2",
createdAt: ISODate("2021-11-11T17:21:58.624+01:00"),
updatedAt: ISODate("2021-11-25T10:35:25.842+01:00"),
posts: [
{
_id: ObjectId("619d0f5df3f74575aff1a551"),
updatedAt: ISODate("2021-11-23T16:57:17.816+01:00"),
createdAt: ISODate("2021-11-23T16:57:17.816+01:00"),
content: "Test content....",
comments: [
{
createdBy: ObjectId("618d4326f1668007b3b98404"),
comment: "test comment...",
_id: ObjectId("619dfaaaa88266dc91b9489c"),
},
{
createdBy: ObjectId("618d4326f1668007b3b98404"),
comment: "test comment...",
_id: ObjectId("619dfc60a88266dc91b95741"),
},
],
date: ISODate("2021-11-23T16:57:17.820+01:00"),
},
{
_id: ObjectId("619d0f5df3f74575aff1a551"),
updatedAt: ISODate("2021-11-23T16:57:17.816+01:00"),
createdAt: ISODate("2021-11-23T16:57:17.816+01:00"),
content: "Test content....",
comments: [],
date: ISODate("2021-11-23T16:57:17.820+01:00"),
},
],
},
{
_id: ObjectId("619d0f5df3f74665aff1a551"),
name: "Test Name",
surname: "test surname",
createdAt: ISODate("2021-11-11T17:21:58.624+01:00"),
updatedAt: ISODate("2021-11-25T10:35:25.842+01:00"),
posts: [
{
_id: ObjectId("619d0f5df3f74575aff1a551"),
updatedAt: ISODate("2021-11-23T16:57:17.816+01:00"),
createdAt: ISODate("2021-11-23T16:57:17.816+01:00"),
content: "Test content....",
comments: [
{
createdBy: ObjectId("618d4326f1668007b3b98404"),
comment: "test comment...",
_id: ObjectId("619dfaaaa88266dc91b9489c"),
},
{
createdBy: ObjectId("618d4326f1668007b3b98404"),
comment: "test comment...",
_id: ObjectId("619dfe7ba88266dc91b961b6"),
},
],
date: ISODate("2021-11-23T16:57:17.820+01:00"),
},
{
_id: ObjectId("619d0f5df3f74575aff1a551"),
updatedAt: ISODate("2021-11-23T16:57:17.816+01:00"),
createdAt: ISODate("2021-11-23T16:57:17.816+01:00"),
content: "Test content....",
comments: [
{
createdBy: ObjectId("618d4326f1668007b3b98404"),
comment: "test comment...",
_id: ObjectId("619dfaaaa88266dc91b9489c"),
},
{
createdBy: ObjectId("618d4326f1668007b3b98404"),
comment: "test comment...",
_id: ObjectId("619dfc60a88266dc91b95741"),
},
],
date: ISODate("2021-11-23T16:57:17.820+01:00"),
},
],
},
];
HERE MY AGGREGATE QUERY
db.users.aggregate([
{ $unwind: { path: '$posts', preserveNullAndEmptyArrays: true } },
{ $unwind: { path: '$posts.comments', preserveNullAndEmptyArrays: true } },
{
$lookup: {
from: 'users',
localField: 'posts.comments.createdBy',
foreignField: '_id',
as: 'posts.comments.createdBy'
}
},
{ $unwind: { path: '$posts.comments.createdBy', preserveNullAndEmptyArrays: true } },
{
$group: {
_id: { _id: '$_id', post_id: '$posts._id' },
name: { $first: '$name' },
posts: { $push: '$posts' },
comments: { $push: '$posts.comments' },
}
},
{
$group: {
_id: '$_id._id',
name: { $first: '$name' },
posts: {
$push: {
_id: '$_id.post_id',
date: { $first: '$posts.date' },
content: { $first: '$posts.content' },
comments: '$comments'
}
}
}
},
])
Here an image with the fail array:
you have to remove preserveNullAndEmptyArrays field from unwind to don't have empity objects
The arrays I have
const users = [
{ id: 1, name: "field 1" },
{ id: 2, name: "field 2" },
{ id: 3, name: "field 3" },
{ id: 4, name: "field 4" },
];
const onlineUsers = [
{ id: 1, name: "field 1" },
{ id: 3, name: "field 3" }
];
I would like to find the online and offline ones by comparing the two series
I want to do:
const userLists = [
{ id: 1, name: "field 1", online: true },
{ id: 2, name: "field 2", online: false },
{ id: 3, name: "field 3", online: true },
{ id: 4, name: "field 4", online: false },
];
Using Array.map and Array.some
const users = [
{ id: 1, name: "field 1" },
{ id: 2, name: "field 2" },
{ id: 3, name: "field 3" },
{ id: 4, name: "field 4" },
];
const onlineUsers = [
{ id: 1, name: "field 1" },
{ id: 3, name: "field 3" }
];
var retVal=users.map(u=>{
var isOnline=onlineUsers.some(ou=> ou.id==u.id);//this will check if onlineUsers have some record with given userid
return {...u,online:isOnline}
})
console.log(retVal)
You can just traverse through the user list and you can find out the onlineuser using find and just push it in the onlineuserList.
const users = [
{ id: 1, name: "field 1" },
{ id: 2, name: "field 2" },
{ id: 3, name: "field 3" },
{ id: 4, name: "field 4" },
];
const onlineUsers = [
{ id: 1, name: "field 1" },
{ id: 3, name: "field 3" }
];
const userLists = [];
users.forEach(user => {
if(onlineUsers.find(q => q.id == user.id)){
userLists.push({
id: user.id,
name: user.name,
online: "true"
})
}
else{
userLists.push({
id: user.id,
name: user.name,
online: "false"
})
}
})
console.log(userLists);
a bit faster approach using Array.indexOf() and JSON.strigify()
const onlineUsers = JSON.stringify([
{ id: 1, name: "field 1" },
{ id: 3, name: "field 3" }
]);
const userList = users.map(user =>
({
...user,
online: onlineUsers.indexOf(JSON.stringify(user)) > -1
})
);
OR if you neither want to change original onlineUsers array nor declare another variable:
const userList = users.map(user =>
({ ...user, online: JSON.stringify(onlineUsers).indexOf(JSON.stringify(user)) > -1 })
);
Currently I'm filtering data based from questions that have checked property value equals to true..
const data = [
{Name: "foo", X1: "1", X2: "1", Other: "Test1"},
{Name: "bar", X1: "2",X2: "2",Other: "Test2"},
{Name: "test",X1: "2",X2: "3",Other: "Test3"}
];
const questions = [{rows: {text: "Text 1", checked: true,fields: "1",column: "X1"}
}, {rows: {text: "Text 2", checked: true,fields: "2",column: "X1"}
}, {rows: {text: "Text 3", checked: false,fields: "1",column: "X2"}
}, {rows: {text: "Text 4", checked: false,fields: "2",column: "X2"}
}, {rows: {text: "Text 5", checked: false,fields: "3",column: "X2"}
}];
console.log(questionArr);
// console.log(dataArr);
const res = data.filter(d => questions.find(f => d[f.rows.column] === f.rows.fields && f.rows.checked));
which works but does not work when filtering the actual data below. I think there's a slight difference between the question object and the actual question object below.. What should be my filter code when accessing these kind of structure ?
I think this is what you're looking for. I matched the data structure to the image in your question. Let me know if I missed something.
const data = [
{ Name: "foo", X1: "1", X2: "1", Other: "Test1" },
{ Name: "bar", X1: "2", X2: "2", Other: "Test2" },
{ Name: "test", X1: "2", X2: "3", Other: "Test3" }
];
const questions = [
{ rows: [{ text: "Text 1", checked: true, fields: "2", column: "X1" }] },
{ rows: [{ text: "Text 2", checked: true, fields: "2", column: "X1" }] },
{ rows: [{ text: "Text 3", checked: false, fields: "1", column: "X2" }] },
{ rows: [{ text: "Text 4", checked: false, fields: "2", column: "X2" }] },
{ rows: [{ text: "Text 5", checked: false, fields: "3", column: "X2" }] }
];
const result = data.filter(function(item){
return questions.some(function(question){
return question.rows.some(function(row){
return (row.checked && item[row.column] === row.fields);
});
});
});
console.log(result);
The compact version
const result = data.filter((item) => questions.some((question) => question.rows.some((row) => (row.checked && item[row.column] === row.fields))));
With perf in mind
const data = [
{ Name: "foo", X1: "1", X2: "1", Other: "Test1" },
{ Name: "bar", X1: "2", X2: "2", Other: "Test2" },
{ Name: "test", X1: "2", X2: "3", Other: "Test3" }
];
const questions = [
{ rows: [{ text: "Text 1", checked: true, fields: "2", column: "X1" }] },
{ rows: [{ text: "Text 2", checked: true, fields: "2", column: "X1" }] },
{ rows: [{ text: "Text 3", checked: false, fields: "1", column: "X2" }] },
{ rows: [{ text: "Text 4", checked: false, fields: "2", column: "X2" }] },
{ rows: [{ text: "Text 5", checked: false, fields: "3", column: "X2" }] }
];
const result = {};
for(let a = 0, b = data.length; a < b; a++){
const item = data[a];
for(let c = 0, d = questions.length; c < d; c++){
const rows = questions[c].rows;
for(let e = 0, f = rows.length; e < f; e++){
const row = rows[e];
if(row.checked && item[row.column] === row.fields){
result[item.Name] = item;
break;
}
}
}
}
// this could be replaced with Object.values(result);
const matches = [];
for(let match in result){
matches.push(result[match]);
}
// not supported by IE yet
// Object.values(result);
console.log(matches);
so, i have a select list and I am trying to select the item dynamically. The thing is, even doe the expression is evaluated to "true" the option is still not being selected
<label for="articlePage">Page:</label>
<select class="form-control pageList" name="articlePage" required="" ng-model="article.page_ID">
<option ng-repeat="page in pages" ng-selected ="{{page.id == article.page_ID}}" value={{page.id}}>{{page.name}}</option>
</select><br>
the scope(pages):
$scope.pages = [
{ name: "Home", id: "1" },
{ name: "Plugs", id: "2" },
{ name: "Pack Bedding", id: "3" },
{ name: "Pot Bedding", id: "4" },
{ name: "Poinsettias", id: "5" },
{ name: "Sales", id: "6" },
{ name: "Process Quality", id: "7" },
{ name: "Environment", id: "8" },
{ name: "Process Technology", id: "9" },
{ name: "Process Control", id: "10" },
{ name: "Infrastructure", id: "11" },
{ name: "News", id: "12" },
{ name: "About", id: "13" },
{ name: "Contact", id: "14" },
{ name: "Find Us", id: "15" },
{ name: "Key Personnel", id: "16" },
{ name: "Recruitment", id: "17" },
{ name: "Legal Information", id: "18" },
{ name: "Hidden", id: "19" }
];
there is also an service that is retrieving my articles, i know i get that right and like i said, the expression is being evaluated. here is a print screen to prove that:
does anyone have any idea why the option isn't being selected?
Thank you! :)
You don't need expression inside the ng-selected! Try this:
<label for="articlePage">Page:</label>
<select class="form-control pageList" name="articlePage" required="" ng-model="article.page_ID">
<option ng-repeat="page in pages" ng-selected ="page.id == article.page_ID" value="{{page.id}}">{{page.name}}</option>
</select><br>