I am trying to create a Flutter portfolio sorted by "categories" with flat buttons. When one click on the categories, the related projects will be filtered and displayed accordingly, in descending order based on the timestamp.
I have succeeded in displaying the projects in descending order, however have been unable to display my projects by the key value.
Code for the "categories" flat buttons:
class PortfolioCategories extends StatefulWidget {
@override
_PortfolioCategoriesState createState() => new _PortfolioCategoriesState();
}
class _PortfolioCategoriesState extends State<PortfolioCategories> {
void _select(CategoryChoice category) {
setState(() {
PortfolioRow.itemBuilder(context, category.categoryIndex);
});
}
class CategoryChoice {
const CategoryChoice({this.category, this.categoryIndex});
final String category;
final String categoryIndex; //value of 'category' key in Firebase
}
const List<CategoryChoice> categories = const <CategoryChoice>[
const CategoryChoice(category: 'ALL', categoryIndex: 'Category_ALL'),
const CategoryChoice(
category: 'MULTIMEDIA DESIGN', categoryIndex: 'Category_1'),
const CategoryChoice(category: 'CURATORIAL', categoryIndex: 'Category_2'),
const CategoryChoice(category: 'ART', categoryIndex: 'Category_3'),
];
Code for my portfolio:
class PortfolioRow extends StatelessWidget {
const PortfolioRow({Key key, this.category}) : super(key: key);
final CategoryChoice category;
@override
Widget build(BuildContext context) {
return StreamBuilder(
stream: Firestore.instance
.collection('portfolio')
.orderBy('createdAt', descending: true)
.snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) return Text("Loading...");
return GridView.builder(
physics: ScrollPhysics(),
shrinkWrap: true,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
),
itemCount: snapshot.data.documents.length,
itemBuilder: (context, index) =>
portfolioContainer(context, snapshot.data.documents[index])); //portfolioContainer is the portfolio projects that will be displayed
},
);
}
}
My question could be answered by this: how to use where with orderby in flutter
And then with:
.where('category', arrayContainsAny:[category.categoryName]) .orderBy('createdAt', descending: true)
Regarding the query, I was silly to have tried to allow variables query from different classes. I succeed to query request from FlatButton to portfolioRow()
when all the code were all appended as a child in _portfolioCategoriesState()
as below:
class PortfolioCategoriesAndDisplay extends StatefulWidget {
@override
_PortfolioCategoriesAndDisplayState createState() =>
new _PortfolioCategoriesAndDisplayState();
}
String _showCat = 'All'; //default state is All
class CategoryChoice {
const CategoryChoice({this.category, this.categoryName});
final String category;
final String categoryName; //'category.[Name]' in Firebase
@override
String toString() {
return 'category: $category categoryName: $categoryName';
}
}
const List<CategoryChoice> categories = const <CategoryChoice>[
const CategoryChoice(categoryName: 'All'),
const CategoryChoice(categoryName: 'Multimedia Design'),
const CategoryChoice(categoryName: 'Curatorial'),
const CategoryChoice(categoryName: 'Sustainability'),
];
class _PortfolioCategoriesAndDisplayState
extends State<PortfolioCategoriesAndDisplay> {
void _select(String newCategory) {
setState(() {
_showCat = newCategory;
});
}
Widget build(BuildContext context) {
return Container(
child: Row(
children: [
Expanded(
child:
Column(children: [
Container(
child:
Row(children: [
FlatButton(
onPressed: () {
_select(categories[0].categoryName);
},
child: Text(
'ALL',
)),
FlatButton(
onPressed: () {
_select(categories[1].categoryName);
},
child: Text(
'MULTIMEDIA DESIGN',
)),
FlatButton(
onPressed: () {
_select(categories[2].categoryName);
},
child: Text(
'CURATORIAL',
)),
FlatButton(
onPressed: () {
_select(categories[3].categoryName);
},
child: Text(
'SUSTAINABILITY',
)),
]),
),
StreamBuilder(
stream: Firestore.instance
.collection('portfolio')
.where('category', arrayContainsAny: [_showCat])
.orderBy('projectOrder', descending: true)
.snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) return Text("Loading...");
return GridView.builder(
physics: ScrollPhysics(),
shrinkWrap: true,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
crossAxisSpacing: 70.0,
mainAxisSpacing: 70.0,
childAspectRatio:
MediaQuery.of(context).size.height / 1280,
),
itemCount: snapshot.data.documents.length,
itemBuilder: (context, index) => portfolioContainer(
context, snapshot.data.documents[index]));
},
)
]),
)
],
));
}
}