retrieving data from an array, starting with specific nth item in AngularJs - javascript

Working on a project with Angular, and was curious if there is an 'angular-specific' method to acheive this.
I essentially want to retrieve data starting at a specific item in the array, like the 3rd.
You'll see in the html what I was curious if angular provides any type of method or filter.
html
<div ng-controller="bracketsController">
<div ng-repeat="bracket in brackets | limitTo: 2" class="bracket-container left" >
<div>{{bracket.brackets.single.contestant1}}</div>
<div>{{bracket.brackets.single.contestant2}}</div>
</div>
<div ng-repeat="bracket in brackets | limitTo: 2 SOME **Angular FILTER TO START AT 3**" class="bracket-container right" >
<div>{{bracket.brackets.single.contestant1}}</div>
<div>{{bracket.brackets.single.contestant2}}</div>
</div>
</div>
js
var bracketsapp = angular.module('bracketsApp', []);
bracketsapp.controller('bracketsController', function($scope){
$scope.brackets = [
{
"brackets": {
"single": {
"contestant1": "john doe",
"contestant2": "jane doe"
}
}
},
{
"brackets": {
"single": {
"contestant1": "john doe",
"contestant2": "jane doe"
}
}
},
{
"brackets": {
"single": {
"contestant1": "john doe",
"contestant2": "jane doe"
}
}
},
{
"brackets": {
"single": {
"contestant1": "john doe",
"contestant2": "jane doe"
}
}
},
{
"brackets": {
"single": {
"contestant1": "john doe",
"contestant2": "jane doe"
}
}
}
]
});
Thanks for any tips or suggestion.

You could just use the .slice method directly on the array:
<div ng-repeat="bracket in brackets.slice(3)" class="bracket-container right" >
Besides that though, there is a discussion they are having currently for the next version of angular to support this as a filter. You can follow along here: https://github.com/angular/angular.js/issues/5355

You can create you own filter, has mention here: Filter results 6 through 10 of 100 with ng-repeat in AngularJS
app.filter('slice', function() {
return function(arr, start, end) {
return (arr || []).slice(start, end);
};
});
<div ng-repeat="bracket in brackets | slice:3:2">{{item}}</div>

Related

JavaScript - specific queried from two databases

I need help with a JavaScript task.
How do I get something specific queried from two databases?
Task:
View the index.js file
Implement the gradeOverview() function, which gets the variables students and
grades and creates a grade overview for each student. Thereby
each element in the students array should be projected to an object in the following format:
{ student: (students[i]), grades: [(grades[j], grades[j+k], ...)] }
This is my function which accesses both databases and should retrieve and display a value from one database at a time based on the "student number".
function gradeOverview(students, grades) {
const result = students.map((student) => [
{
student: student,
grade: grades.reduce((grades, grade) => {
const student number = grade.studentnumber;
if (grades[matriculationnumber] == null) grades[matriculationnumber] = [];
grades[matriculationnumber].push(grade);
return grades;
}),
},
]);
console.log(result);
return result;
// TODO: implement me
}
The Data:
var students = [{
"matrikelnummer": 4636,
"vorname": "Vérane",
"nachname": "Voase"
}]
var grades = [{
"id": 628,
"matrikelnummer": 4636,
"grade": "3,3"
},
{
"id": 886,
"matrikelnummer": 4636,
"grade": "5,0"
}]
Output:
"student": {
"matrikelnummer": 4636,
"vorname": "Vérane",
"nachname": "Voase"
},
"grades": [
{
"id": 628,
"matrikelnummer": 4636,
"grade": "3,3"
},
{
"id": 886,
"matrikelnummer": 4636
"grade": "3,6"
}
]
},
Updated: Fiddle Link https://jsfiddle.net/uzrodex3/
I hope i guessed correctly your incoming data you put into gradeOverview function.
const studentsQueryResponse = [
{
name: "John Doe",
studentNumber: 123
},
{
name: "Johan Doe",
studentNumber: 321
},
{
name: "Jane Doe",
studentNumber: 111
}
]
const gradesQueryResponse = [
{
studentNumber: 123,
grade: 1
},
{
studentNumber: 123,
grade: 3
},
{
studentNumber: 321,
grade: 5
},
{
studentNumber: 123,
grade: 1
}
]
There is your function which returns in this case
[
{
"student": {
"name":"John Doe",
"studentNumber":123
},
"grade":[1,3,1]
},
{
"student": {
"name":"Johan Doe",
"studentNumber":321
},
"grade":[5]
},
{
"student": {
"name":"Jane Doe",
"studentNumber":111
},
"grade":[]
}
]
If you want to return whole grade object in array, then just remove map line which returns grade property value from grade object
function gradeOverview(students, grades) {
console.log("Input arguments", students, grades)
const results = students.map((student) => {
return {
student: student,
grade: grades
.filter((gradeObject) => gradeObject.studentNumber === student.studentNumber)
.map((gradeObject) => gradeObject.grade)
}
});
console.log("Results", results);
return results;
}
And then you call your function
gradeOverview(studenstQueryResponse, gradesQueryResponse)

