sorting collection objects into directive by id with recursion - angularjs

I've been checking some posts about recursive directives in here, but none of them seems to work for me.
Basically my case is the following:
Having a collection of objects as follows:
[
{id: 1, parentid:null, text: 'something 1'},
{id: 2, parentid:null, text: 'something 2'},
{id: 3, parentid:1, text: 'something 3'},
{id: 4, parentid:1, text: 'something 4'},
{id: 5, parentid:2, text: 'something 5'},
{id: 6, parentid:3, text: 'something 6'},
{id: 7, parentid:4, text: 'something 7'},
{id: 8, parentid:5, text: 'something 8'}
]
Of course there are more keys, but these are needed to place the logic.
Basically I something which renders the following:
<ul>
<li>Parent id: n
<ul>
<li>Children of n</il>
</li>
</ul>
So my first guess was that I need a directive which renders a similar version of itself each time there is a child occurence, but I'm sure even how to attack this. I just need a unknown number of heritance refers to the child of the upper level.
Any approach or pattern remendation to face this?

I think the easiest way is to first organise the data into hierarchical structure like this:
[
{
id: 1,
parentid:null,
text: 'something 1',
children: [
{id: 3, parentid:1, text: 'something 3'},
{id: 4, parentid:1, text: 'something 4'},
]
},
{
id: 2,
parentid:null,
text: 'something 2',
children: [
{id: 5, parentid:2, text: 'something 5'}
]
},
]
Then rendering with ng-repeat with nested ng-repeat is quite obvious.
If you have more levels in this hierarchy, then thinking about some kind of recursion may be a solution.
EDIT:
The simplest way is to reorganise data for rendering purposes in an object, where indexes (property names) are ids, and values are arrays with this node children. Then, to get children of each id you can get them by dictVar[parentId].
Data transformation is quite simple and can be done various ways, e.g.:
var dataDict = {};
angular.forEach(data, function (item) {
var id = item.parentid || 0;
var items = $scope.dataDict[id] || [];
items.push(item);
dataDict[id] = items;
});
After that in dataDict you have:
{
"0": [
{"id": 1, "parentid": null, "text": "something 1"},
{"id": 2, "parentid": null, "text": "something 2"}
],
"1": [
{"id": 3, "parentid": 1, "text": "something 3"},
{"id": 4, "parentid": 1, "text": "something 4"}
],
"2": [
{"id": 5, "parentid": 2, "text": "something 5"}
],
"3": [
{"id": 6, "parentid": 3, "text": "something 6"}
],
"4": [
{"id": 7, "parentid": 4, "text": "something 7"}
],
"5": [
{"id": 8, "parentid": 5, "text": "something 8"}
]
}
You can leave it like this or transform it even further to get fully hierarchical structure.
Then, to render the list you can use technique described here: http://sporto.github.io/blog/2013/06/24/nested-recursive-directives-in-angular/

Related

React JS Material UI DataGrid: how to join data between multiple table?

I have a dataGrid with React and Material UI. All data comes from table A which is structured as follows:
{Name: foo, Surname: Fry, Job Position: 3}
Then there is a table B which contains the correspondences of the various works eg:
{id: 3, Job: "comic"}
{id: 4, Job: "actor"}
etc...
how do i show "comic" in the grid instead of "3" as in the example?
A thousand thanks
You can process your data using the map() function. If your original data is in an array called people:
const people = [
{name: "Alice", surname: "Alman", job:3},
{name: "Bob", surname: "Briscoe", job:3},
{name: "Carol", surname: "Conway", job:1},
{name: "Dan", surname: "Dunne", job:2},
]
And you have the second table available
const jobs = [
{id: 1, job:"Programmer"},
{id: 2, job:"Actor"},
{id: 3, job:"Comic"},
{id: 4, job:"Manager"},
]
Then before passing the data to the grid you can do the following map to add the job title to each record:
const data = people.map(person => {
const job = jobs.find(job => job.id == person.job);
return {...person, title: job.job}
});
Which ends up with these values:
[{
"name": "Alice",
"surname": "Alman",
"job": 3,
"title": "Comic"
}, {
"name": "Bob",
"surname": "Briscoe",
"job": 3,
"title": "Comic"
}, {
"name": "Carol",
"surname": "Conway",
"job": 1,
"title": "Programmer"
}, {
"name": "Dan",
"surname": "Dunne",
"job": 2,
"title": "Actor"
}]

