Converting Map<String, Object> to List<Widget> in flutter, dart - flutter

I am using graphql-flutter in flutter
I think my query result is LazaCaheMap which is Map. You can look here
Then I need to use that map for GridView.
My code looks like this.
List playlists = result.data['playlists'];
return GridView.count(
crossAxisCount: 2,
mainAxisSpacing: 8,
crossAxisSpacing: 8,
padding: const EdgeInsets.all(8),
childAspectRatio: 1,
children: newPlaylist.map<Widget>((playlist) {
return ChannelCard(
playlistId: playlist['playlistId'],
playlistTitle: playlist['playlistTitle'],
thumbnailUrl: playlist['thumbnailUrl'],
description: playlist['description'],
);
}),
);
But as I expect, I got type 'MappedListIterable<Object, Widget>' is not a subtype of type 'List<Widget>' error.
How can I convert this type?

There is a toList() method for converting an Iterable to a List.
somelist.map((f)=>{}).toList();

Related

What is Tile in flutter_staggered_grid_view

I am trying to use AlignedGridView from flutter_staggered_grid_view as mentioned in their Docs -
AlignedGridView.count(
crossAxisCount: 4,
mainAxisSpacing: 4,
crossAxisSpacing: 4,
itemBuilder: (context, index) {
return Tile(
index: index,
extent: (index % 7 + 1) * 30,
);
},
);
What is Tile in this code? I Dont have any class or widget with that name that I can import here.
I get error - Error: The method 'Tile' isn't defined for the class
Tile used in example is from common file (you can make custom or common widgets so you can access it whenever you need)
you can find it here (line 31 to 75): https://github.com/letsar/flutter_staggered_grid_view/blob/master/examples/lib/common.dart

Flutter GridView ItemBuilder