How to create index properly in MongoDB to search in entire one collection?

I a have collection named people and this collection have almost 100k documents..
While I am a front-end dev, I don't know How can I boost my search performance.
I do search as below:
const phoneNumbers = [
{ "phone": { "$regex": `1` } },
{ "phone": { "$regex": `2` } },
{ "phone": { "$regex": `3` } },
{ "phone": { "$regex": `4` } },
{ "phone": { "$regex": `5` } },
{ "phone": { "$regex": `xxx` } },
{ "phone": { "$regex": `999` } },
{ "phone": { "$regex": `1000` } },
];
peopleCollection.find({$or: phoneNumbers}).toArray((error, matchedDocs)=> {
// returning matched docs
});
As you can see the structure of my search what is your suggestions to create index?
Is that helpful to create index ?
If yes how Can I create a proper index ?
Indexing does not reduce the complexity of your search expression, rather it helps the database to find out the matched result faster(i.e. reduce the time complexity).
Here is how you can create indexing:
db.collectionName.createIndex(key_name)
The above one-line operation creates indexing on key key_name.

AngularJS Array Comparison

I have got the following array of Usernames
Usernames = [
{
"id": 1,
"userName": "Jack",
"description": "jack is a nice guy",
"userRoleIds": [
1
]
},
{
"id": 2,
"userName": "Caroline",
"description": "Good girl",
"userRoleIds": [
2,3
]
},
{
"id": 3,
"userName": "Smith",
"description": "Smithyyyy",
"userRoleIds": [
1,2
]
}
]
And an array of userRoles.
userRoles = [
{
id: 1,
roleName: "Admin"
},
{
id: 2,
roleName: "Tester"
},
{
id: 3,
roleName: "Developer"
}
]
What i want to get done is first concat the arrays in in Usernames and userRoles to get the following result.
Usernames = [
{
"id": 1,
"userName": "Jack",
"description": "jack is a nice guy",
"userRoleIds": [
{
"id": 1,
"roleName" : "Admin"
}
]
},
{
"id": 2,
"userName": "Caroline",
"description": "Good girl",
"userRoleIds": [
{
"id": 2,
"roleName" : "Tester"
},
{
"id": 3,
"roleName" : "Developer"
}
]
},...
The second thing i want is to be able to filter for the roleName and userName seperated by pipe signs. As in type something in a text box that searches for userName and roleName for example.
if i type
Caroline, Tester
The result will be
result = [
{
"id": 2,
"userName": "Caroline",
"description": "Good girl",
"userRoleIds": [
2,3
]
},
{
"id": 3,
"userName": "Smith",
"description": "Smithyyyy",
"userRoleIds": [
1,2
]
}
]
What is the best practice for achieving this?
Thanks
Here is how I would do it. I prefer using services and take advantage of their functions to keep code clean.
app.service('UserService', function (PermisionsServices) {
var self = {
'list': [],
'load': function (Users) {//Pass your array of Users
angular.forEach(Users, function (user) {
angular.forEach(user.userRoleIds, function (role) {
self.user.userRolesIds.push(PermisionsServices.get(role));
});
self.list.push(user);
});
}, 'get': function (id) {
for (var i = 0; i < self.list.length; i++) {
var obj = self.list[i];
if (obj.id == id) {
return obj;
}
}
}
};
return self;
});
app.service('PermisionsServices', function () {
var self = {
'list': [],
'load': function (permisions) {//Pass your array of permisions
angular.forEach(permisions, function (permision) {
self.list.push(permision);
});
}, 'get': function (id) {
for (var i = 0; i < self.list.length; i++) {
var obj = self.list[i];
if (obj.id == id) {
return obj;
}
}
}
};
return self;
});
Afterwards, you can use it on your controller:
$scope.users=UserService;
And access each of the users as a separate object which can have multiple object permisions.
NOTE: Building the service (populating it) will of course depend on your app logic and controller, you could just easily remove the "load" function and just hardcode the list object by copy and pasting your arrays.
This is the approach I use to load data from API via resource.
Regards
Edit:
For use on the UI, you would just call:
<div ng-repeat='user in users.list'>
{{user.name}} has {{user.permissions}}
</div>
as the object information is already contained within it.
Edit 2:
If you want to search your data, then you can just add a filter like this:
<div ng-repeat='user in users.list | filter: filterList'>
{{user.name}} has {{user.permissions}}
</div>
And then on the controller:
$scope.filterList = function (user) {
if ($scope.filterTextBox) {
return user.name.indexOf($scope.filterTextBox) == 0;
}
return true;
}
Hope this works for you
I would do with pure JS like this. It won't take more than a single assignment line each.
var Usernames = [
{
"id": 1,
"userName": "Jack",
"description": "jack is a nice guy",
"userRoleIds": [
1
]
},
{
"id": 2,
"userName": "Caroline",
"description": "Good girl",
"userRoleIds": [
2,3
]
},
{
"id": 3,
"userName": "Smith",
"description": "Smithyyyy",
"userRoleIds": [
1,2
]
}
],
userRoles = [
{
id: 1,
roleName: "Admin"
},
{
id: 2,
roleName: "Tester"
},
{
id: 3,
roleName: "Developer"
}
],
modified = Usernames.reduce((p,c) => (c.userRoleIds = c.userRoleIds.map(e => e = userRoles.find(f => f.id == e)),p.concat(c)),[]),
query = ["Caroline","Tester"],
filtered = modified.filter(f => query.includes(f.userName) || f.userRoleIds.some(e => query.includes(e.roleName)));
console.log(JSON.stringify(modified,null,2));
console.log(JSON.stringify(filtered,null,2));
You can use lodash to achieve this.
var role = _.find(userRoles, function(role) {
return role.roleName == 'Tester';
});
_.find(Usernames, function(user) {
return user.userName == 'Caroline' || _.indexOf(user.userRoleIds, role.id)>=0;
});

MongoDB $project embedded document to root level

Using the aggregate pipeline, I am trying to project an embedded document to the root level WITHOUT projecting each field individually.
For example, I want to project name from this collection to the root level:
[
{
_id: "1",
name: {
firstName: "John",
lastname: "Peters"
}
},
{
_id: "2",
name: {
firstName: "Mary",
lastname: "Jones"
}
}
]
This is what I am looking for:
[
{
firstName: "John",
lastname: "Peters"
},
{
firstName: "Mary",
lastname: "Jones"
}
]
Is there a way to do this without projecting each field individually? I don't want to have to do this:
db.collection.aggregate(
[
{
$project : {
"_id" : 0,
"firstName" : "$name.firstName",
"lastName" : "$name.lastName"
}
}
]
MongoDB 3.4 has the new stage in aggregation pipeline - $replaceRoot, which does exactly what was asked.
https://docs.mongodb.com/manual/reference/operator/aggregation/replaceRoot/
Here is the solution which uses JavaScript variable.
# Set Object for what to project
var projectWhat = {'_id' : 0};
# Fill Object with keys
Object.keys(db.coll.findOne().name).forEach(function(x){
projectWhat[x] = "$name." + x;
});
# Do Aggregate
db.coll.aggregate([{$project : projectWhat}])
And the output will be
{ "firstName" : "John", "lastname" : "Peters" }
{ "firstName" : "Mary", "lastname" : "Jones" }
Hope this helps.
You can use $replaceRoot like this:
db.collection.aggregate(
[
{
$replaceRoot : {
newRoot: {"$name"}
}
}
]
)
Also if you have a field in the root document you want to retain you can use a $mergeObjects to combine it with your embedded object:
db.collection.aggregate(
[
{
$replaceRoot : {
newRoot: {
$mergeObjects: [
{"_id": "$_id"},
"$name"
]
}
}
}
]
)
This may be achieved by using $set to update all documents with the values in the name sub-document:
db.collection.find({ "name": {"$exists": 1 } }).forEach(function(doc) {
var setName = {};
for ( var k in doc.name ) {
setName[k] = doc.name[k];
}
db.collection.update(
{ "_id": doc._id },
{ "$set": setName, "$unset": "name" }
);
})
While I'll recommend you use $project because it would be more performant than this solution, I can understand why you wouldn't want to use $project.
Starting Mongo 4.2, the $replaceWith aggregation operator can be used to replace a document by another (in our case by a sub-document):
// { _id: "1", name: { firstName: "John", lastname: "Peters" } }
// { _id: "2", name: { firstName: "Mary", lastname: "Jones" } }
db.collection.aggregate({ $replaceWith: "$name" })
// { firstName: "John", lastname: "Peters" }
// { firstName: "Mary", lastname: "Jones" }

angularjs ng-options with formate date delete duplicates

I made a filter for the field DataIscr on this json :
[
{
"IdPers": "1067",
"CognNome": "JANE SMITH",
"Sex": "F",
"DataIscr": "1949-12-29T00:00:00+01:00"
},
{
"IdPers": "1093",
"CognNome": "JOHN SMITH",
"Sex": "M",
"DataIscr": "1969-12-02T00:00:00+01:00"
},
{
"IdPers": "1093",
"CognNome": "JANE SMITH",
"Sex": "F",
"DataIscr": "1969-06-17T00:00:00+01:00"
}
]
and I used the format date: 'yyyy' to display only the year:
<label for="DataIscr">DataIscr:</label>
<select style="width:200px" data-ng-options="Person.DataIscr as Person.DataIscr|date:'yyyy' for Person in OutAnagrafica" id="DataIscr" data-ng-model="filter.DataIscr" class="form-control input-sm"></select>
plunker:http://plnkr.co/edit/ED1v7czBosNSpCYxKW7n?p=preview
How can I delete the duplicates?? I want to filter object with the same year and the filter 'unique' from angular Ui doesn't work. How can I do??
Sidos Check this out , i used 'angular.filter' modules unique filter .
<select style="width:200px" data-ng-options="Person for Person in OutAnagrafica| removeDuplicates " id="DataIscr" data-ng-model="filter.DataIscr" class="form-control input-sm"></select>
App.filter('removeDuplicates', function ($filter) {
return function (input) {
var dates=[];
angular.forEach(input,function(item,index)
{
dates.push($filter('date')(item.DataIscr,'yyyy'));
})
console.log(dates);
return $filter('unique')(dates);
};
});
http://embed.plnkr.co/slrtdv/preview
Instead of using the angular ui filter, write your own custom filter for filtering the date values. since the UI filter check for the whole value, it does not support the format the values for duplicate removal. below is the fiddle link for your scenario.
JS
var app = angular.module('myApp', []);
app.controller('OutAnCtrl', function ($scope) {
$scope.OutAnagrafica = [{
"IdPers": "1067",
"CognNome": "JANE SMITH",
"Sex": "F",
"DataIscr": "1949-12-29T00:00:00+01:00"
}, {
"IdPers": "1093",
"CognNome": "JOHN SMITH",
"Sex": "M",
"DataIscr": "1969-12-02T00:00:00+01:00"
}, {
"IdPers": "1093",
"CognNome": "JANE SMITH",
"Sex": "F",
"DataIscr": "1969-06-17T00:00:00+01:00"
}];
});
app.filter('customDateUnique', function ($filter) {
return function (arr, field) {
return _.uniq(arr, function (a) {
return $filter('date')(a.DataIscr, 'yyyy');
});
};
});
HTML
<body>
<div>
<div data-ng-controller="OutAnCtrl">
<label for="DataIscr">DataIscr:</label>
<select style="width:200px" data-ng-options="Person.DataIscr as Person.DataIscr|date:'yyyy' for Person in OutAnagrafica | customDateUnique" id="DataIscr" data-ng-model="filter.DataIscr" class="form-control input-sm"></select>
</div>
</div>
</body>
http://jsfiddle.net/1tw3zg9s/1/
After seeing your comment, I changed my answer.
You can define a new $scope.filtered array and upon ajax success do:
$http.get('OutAnagrafica.json')
.success(function (data) {
$scope.OutAnagrafica = data;
$scope.OutAnagrafica.forEach(function(item) {
if (yearUnique($scope.filtered, item)) {
$scope.filtered.push(item);
}
});
});
And you have the function yearUnique:
function yearUnique(arr, item) {
var year = item.DataIscr.substring(0, 4);
var res = true;
if (arr.forEach(function(i) {
if (i.DataIscr.indexOf(year) > -1) {
console.log('false');
res = false;
}
}));
return res;
}
And on the HTML:
<tr data-ng-repeat="Person in filtered">
...
</tr>
Plunker

Categories

Resources