retrieve all data by size of array in spring mongo template

Suppose I have these:
{id: 1, name: name1, tags: [{id: 1, name: tag1}]},
{id: 2, name: name2, tags: []},
{id: 3, name: name3, tags: [{id: 3, name: tag3}, {id:33, name: tag33}]},
{id: 4, name: name4}
Then execute a query and I want this:
{id: 1, name: name1, tags: [{id: 1, name: tag1}]},
{id: 3, name: name3, tags: [{id: 3, name: tag3}, {id:33, name: tag33}]}
Getting documents that have "tags" array and its size is larger than 0. But don't know how to create my criteria.
I tried this but throws an error saying that size() has to take an argument of int...
where(tags).size().gt(0)
Anyone knows the correct one?
'$size' operator doesn't accept the range parameters. You could use positional value existence to decide the size. as follows
db.collection.find({
"tags.0": {
$exists: true
}
})
In Spring, You could try as follows,
mongoTemplate.find(Query.query(Criteria.where("tags.0").exists(true)));
You can use $not operator:
where("tags").not().size(0).andOperator(where("tags").exists(true));
db.collection.find({
"tags": {
"$not": {
"$size": 0
}
},
"$and": [
{
"tags": {
"$exists": true
}
}
]
})
Alternative: You cannot create this with Spring-data-mongo framework:
db.collection.find({
tags: {
$exists: true,
$not: {
$size: 0
}
}
})

How to Join Multiple Arrays inside filter function of Arrays in Typescript

I am using Typescript in an Angular/Ionic project. I have an array of users that contain an array of skills. I have to filter users based on their online status as well as skills.
[
{
"id": 1,
"name": "Vikram Shah",
"online_status": "Online",
"skills": [{
"id": 2,
"title": "CSS"
},
{
"id": 3,
"title": "JavaScript"
},
{
"id": 4,
"title": "Python"
}
]
},
{
"id": 1,
"name": "Abhay Singh",
"online_status": "Online",
"skills": [{
"id": 1,
"title": "HTML"
},
{
"id": 2,
"title": "CSS"
},
{
"id": 3,
"title": "JavaScript"
},
{
"id": 4,
"title": "Python"
}
]
},
{
"id": 1,
"name": "Test Oberoi",
"online_status": "Online",
"skills": [{
"id": 1,
"title": "HTML"
},
{
"id": 2,
"title": "CSS"
},
{
"id": 3,
"title": "JavaScript"
},
{
"id": 4,
"title": "Python"
}
]
}
]
This is how all skills look like
this.skill_types = [
{"id":8,"title":"Cleaner", checked:false},
{"id":7,"title":"Painter", checked:false},
{"id":6,"title":"Plumber", checked:false},
{"id":5,"title":"Carpenter", checked:false},
{"id":4,"title":"Advisor", checked:false},
{"id":3,"title":"Team Leader", checked:false},
{"id":2,"title":"Management", checked:false},
{"id":1,"title":"Administrator", checked:false}
];
This array contains the IDs of skills that I want to filter
filterArr = [1, 3, 6];
This solution is almost working as expected. It is filtering well based on two criteria together.But not sure how to add condition for second filtering. The second filter should apply only if filterArr is not empty.
return this.items = this.items.filter((thisUser) => {
return thisUser.online_status.toLowerCase().indexOf(onlineStatus.toLowerCase()) > -1 &&
thisUser.skills.some(c => this.filterArr.includes(c.id))
});
The issue I am facing with code above is When there is no skill selected in the filter criteria, I would like to display all users. But it is not working that way. The logic here is to not apply any filter when the size of selected skills (filter condition) is greater than zero. So I tried this way....which looks similar to the way above...but this makes everything worse.
let filteredByStatus = [];
filteredByStatus = this.items.filter((thisUser) => {
return thisUser.online_status.toLowerCase().indexOf(onlineStatus.toLowerCase()) > -1
});
//Condition can be applied if filtering is separated
let filteredBySkills = [];
filteredBySkills = this.items.filter((thisUser) => {
return thisUser.skills.some(c => this.filterArr.includes(c.id))
});
//Expecting to join results from multiple filters
return this.items = filteredByStatus.concat(filteredBySkills);
But this is not working at all. Not sure what wrong is there. I am looking for a solution that enables to join arrays of similar objects without duplicating them.
Don't think you need to join arrays for your filtering. You can use something like rxjs filter.
return from(this.items)
.pipe(
filter(user => {
return user.online_status.toLowerCase().indexOf(onlineStatus.toLowerCase()) > -1
&& user.skills.some(c => filterArr.includes(c.id));
})
);
Or if you like to split it up you can just change it to like:
return from(this.items)
.pipe(
filter(user => user.online_status.toLowerCase().indexOf(onlineStatus.toLowerCase()) > -1),
filter(user => user.skills.some(c => filterArr.includes(c.id)))
);
Stackblitz: https://stackblitz.com/edit/angular-pk3w8b
You can tweak your condition a bit and place !this.filterArr.length in your condition (in terms of OR condition AND with user status) to make your whole condition gets true so that user gets filter.

