I have a simple question, I have dummy data about some products and I need to take all categories into the new list. How can I do it?
class Products with ChangeNotifier {
List<Product> _productItems = [
Product(
id: 'p1',
title: 'Red Shirt',
price: 29.99,
category: 'shirts',
),
Product(
id: 'p2',
title: 'Trousers',
description: 'A nice pair of trousers.',
price: 59.99,
category: 'Trousers',
),
Product(
id: 'p3',
title: 'Yellow Scarf',
price: 19.99,
category: 'Scarfs',
),
Product(
id: 'p4',
title: 'A Pan',
price: 49.99,
category: 'Pans',),];
List<Product> get items {
return [...items];
}
List<Product> get fovoriteItems {
return _productItems.where((prodItem) => prodItem.isFavorite!).toList();
}
List<Product> get stockItems {
return _productItems.where((prodItems) => prodItems.isStock!).toList();
}
List<Product> get categoriesList {}
}
I need to take a List like categories = [Shirts,Trousers,Scarfs,Pans];
Your problem isn't clear but there are notable issues in your code. You firstly need to update your items method to return all the products. So update it to something like this:
List<Product> get items {
return _productItems;
}
Then in the get favoriteItems method, you have not defined the isFavorite property in any of the dummy classes. So update them to include it. This also goes for your get stockItems method. Here's an example:
Product(
id: 'p9',
title: 'Apples',
description: 'A delicious red treat',
price: 1.99,
category: 'Food',
isFavorite: false,
isStock: true,
),
Also make sure to remove the ! from prodItem.isFavorite! and prodItems.isStock! because this will give the opposite result.
The categoriesList method should be of type String because a category isn't necessarily product. Here's the implementation:
List<String> get categories {
List<String> ctgrs = [];
for (item in _productItems) {
ctgrs.add(item.category);
}
return ctgrs;
}
I would also highly recommend using UniqueKey() or using the UUID package for every product's id so you don't have to make a custom one for every product. Using UUID is very secure as well.
List<String> categories = [];
_productItems.forEach((element) {
if (categories.indexOf(element.category) < 0) {//avoid duplicates
categories.add(element.category);
}
});
Related
What I am trying to do
I have a type of Category and a type of Product. I want to be able to filter the products, by the category. For example, I want to be able to see only the products that are of Category "Mixed Drink". When in Apollo Studio I am unable to do this.
What I tried
This is in my TypeDef file
type Category {
id:ID
name: String
product: [Product]
},
type Product {
id: ID
name: String
description: String
ingredients: [String]
moveActive: Boolean
price: Float
category: [Category]
},
input productsByCategoryFilter {
id: ID
name: String
description: String
ingredients: [String]
moveActive: Boolean
price: Float
}
type Query {
productsByCategory(category: productsByCategoryFilter): [Product]
},
What I thought this would do is create an input field that I could put as an argument to get back an array of all the products. However, this isn't working.
Here is my resolver function for this.
productsByCategory:(_parent:any, {category}, context: Context) => {
return context.prisma.product.findMany({
where: {
category
}
})
}
Any information would be helpful!
I am using AWS AppSync GraphQL and am trying to filter a list by a nested object's value.
My schema looks like this:
type Post #model {
id: ID
title: String
content: String
hidden: Boolean
}
type PinnedPost #model
{
id: ID!
userID: ID #index(name: "byUser", sortKeyFields: ["postID"])
user: User #hasOne (fields: ["userID"])
postID: ID
post: Post #hasOne (fields: ["postID"])
}
I would like to run a query to list the PinnedPost for a user, but filter out the hidden ones, like so:
const pinnedData = await API.graphql(graphqlOperation(
listPinnedPosts, {
filter: {
userID: {
eq: userInfo.attributes.sub
},
post: {
hidden: {
eq: false
},
}
}
}
))
I have updated the filterinput in my Schema through the AppSync Console to:
input ModelPinnedPostFilterInput {
id: ModelIDInput
userID: ModelIDInput
postID: ModelIDInput
post: ModelPostFilterInput
and: [ModelPinnedPostFilterInput]
or: [ModelPinnedPostFilterInput]
not: ModelPinnedPostFilterInput
}
There are no errors associated with it, but the nested filter is not being applied as it will return both true and false values for hidden.
This question was sort of answered before:
Appsync & GraphQL: how to filter a list by nested value
but it is not clear to me where I am supposed to edit the mapping template to allow this. How can I achieve this result?
I would like to create a dropdown or a list of all free FontAwesomeIcons to allow the user choose the one he/she like more. Also if You write something, the list have to filter the icons(that´s optional).
List<IconData> fontAwesomeIcons = [FontAwesomeIcons.accessibleIcon,FontAwesomeIcons.americanSignLanguageInterpreting,FontAwesomeIcons.assistiveListeningSystems,FontAwesomeIcons.audioDescription,];
You can do the following:
DropdownButton<IconData>(
value: dropdownValue,
onChanged: (IconDatanewValue) {
setState(() {
dropdownValue = newValue;
});
},
items: <IconData>[FontAwesomeIcons.accessibleIcon,FontAwesomeIcons.americanSignLanguageInterpreting,FontAwesomeIcons.assistiveListeningSystems,FontAwesomeIcons.audioDescription]
.map<DropdownMenuItem<IconData>>((IconData value) {
return DropdownMenuItem<IconData>(
value: value,
child: Text(value),
);
})
.toList(),
),
The DropdownMenuItem is a class used to represent the items.
onChanged is called when the user selects an item.
Check the docs for more information:
https://api.flutter.dev/flutter/material/DropdownButton-class.html
I am using the following Xtemplate to filter out items by category (see view/panel in which it is "housed" below):
itemTpl: new Ext.XTemplate(
'<tpl for=".">',
'<tpl if="category === \'vegetable\'">',
'{str}',
'</tpl>',
'</tpl>'),
and it is filtering as expected (well, at least partially).
I have the following store:
Ext.define("Produce.store.List", {
extend: 'Ext.data.Store',
alias: 'store.List',
config: {
model: 'Produce.model.Food',
sorters: 'category',
grouper: function(record) {
return record.get('category')[0];
},
data: [
{ category: 'fruit', str: 'tomato'},
{ category: 'fruit', str: 'green bean'},
{ category: 'vegetable', str: 'celery'},
{ category: 'vegetable', str: 'sprouts'},
{ category: 'fruit', str: 'squash'},
{ category: 'fruit', str: 'snap peas'},
{ category: 'vegetable', str: 'rhubarb'},
{ category: 'vegetable', str: 'cabbage'}
]
}
});
The Xtemplate is rendered in the following view/panel:
Ext.define('Produce.view.Vegetable', {
extend: 'Ext.tab.Panel',
requires: ['Produce.model.Food'],
config: {
tabBar: {
docked: 'top',
ui: 'neutral',
layout: {
pack: 'center'
}
},
items: [{
title: 'Produce',
layout: Ext.os.deviceType == 'Phone' ? 'fit' : {
type: 'vbox',
align: 'center',
pack: 'center'
},
cls: 'demo-list',
items: [{
width: Ext.os.deviceType == 'Phone' ? null : 300,
height: Ext.os.deviceType == 'Phone' ? null : 500,
xtype: 'list',
store: 'List',
itemTpl: new Ext.XTemplate(
'<tpl for=".">',
'<tpl if="category === \'vegetable\'">',
'{str}',
'</tpl>',
'</tpl>'),
variableHeights: false
}]
}
});
When I run this only the vegetables in the store are displayed in the panel- which is great - but blank rows are also displayed where the fruit items were filtered out in the rendered list - which is not great. (Similarly, in my "fruit" view, fruit are displayed as desired, but where there were vegetables, blanks rows show up).
How can I get rid of these blank rows (this is an issue, since the fruits and vegetables in my list are just to get the app working, and are a fill-in to represent a much larger number of records that will be categorized for my actual app). I tried using Ext.IsEmpty and filtering by null, but neither of these did the trick.
The View is working well: it shows a row for each record. You should try to add a filtered store to the list.
Take a look at Ext.util.Filter in the Sencha Touch documentation.
This will solve your problem!
I'm trying to use the Knockout Concurrency plugin in my project, and I'm currently fiddling with the example code, but I'm not getting it to work:
https://github.com/AndersMalmgren/Knockout.Concurrency/wiki/Getting-started
ViewModel = function() {
this.name = ko.observable("John").extend({ concurrency: true});
this.children = [{ name: ko.observable("Jane").extend({concurrency: true })}, { name: ko.observable("Bruce").extend({concurrency: true })}];
this.getData = function() {
//Simulate backend data
var data = { name: "John Doe", children: [{ name: "Jane Doe"},{ name: "Bruce Wayne"}, { name: "New row"}]};
new ko.concurrency.Runner().run(this, data);
}
}
ko.applyBindings(new ViewModel());
http://jsfiddle.net/rCVk4/3/
Nothing happens and the newly added item is not tracked by the plugin, does anyone know why?
Thanks for trying out my Plugin, really fast too, I uploaded the code today!
The plugin does indeed support tracking of deleted and added rows. But for it to know which rows are what It needs you to supply it with a mapper
var mappings = {
children: {
key: function(item) {
return ko.utils.unwrapObservable(item.id);
},
create: function(data) {
return { id: data.id, name: data.name };
}
}
};
The name children corresponds to the name of the array.
The Key method is used to identify the property used as an identifier.
The Create method is used to create new rows (Added rows).
You can download the MVC3 sample from Github for a fully featured Demo, also please try out this Fiddle
http://jsfiddle.net/7atZT/