I'm building a GridView based on data stored in a Hive box. The data stored in Hive has several objects to it and i need to get to some of that data in order to display it in a GridView.
I have a couple of issues with building the GridView, one i get an issue when first opening the page, where no data is loaded and then i get data after a few seconds, the other issue is that what i've written can't be correct as it just looks too badly written.
This is my code for the GridView builder;
Builder(builder: (context) {
return GridView.builder(
padding: EdgeInsets.zero,
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
crossAxisSpacing: 0,
mainAxisSpacing: 0,
childAspectRatio: 1,
),
shrinkWrap: true,
scrollDirection: Axis.vertical,
itemCount: posList?.length,
itemBuilder:
(context, posIndex) {
PointOfServices? pos = posList
?.elementAt(posIndex);
List<List<Orders>?> ordering = posList!.map((e) => e.orders).toList();
List<Orders>? ordering2 =ordering.elementAt(posIndex);
Orders? ordering3 = ordering2?.elementAt(0);
As you'll see there are several Lists etc to eventually get me to the data i require, it's just not best practice at all, i'm new to Flutter etc :)
This is how i get the data for the posList;
void getPosData() async {
final posData = _orderInfo?.values
.where((posDataMap) =>
posDataMap.deliveryAddressNo == deliveryAddressNo)
.toList();
posDataMap = posData?.asMap();
var posList1 = posDataMap?.values.first.pointOfServices?.toList();
posList = posList1
?.where((element) =>
element.pointOfServiceOrderingGroupNo == posGroupId)
.toList();
}
_orderInfo being my Hive Box data. Data is brought in to the app via an API and stored to my Hive Box.
Do i need to wait for my data to build first before loading the page? Any pointers and feedback would be great.
Thanks

Flutter getx loading data continuously causing UI to be unstable about which data to show

I'm trying to load data from my database using Getx in flutter. I have a list of categories containing a list of sub-categories, and each sub-category has a list of products inside of it. The problem is that the UI of the sub-categories page keeps getting confused which list of data to show, since I'm calling data by category_id. Something that made my app UI unstable and always changing data.
Here is my code for the sub-categories page:
GetBuilder<SubCategoriesController>(builder: (subCategories) {
Get.find<SubCategoriesController>()
.getSubCategories(widget.catId);
print(Get.find<SubCategoriesController>()
.getSubCategories(widget.catId));
return GridView.count(
crossAxisCount: 2,
shrinkWrap: true,
physics: ScrollPhysics(),
mainAxisSpacing: 16,
crossAxisSpacing: 16,
childAspectRatio: 90 / 100,
padding: EdgeInsets.all(16),
children: List.generate(subCategories.subCategoriesList.length,
(index) {
return _buildSingleSubCategory(
index,
SubCategoryModel.fromJson(
subCategories.subCategoriesList[index]));
}),
);
})
I tried to print the output of
Get.find<SubCategoriesController>()
.getSubCategories(widget.catId)
and I figured out that it keeps running continuously without stopping showing: Instance of 'Future<void>'
, and each time it shows data of a specific category, which is pretty weird!
Edit:
Future<void> getSubCategories(int cat_id) async {
Response response = await subCategoriesRepo.getSubCategoriesList(cat_id);
//print(response.body);
if (response.statusCode == 200) {
_subCategoriesList = [];
_subCategoriesList.addAll(response.body);
_isLoaded = true;
update(); // = setState();
}
}
I found out that the update() function called in here is making the issue, but once I remove it I get no data at all.
I think the problem is you are trying to call your getSubCategories(widget.catId) from your builder method.
You can try resolving this issue by calling your getSubCategories(widget.catId) from initstate instead of in builder method like this:
GetBuilder<SubCategoriesController>(
initState: (logic) => logic.getSubCategories(widget.catId),
builder: (subCategories) {
return GridView.count(
crossAxisCount: 2,
shrinkWrap: true,
physics: ScrollPhysics(),
mainAxisSpacing: 16,
crossAxisSpacing: 16,
childAspectRatio: 90 / 100,
padding: EdgeInsets.all(16),
children: List.generate(subCategories.subCategoriesList.length,
(index) {
return _buildSingleSubCategory(
index,
SubCategoryModel.fromJson(
subCategories.subCategoriesList[index]));
}),
);
},
)

why the GridView.custom did not rerender in flutter

I am uisng GridView.custom to render four Grid in the sreen in flutter(v3.0.4), this is the core render dart code look like:
Widget buildGridView(List<TodoTask> renderTasks) {
return GridView.custom(
semanticChildCount: 2,
cacheExtent: 4,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
mainAxisSpacing: 3.0,
crossAxisSpacing: 3.0,
crossAxisCount: 2,
childAspectRatio: childAspectRatio.value,
),
childrenDelegate: SliverChildBuilderDelegate((BuildContext context, int index) {
List<TodoTask> itemsBuild = renderTasks.where((element) => element.priority == index + 1).toList();
return buildListViewItemWidget(index, itemsBuild);
}, childCount: 4),
);
}
the render function will be invoke 2 times, fisrt the page initial render, the tasks size are 0. The next time when the async request fetched the tasks from server side, invoke this function to rerender the widget. To my surprise, the second time execute but did not trigger the GridView.custom rerender. why did this happen? Am I missing something? what should I do to let the GridView.custom rerender after fetched data from server side? I set the breakpoint in childrenDelegate code block, the sencond invoke enter the buildGridView function but did not trigger the breakpoint in childrenDelegate. I have tried like this:
Widget buildGridView(List<TodoTask> renderTasks) {
if (renderTasks.isEmpty) {
return Text("Loading....");
}
return GridView.custom(
semanticChildCount: 2,
cacheExtent: 4,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
mainAxisSpacing: 3.0,
crossAxisSpacing: 3.0,
crossAxisCount: 2,
childAspectRatio: childAspectRatio.value,
),
childrenDelegate: SliverChildBuilderDelegate((BuildContext context, int index) {
List<TodoTask> itemsBuild = renderTasks.where((element) => element.priority == index + 1).toList();
return buildListViewItemWidget(index, itemsBuild);
}, childCount: 4),
);
}
when the renderTasks is null, render the loading..., seems still did not enter the childrenDelegate.
BTW:seems like the controller did not contains buildContext. I am put this code in the get get: ^4.3.8 controller code.
Sliverchildbuilderdelegate will build it lazily. Maybe thats the reason. Its not build till it needs to be displayed. Try other delegates like sliverchildlistdelegate

Flutter GridView "type 'List<Widget> is not a subtype of type Widget"

it feels like I am doing something out of the ordinary!
I have 2 sub collections (subColl1 and subColl2) within 1 Collection in firebase firestore.
I get access to them with CollectionGroup
children: [
FutureBuilder<List<dynamic>>(
//<QuerySnapshot>(
future: Future.wait([
FirebaseFirestore.instance.collectionGroup('subColl1').get(),
FirebaseFirestore.instance.collectionGroup('subColl2').get(),
]),
Now I want to display both collections into a GridView.count() here:
return GridView.count(
restorationId: 'dashboardGridView',
crossAxisCount: 2,
mainAxisSpacing: 8,
crossAxisSpacing: 8,
padding: const EdgeInsets.all(8),
childAspectRatio: 1,
children: <Widget>[
snapshot.data[0].docs.map<Widget>((document) {
return _DashboardGridViewItem(
document: document,
);
}).toList(),
snapshot.data[1].docs.map<Widget>((document) {
return _DashboardGridViewItem(
document: document,
);
}).toList(),
],
);
I tried individually snapshot.data[0].... and snapshot.data[1].... and they worked. But doing it like the above (which is both at the same time) throws an error type 'List<Widget>' is not a subtype of type 'Widget'
I understand the error but there must be a way to display both collections in the same gridview...
you will notice that I pass a document to a private method _DashboardGridViewItem(document: document), which is used to display information from the document. The other way I was thinking is to use a for loop surrounding the gridview and use the index i inside the snapshot.data[i]..... but then am I not returning 2 Gridviews???
need direction..
It is expecting a [Widget, Widget, Widget ..], you are instead giving [[Widgets], [Widgets]]
Simplest way to solve is to use the spread operator '...' as in below:
children: <Widget>[
...snapshot.data[0].docs.map<Widget>((document) {
return _DashboardGridViewItem(
document: document,
);
}).toList(),
...snapshot.data[1].docs.map<Widget>((document) {
return _DashboardGridViewItem(
document: document,
);
}).toList(),
],