How to count the value in an nested array in Vue.js? - vue.js

I'm trying to count how many hr_checked = false by specific user on a nested array inside an array in an Vue.js. Here's a snippet of array code:
userlistes: [
{
id: 2,
username: "Larry",
department_id: 3,
department: {
department_name: "IT",
id: 3,
},
worklists: [
{
id: 278,
user_id: 2,
task_id: 1,
date: "2021-07-30",
hour: 2,
description: "A",
is_overtime: false,
overtime_hour: 0,
task: {
taskname: "Task A",
},
hr_checked: false,
},
{
id: 277,
user_id: 2,
task_id: 1,
date: "2021-07-30",
hour: 3,
description: "B",
is_overtime: false,
overtime_hour: 0,
task: {
taskname: "Task B",
},
hr_checked: false,
},
],
},
{
id: 4,
username: "Tom",
department_id: 2,
department: {
department_name: "Business",
id: 2,
},
worklists: [
{
id: 259,
user_id: 4,
task_id: 7,
date: "2021-07-27",
hour: 6.5,
description:
"A",
is_overtime: false,
overtime_hour: 0,
task: {
taskname: "Task A",
},
hr_checked: false,
},
{
id: 260,
user_id: 4,
task_id: 7,
date: "2021-07-27",
hour: 0.5,
description: "B",
is_overtime: false,
overtime_hour: 0,
task: {
taskname: "Task B",
},
hr_checked: false,
},
],
},
],
And i tried to used Vue computed property to implement this:
computed: {
countCheck() {
return this.userlistes.filter((userliste) => {
return userliste.workhours.reduce((sum, workhour) => {
if (workhour.hr_checked === false) {
sum++;
}
return sum;
}, 0);
});
}
I want to get the count of the values inside the nested array's 'hr_checked'.
the returning result should be like:
Larry: unchecked 2
Tom: unchecked 2
Is there any way to do this in Vue.js? or i'm use wrong function??

Try to map the wrapping array then reduce the nested one :
return this.userlistes.map((item)=>({username:item.username,
unchecked :item.worklists.reduce((sum, workhour) => {
if (workhour.hr_checked === false) {
sum++;
}
return sum;
}, 0)}))
let userlistes = [{
id: 2,
username: "Larry",
department_id: 3,
department: {
department_name: "IT",
id: 3,
},
worklists: [{
id: 278,
user_id: 2,
task_id: 1,
date: "2021-07-30",
hour: 2,
description: "A",
is_overtime: false,
overtime_hour: 0,
task: {
taskname: "Task A",
},
hr_checked: false,
},
{
id: 277,
user_id: 2,
task_id: 1,
date: "2021-07-30",
hour: 3,
description: "B",
is_overtime: false,
overtime_hour: 0,
task: {
taskname: "Task B",
},
hr_checked: false,
},
],
},
{
id: 4,
username: "Tom",
department_id: 2,
department: {
department_name: "Business",
id: 2,
},
worklists: [{
id: 259,
user_id: 4,
task_id: 7,
date: "2021-07-27",
hour: 6.5,
description: "A",
is_overtime: false,
overtime_hour: 0,
task: {
taskname: "Task A",
},
hr_checked: false,
},
{
id: 260,
user_id: 4,
task_id: 7,
date: "2021-07-27",
hour: 0.5,
description: "B",
is_overtime: false,
overtime_hour: 0,
task: {
taskname: "Task B",
},
hr_checked: false,
},
],
},
]
let mapped = userlistes.map((item) => ({
username: item.username,
unchecked: item.worklists.reduce((sum, workhour) => {
if (workhour.hr_checked === false) {
sum++;
}
return sum;
}, 0)
}))
console.log(mapped)

Here is another solution:
link to codesandbox example
Code in computed props:
computed: {
getHRByUser() {
let res = [];
let reducer = (sum, workitem) => {
if (workitem.hr_checked === false) {
sum++;
}
return sum;
};
for (const i in this.userlistes) {
let inactiveHRCount = this.userlistes[i].worklists.reduce(reducer, 0);
res.push({
username: this.userlistes[i].username,
inactiveHRCount: inactiveHRCount,
});
}
return res;
},
}
But Boussadjra Brahim proposed a bit more elegant solution in this case.

computed is fine as your data are dynamic and the function would run everytime the data changes. I would use the above example
countCheck() {
let count = 0
this.userlistes.filter((userliste) => {
if (userliste.workhours && userliste.workhours.hr_checked) {
count++
}
})
return count
}

Related

Why sequelize return result different than console.log(return)?

I try to send the data through postman and the data result is clean(without another property). But when I try to console.log(data), there are many other properties. I read on another thread(Sequelize return result is different than console.log(result)), this is because res.json serialized the data into a plain object with model props from dataValues. But how can res.json only get the dataValues property meanwhile the other properties are ignored?
my code:
async getItems(req, res, next){
const data = await Item.findAll({
attributes: ['id', 'name', 'price']
});
console.log(data);
return res.status(200).json(data);
};
postman result:
[
{
"id": 1,
"name": "PS5",
"price": 600
},
{
"id": 2,
"name": "XBOX X",
"price": 400
}
]
console.log(data) result:
[
Item {
dataValues: {
id: 1,
name: 'PS5',
price: 600
},
_previousDataValues: {
id: 1,
name: 'PS5',
price: 600
},
uniqno: 1,
_changed: Set(0) {},
_options: {
isNewRecord: false,
_schema: null,
_schemaDelimiter: '',
raw: true,
attributes: [Array]
},
isNewRecord: false
},
Item {
dataValues: {
id: 2,
name: 'XBOX X',
price: 400
},
_previousDataValues: {
id: 2,
name: 'XBOX X',
price: 400
},
uniqno: 1,
_changed: Set(0) {},
_options: {
isNewRecord: false,
_schema: null,
_schemaDelimiter: '',
raw: true,
attributes: [Array]
},
isNewRecord: false
}
]
Sequelize models implement a toJSON method which JSON.stringify calls under the hood. You can also call model.toJSON() to get cleaner logs:
https://sequelize.org/docs/v6/core-concepts/model-instances/#note-logging-instances
Another example:
JSON.stringify({
toJSON() {
return 'arbitrary value';
}
});
// => "arbitrary value"

DataTables - set row colour

I am using DataTables and would like to set the background colour for each row depending on the input. I followed the directions in the forum:
https://datatables.net/forums/discussion/36595/change-the-row-color-based-on-column-data
[https://datatables.net/forums/discussion/62460/changing-row-color-at-rendering-time-based-on-column-values]
However, I can not get it to work.
My code is:
createdRow: function( row, data, dataIndex){
//console.log('data[3]: ' + data[3]);
if( data[3] == '4'){
$(row).css("background-color", "red");
}
},
The console.log displays "data[3] is undefined".
I have tried:
if( data[3] === '4')
The full context is:
//Show DataTable
moment.updateLocale(moment.locale(), { invalidDate: "" })
if ( $.fn.dataTable.isDataTable( '#ymTable' ) ) {
var ymTable = $('#ymTable').DataTable();
}
else {
var ymTable = $('#ymTable').DataTable( {
createdRow: function( row, data, dataIndex){
// console.log('data[3]: ' + data[3]);
if( data[3] == '4'){
$(row).css("background-color", "red");
}
},
info: false,
dom: 'Bfrtip',
order: [[ 3, 'asc' ], [ 1, 'asc' ], [ 2, 'asc' ]],
// buttons: ['copy', 'csv', 'excel', 'pdf', 'print'],
buttons: [
{
extend: 'copy',
exportOptions: {
columns: [ 1, 2, 3, 4, 5, 6 ]
}
},
{
extend: 'csv',
exportOptions: {
columns: [ 1, 2, 3, 4, 5, 6 ]
}
},
{
extend: 'excel',
exportOptions: {
columns: [ 1, 2, 3, 4, 5, 6 ]
}
},
{
extend: 'pdf',
exportOptions: {
columns: [ 1, 2, 3, 4, 5, 6 ]
}
},
{
extend: 'print',
exportOptions: {
columns: [ 1, 2, 3, 4, 5, 6 ]
}
},
],
columns: [
{data: 'cdId',
visible: false,
searchable: false},
{data: 'surname',
defaultContent: ""},
{data: 'firstname',
defaultContent: ""},
{data: 'age',
defaultContent: ""},
{data: 'gender',
defaultContent: ""},
{data: 'paradePatrol',
defaultContent: ""},
{data: 'role',
defaultContent: ""},
{data: null,
className: "center",
render: function(data,type,row) {
if(data.sayId == null || data.sayId == undefined){
return ("<input type='checkbox' id=" + data.cdId + " name='update' onchange='ymActivityPatrolFunction(this)' style='zoom: 2.0;'>")
}else{
return ("<input type='checkbox' id=" + data.cdId + " name='update' onchange='ymActivityPatrolFunction(" + data.cdId + ", " + this.checked + ")' style='zoom: 2.0;' checked>");
}
},
},
],
columnDefs: [
{targets: 7, orderable: false},
],
});
}
I found the answer to be, to replace:
data[3] == '4'
with:
data.age == '4'
As in:
createdRow: function( row, data, dataIndex){
if( data.age == '4'){
$(row).css("background-color", "red");
}
},

Multiple filters / Filter inside filter - React Native

how can i do something like that in React-Native:
data = [
{id:1,title:'Action',games:[
{id:1,title:'Game1'},
{id:2,title:'Game2'},
{id:3,title:'Game3'},
]},
{id:2,title:'Horror',games:[
{id:1,title:'Game1'},
{id:2,title:'Game2'},
{id:3,title:'Game3'},
]},
]
Every time the query string is updated, look for the game within the category.
Returns only the categories that contain a game with the searched characters.
Thank you! :D
I don't know if I understand your question correctly. This is my solution.
If you query for "Game5" you will get whole object that contains query
const data = [
{
id: 1,
title: "Action",
games: [
{ id: 1, title: "Game1" },
{ id: 2, title: "Game2" },
{ id: 3, title: "Game3" },
],
},
{
id: 2,
title: "Horror",
games: [
{ id: 1, title: "Game4" },
{ id: 2, title: "Game5" },
{ id: 3, title: "Game6" },
],
},
];
const query = "Game5";
const result = data.find((category) =>
category.games.find((g) => g.title === query)
);
console.log(result);
You can use 'filter' instead of 'find' and result will be an array.
This is example of filter version. I add one more category so you can see how it filter
const data = [
{
id: 1,
title: "Action",
games: [
{ id: 1, title: "Game1" },
{ id: 2, title: "Game2" },
{ id: 3, title: "Game3" },
],
},
{
id: 2,
title: "Horror",
games: [
{ id: 1, title: "Game1" },
{ id: 2, title: "Game2" },
{ id: 3, title: "Game3" },
],
},
{
id: 3,
title: "Comedy",
games: [
{ id: 1, title: "Game5" },
{ id: 2, title: "Game6" },
{ id: 3, title: "Game7" },
],
},
];
const query = "Game2";
const result = data.filter((category) =>
category.games.find((g) => g.title === query)
);
console.log(result);
And you might want to look at life cycle componentDidUpdate if you write class component, but if you write function component you might want to use useEffect
This is official react hook explaination
EDIT: from your comment you might want something like this
const data = [
{
id: 1,
title: "Action",
games: [
{ id: 1, title: "Game1" },
{ id: 2, title: "Game2" },
{ id: 3, title: "Game3" },
],
},
{
id: 2,
title: "Horror",
games: [
{ id: 1, title: "Game1" },
{ id: 2, title: "Game2" },
{ id: 3, title: "Game3" },
],
},
{
id: 3,
title: "Comedy",
games: [
{ id: 1, title: "Game5" },
{ id: 2, title: "Game6" },
{ id: 3, title: "Game7" },
],
},
];
const query = "Game5";
let result = null;
data.forEach((category) => {
const game = category.games.filter((g) => g.title === query);
if (game.length) result = { ...category, games: game };
});
console.log(result);

How to get single value from array in VueJs

Tell a beginner web delepoer how to get all title from all objects in array
this is my array
0: {id: 6, category_id: 2, title: "Test", brand: "Test", serial_number: "2165412315864",…}
1: {id: 7, category_id: 3, title: "Test2", brand: "Test2", serial_number: "2165412315864",…}
2: {id: 8, category_id: 5, title: "New", brand: "New", serial_number: "2165412315864",…}
3: {id: 9, category_id: 1, title: "New2", brand: "New2", serial_number: "2165412315864",…}
Im try to use this code
categories: {
handler(categories) {
console.log('categories: ', categories[title]); //Debug
},
deep: true
}
If you want an array with just the titles you can use Array.map and pick the parts your interested in:
const arr = [{
id: 6,
category_id: 2,
title: "Test",
brand: "Test",
serial_number: "2165412315864"
},
{
id: 7,
category_id: 3,
title: "Test2",
brand: "Test2",
serial_number: "2165412315864"
},
{
id: 8,
category_id: 5,
title: "New",
brand: "New",
serial_number: "2165412315864"
},
{
id: 9,
category_id: 1,
title: "New2",
brand: "New2",
serial_number: "2165412315864"
}
];
const titles = arr.map(({ title }) => title);
console.log(titles);
The categories variable is actually an array here, so you can not use
categories['title']
// Or,
categories.title
here. To get all title property for each category inside the categories array you can use array .map() method like:
categories: {
handler(categories) {
const arr = categories.map(c => c.title)
console.log('titles: ', arr); //Debug
},
deep: true
}

How to configure the datasource for the Kendo Treeview?

This should be an easy one but I'm missing something. I have an MVC application that returns JSON data using this controller method:
public ActionResult GetVenues()
{
ActionResult ar = Json(_VenueRepository.GetData(), JsonRequestBehavior.AllowGet);
return ar;
}
Nothing fancy here. I'm displaying a Kendo treeview on my view using the following code:
var venuetree = function () {
$("#venuetreeview").kendoTreeView({
checkboxes: {
checkChildren: true
},
dataSource: [{ id: 0, text: "Venues", items: [{ id: 1, text: "Venue 1", items: [{ id: 5, text: "Venue 2" }] }, { id: 2, text: "Venue 3", items: [{ id: 14, text: "Venue 4" }] }, { id: 3, text: "Venue 5", items: [{ id: 38, text: "Venue 6" }, { id: 39, text: "Venue 7" }, { id: 25, text: "Venue 8" }, { id: 26, text: "Venue 9" }, { id: 27, text: "Venue 10" }, { id: 28, text: "Venue 11" }] }, { id: 30, text: "Venue 12" }, { id: 40, text: "Venue 13", items: [{ id: 41, text: "Venue 14" }] }, { id: 4, text: "Venue 15", items: [{ id: 29, text: "Venue 16" }] }, { id: 31, text: "Venue 17" }, { id: 32, text: "Venue 18" }] }]
//dataSource: new kendo.data.HierarchicalDataSource({
// transport: {
// read: {
// url: "DataManager/GetVenues",
// dataType: "json",
// contentType: "application/json"
// }
// },
// pageSize: 100,
// requestEnd: function (e) {
// $("#wait").hide();
// },
//})
}).data("kendoTreeView");
};
The hard-coded JSON here renders just fine. I obtained this JSON directly from the ActionResult object in the controller method.
However, when I uncomment the code that returns the HierarchicalDataSource (while commenting out the hard-coded version, of course) The treeview displays a Loading message with a wait animation. Note: same problem using DataSource as HierarchicalDataSource.
Any ideas why its acting this way?
Thanks
Carl
i use this
var dataSource = new kendo.data.HierarchicalDataSource({
transport: {
read: {
url: foo,
datatype: "json",
contentType: "application/json"
}
},
schema: {
model: {
children: "items",
id: "id"
},
data: function(data) {
var dataArray = eval(data);
return dataArray;
}
}
});
I think eval(data) is the solution.
I tried many things and after using eval it works :)