Flutter: Parse json arrays without name

I am getting json response from server as below.
[
[{
"ID": 1,
"Date": "11-09-2015",
"Balance": 1496693.00
}, {
"ID": 2,
"Date": "01-10-2015",
"Balance": 1496693.00
}],
[{
"ID": 1,
"Date": "03-09-2000",
"IntAmount": "003.00"
}],
[{
"EmployeeId": "000",
"DesignationName": "deg"
}],
[{
"LoanAmount": "00000.00",
"IntRate": "3.00",
"LoanNo": "56656"
}]
]
I can parse json array with name but in above json there are three arrays without name.
How to parse above json in three different arrays?
If you are positive that the data will always come in the stated format, then you can iterate through the result. See below for example:
main(List<String> args) {
// Define the array of data "object" like this
List<List<Map<String, dynamic>>> arrayOfData = [
[
{"ID": 1, "Date": "11-09-2015", "Balance": 1496693.00},
{"ID": 2, "Date": "01-10-2015", "Balance": 1496693.00}
],
[
{"ID": 1, "Date": "03-09-2000", "IntAmount": "003.00"}
],
[
{"EmployeeId": "000", "DesignationName": "deg"}
],
[
{"LoanAmount": "00000.00", "IntRate": "3.00", "LoanNo": "56656"}
]
];
/*
Iterate through the array of "objects" using forEach,
then, iterate through each resulting array using forEach
*/
arrayOfData.forEach((datasetArray) => datasetArray.forEach((dataset) => print(dataset)));
/*
============== RESULT ========
{ID: 1, Date: 11-09-2015, Balance: 1496693.0}
{ID: 2, Date: 01-10-2015, Balance: 1496693.0}
{ID: 1, Date: 03-09-2000, IntAmount: 003.00}
{EmployeeId: 000, DesignationName: deg}
{LoanAmount: 00000.00, IntRate: 3.00, LoanNo: 56656}
*/
}

How to normalize paginated data?

I need to convert a data like this:
{peopleList: [{id:1, name: 'joe'}, {id: 2, name: 'john'}], page: 1, rowPerPage: 8}
to this model:
{entities: {'0': {id: 0, name: 'joe'}, '1': {id: 1, name: 'john'}, page: 1, rowPerPage: 8}, result: [0, 1]}
but when I add this schema:
const people = new schema.Entity('peopleList');
const normalizedData = normalize(_data, { peopleList: [people] });
I get this output:
{
"entities": {
"peopleList": {
"1": {
"id": 1,
"name": "joe"
},
"2": {
"id": 2,
"name": "john"
}
}
},
"result": {
"peopleList": [
1,
2
],
"page": 1,
"rowPerPage": 8
}
}
I don't know exactly how to make a proper schema that create result filed as my desire. maybe the correct way is to have it in result and this output is correct. any idea?

Resources