This question already has answers here:
Group By Multiple Columns
(14 answers)
Closed 1 year ago.
I have 2 tables: OrderDetail and Product. I try to groupby IdProduct in OrderDetail table and retrieve ( Name in Product table, Quantity in OrderDetail). But I can't get the Name, only the key.
public ActionResult GetData()
{
DbCon db = new DbCon();
var query = db.OrderDetail.Include("Product")
.GroupBy(p => p.Product_Id)
.Select(g => new { name = g.Key ,count = g.Sum(w => w.Quanity) }).ToList();
return Json(query, JsonRequestBehavior.AllowGet);
}
//code highcharts
<script>
$(document).ready(function () {
$.getJSON("/Admin/Product/GetData", function (data) {
var Names = []
var Qts = []
for (var i = 0; i < data.length; i++) {
Names.push(data[i].name);
Qts.push(data[i].count);
}
Highcharts.chart('container', {
chart: {
type: 'line'
},
title: {
text: 'Thống kê các mặt hàng bán ra'
},
subtitle: {
text: ''
},
xAxis: {
categories: Names
},
yAxis: {
title: {
text: 'Số lượng bán ra'
}
},
plotOptions: {
line: {
dataLabels: {
enabled: true
},
enableMouseTracking: false
}
},
series: [{
name: 'Số lượng bán ra',
data: Qts
}]
});
});
});
</script>
Result:
enter image description here
To get the Product Name, you can apply GroupBy with Product_Id and ProductName as your Key.
The reason why GroupBy with Product_Id and ProductName but not ProductName as:
Id is a unique identifier.
Possible that Product Name will be duplicated in different products and leads to inaccurate calculation.
Next, retrieve the Product Name from Key.
var query = db.OrderDetail.Include("Product")
.GroupBy(p => new { p.Product_Id, ProductName = p.Name })
.Select(g => new {
name = g.Key.ProductName,
count = g.Sum(w => w.Quanity)
}).ToList();
Related
I have the most basic explicit Many-to-Many relation:
model Category {
id Int #id #default(autoincrement())
title String #db.VarChar(24)
posts PostCategory[]
}
model Post {
id Int #id #default(autoincrement())
title String #db.VarChar(24)
categories PostCategory[]
}
model PostCategory {
category Category #relation(fields: [categoryId], references: [id])
categoryId Int
post Post #relation(fields: [postId], references: [id])
postId Int
##id([categoryId, postId])
##unique([categoryId, postId])
}
What I now try to accomplish is to create a new Post with n categories.
So lets say we have an String array with n amount of category titles:
const myStringArray = ["Category1", "Category2", "Category3", ...];
How can I create one query that adds all of them to my new created post?
If I put it in static it is not a problem, but how can I handle a list where I don't know the size?
const assignCategories = await prisma.post.create({
data: {
title: 'First Post Title',
categories: {
create: [
{
category: {
create: {
name: myStringArray[0],
},
},
},
{
category: {
create: {
name: myStringArray[1],
},
},
},
],
},
},
})
You can use Array.map() to map each string element into an object of the required shape
const myStringArray = ['Category1', 'Category2', 'Category3'];
const assignCategories = await prisma.post.create({
data: {
title: 'First Post Title',
categories: {
create: myStringArray.map((title) => ({
category: { create: { title } },
})),
},
},
});
Array.map() docs:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map
In my Vue.js project I have an array of objects which I want to list through and display in the browser.
My array contains four objects, I want to display only 3. The way I choose the 3 objects are dependent on a preference setting that the user has chosen somewhere else in the project and stored in a variable (below it is called userPreference). I am currently stuck on the best and most efficient way to remove one of the objects from my array based on the userPreference value.
My v-for in my template
<ul v-for="item in getOutroItems"><li>item<li></ul>
My object:
data() {
return {
outroItems: [{ title: "outro1", text: "XYZ" }, { title: "outro2", text: "ABC" }, { title: "outro3",
text`enter code here`: "QRS" }, { title: "outro4", text: "TUV" }],
userPreference: ""
};
}
My computed property (this is what I have so far)
getOutroItems() {
this.outroItems.filter((value) => {
if(this.userPreference === "newsletter") {
/// here I want to remove outro2 from my array and return an array with the other 3 values
} else (this.userPreference === "noNewsletter") {
/// here I want to remove outro3 from my array and return an array with the other 3 values
}
})
}
So, what is the best way to remove a specific element from an array?
Thanks in advance, and let me know if anything wasn't clear enough.
Your requirement can be fulfilled by below code as array.filter just wants true or false in its return to accept or remove an element from its array.
getOutroItems() {
this.outroItems.filter((value) => {
if(this.userPreference === "newsletter") {
// here I want to remove outro2 from my array and return an array with the other 3 values
return value.title != 'outro2';
} else (this.userPreference === "noNewsletter") {
// here I want to remove outro3 from my array and return an array with the other 3 values
return value.title != 'outro3';
}
})
}
However if you want to not create another array if it is big. you should go with swapping such elements to be removed with the end indexed element in the array and popping those many elements from the array.
There are multiple ways of getting the correct items from an array.
My preferred method and in your example: Using array.filter
const outroItems = [
{ title: "outro1", text: "XYZ" },
{ title: "outro2", text: "ABC" },
{ title: "outro3", text: "QRS" },
{ title: "outro4", text: "TUV" }
];
const leftOverItems = outroItems.filter((item) => item.title !== "outro2");
console.log(leftOverItems);
Another option is to find the index of the item to remove and then remove it with splice
const outroItems = [
{ title: "outro1", text: "XYZ" },
{ title: "outro2", text: "ABC" },
{ title: "outro3", text: "QRS" },
{ title: "outro4", text: "TUV" }
];
const itemToDelete = outroItems.find((item) => item.title === "outro2");
const indexToDelete = outroItems.indexOf(itemToDelete);
outroItems.splice(indexToDelete, 1);
console.log(outroItems);
Combining any of the functions above with a function will prevent you from writing duplicate code.
const itemToRemove = (arr, attr, name) => {
return arr.filter((item) => item[attr] !== name);
}
const outroItems = [
{ title: "outro1", text: "XYZ" },
{ title: "outro2", text: "ABC" },
{ title: "outro3", text: "QRS" },
{ title: "outro4", text: "TUV" }
];
// Remove from "outroItems" where "title" is "outro2"
const removed2 = itemToRemove(outroItems, "title", "outro2");
// Remove from "outroItems" where "title" is "outro3"
const removed3 = itemToRemove(outroItems, "title", "outro3");
// Remove from "outroItems" where "text" is "TUV"
const removedTUV = itemToRemove(outroItems, "text", "TUV");
console.log(removed2);
console.log(removed3);
console.log(removedTUV);
This is suppose to look at the users category selection and then update the subcategory. The solution was recommended by someone else but I can't seem to get it to work. When I select the category, subcategory doesn't update. Can someone let me know what I'm missing.
Path: category.js
<template name="category">
{{#autoForm collection="Meteor.users" id="categoryForm" doc=currentUser type="update"}}
{{> afQuickField name='profile.categories'}}
{{/autoForm}}
</template>
Path: Schema.js
var fruitArr = ['apple', 'banana'];
var vegetablesArr = ['carrot', 'broccoli'];
Schema.Category = new SimpleSchema({
category: {
type: String,
label: "Category",
allowedValues: ['fruit', 'vegetables']
},
subcategory: {
type: String,
label: "Subcategory",
allowedValues: _.union(fruitArr, vegetablesArr),
autoform: {
options: function () {
let category = AutoForm.getFieldValue("category");
if (!category) return [{label: "Please select a category first", value: ""}];
if (category === "fruit") return _.map(fruitArr, (v, i) => ({
label: "Fruit " + (i + 1) + ": " + v,
value: v
}));
else return _.map(vegetablesArr, (v, i) => ({label: "Vegetables " + (i + 1) + ": " + v, value: v}));
}
}
}
});
Schema.UserProfile = new SimpleSchema({
categories: {
type: Schema.Category,
optional: true,
}
});
When calling AutoForm.getFormValues('categoryForm'); in the browser's console log, the following result will be returned:
{
"insertDoc":{
"profile":{
"categories":{
"category":"fruit"
}
}
},
"updateDoc":{
"$set":{
"profile.categories.category":"fruit"
},
"$unset":{
"profile.categories.subcategory":""
}
}
}
As you can see from above, the schema field subcategory is referenced as profile.categories.subcategory. Therefore, the field subcategory won't be updated because AutoForm.getFieldValue("category"); returns undefined.
You can fix this error by changing
let category = AutoForm.getFieldValue("category");
to
let category = AutoForm.getFieldValue("profile.categories.category");
inside your options function in the subcategory schema field.
Is it possible to show data in table from two stores (merge them) without creating third store?
Example:
var store1 = {
data: [{
name: 'Joe'
}, {
name: 'Jane'
}, {
name: 'Kate'
}]
};
var store2 = {
data: [{
name: 'John'
}, {
name: 'Richard Roe'
}]
};
var grid = {
store: [store1, store2]
}
If both stores' models are same, why don't you merge stores' data ? then load merged data into store1. Like that: https://fiddle.sencha.com/#fiddle/tjh
var mergedData = Ext.Array.union(store1.getRange(),(store2.getRange());
store1.loadData(mergedData);
grid.setStore(store1);
// to provide unique
store1.on('datachanged', function(store) {
var checkArray = [];
Ext.each(store.getRange(), function(record) {
var userName = record.get('name');
if (checkArray.indexOf(userName) > -1) {
store.remove(record);
}
checkArray.push(userName);
});
});
I have a ul containing li's which contain names of different recipe ingredients for a recipe page. I'm trying to get those ingredients and store them into a JavaScript array within an object. I already know the title of the recipe so I put that right into the object property title, but I don't know how many ingredients there will be for each recipe. Here is what I have:
var recipeobj = {
title: $('h3.title').val(),
ingredients: [
ingredient,
optional
]
}
$.each($('ul.ingredients > li > h4'), function (index, ingredient) {
recipeobj.ingredients[index].ingredient = $(ingredient).html();
recipeobj.ingredients[index].optional = false;
})
If I try to do console.log(recipeobj.ingredients) I just get the error Uncaught ReferenceError: ingredient is not defined
No doubt this is simple, I just rarely need to use arrays in JavaScript so have little experience with them.
Open your console and run it
var recipeobj = {
title: $('h3.title').html(),
// ingredients is empty for now
ingredients: []
};
$.each($('ul.ingredients > li > h4'), function(index, ingredient) {
// Get the name
var name = $(ingredient).html(),
// Find out if it is 'optional'(using a class here)
optional = $(ingredient).hasClass('optional');
// Push a new ingredient into the array
recipeobj.ingredients.push({ name: name, optional: optional });
});
console.log(recipeobj);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h3 class="title">Pork and beans</h3>
<ul class="ingredients">
<li>
<h4>Pork</h4>
</li>
<li>
<h4>Beans</h4>
</li>
<li>
<h4 class="optional">Salt*</h4>
</li>
</ul>
This should output:
{
"title": "Pork and beans",
"ingredients": [
{ name : "Pork", optional : false },
{ name : "Beans", optional : false },
{ name : "Salt*", optional : true}
]
}
var rObj = {
title: $('h3.title').val(),
ingredients: [
'source cream',
'cheese',
'chopped meat'
],
optional: true
};
accessing
var rItem = rObj.ingredients[1];
or you want
var rObj = {
title: $('h3.title').val(),
ingredients: {
ingredient_list: ['one','two','three'],
optional: true
}
};
accessing
var rItem = rObj.ingredients.ingredient_list[1];
The structure you are attempting to use looks like the structure should be like
var rObj = {
title: $('h3.title').val(),
things: [{
ingredient: 'source cream',
optional: true
},
{
ingredient: 'cheese',
optional: false
}]
};
accessing
var ingred = rObj.things[1].ingredient;
var rObj = {
title: $('h3.title').val(),
ingredients : []
};
you can add ingredients:
$.each($('ul.ingredients > li > h4'), function (index, ingredient) {
rObj.ingredients.push({ingredient: $(ingredient).html(), optional :false})
})