I have a list of several points of service in a List.
Within the PointsOfServices there is another object named Orders. How do i go about getting access to the Orders object to use it's data alongside the PointsOfService data?
Thanks
Edit: I want to be able to use this data to produce a GridView that will enable me to display both data from PointOfServices and Orders.
Will i be able to use a Future for this and FutureBuilder when creating the GridView?
You can directly access it using the index
print(mainList[0].orders[0].id);
Will print the first pointOfService's first order's Id
Note: here mainList is the name of the list that contains all pointOfService and i assumed that you have id in each order
Your question isn't clear as of what you want to exactly achieve, but to access list inside list , you can refer this ,
class PointOfService {
final String name;
final List<Order> orders;
PointOfService({this.name, this.orders});
}
class Order {
final String name;
Order({this.name});
}
void main() {
List<PointOfService> pointofServices = [
PointOfService(
name: "PointOfService 1",
orders: [
Order(name: "Order 1"),
Order(name: "Order 2"),
]),
PointOfService(
name: "PointOfService 2",
orders: [
Order(name: "Order 3"),
Order(name: "Order 4"),
])
];
for (var pointOfService in pointofServices) {
print("PointOfService name: ${pointOfService.name}");
for (var order in pointOfService.orders) {
print("Order name: ${order.name}");
}
}
}
This will output
PointOfService name: PointOfService 1
Order name: Order 1
Order name: Order 2
PointOfService name: PointOfService 2
Order name: Order 3
Order name: Order 4
Edit
For GridView you can do something like:
FutureBuilder<List<PointOfService>>(
future: < Your future here >
builder: (context, snapshot) {
if (snapshot.hasData) {
return GridView.builder(
gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 200,
childAspectRatio: 3 / 2,
crossAxisSpacing: 20,
mainAxisSpacing: 20),
itemCount: snapshot.data.pointOfServices.length,
itemBuilder: (context, index) {
Order order = snapshot.data!.pointOfServices[index];
return Column(
children:[
Text(order['name']),// You can access this way
);
);
}),
} else {
return Text("No data");
}
},
)
Related
i'm trying to fetch a list of sub categories based on category id, for example:
Category A has 3 sub categories: A1 - A2 - A3
My backend works fine, I pass the category_id to the function and it returns me a list of sub categories having the category_id.
Since i'm new to getx, I tried passing the category_id as a route parameter but i'm not able to show the list of sub categories. In fact I didn't get how to pass the category_id while in the UI.
Here is my repo:
Future<Response> getSubCategoriesListByCategory(int categ_id) async {
return await apiClient.getData('shop/category/$categ_id');
}
Here is my controller:
List<dynamic> _subCategoriesListByCategory = [];
List<dynamic> get subCategoriesListByCategory => _subCategoriesListByCategory;
bool _isLoaded = false;
bool get isLoaded => _isLoaded;
Future<void> getSubCategoriesByCategoryId(int cat_id) async {
Response response =
await subCategoriesRepo.getSubCategoriesListByCategory(cat_id);
if (response.statusCode == 200) {
_subCategoriesListByCategory = [];
_subCategoriesListByCategory.addAll(response.body);
_isLoaded = true;
//print(categoriesList);
update(); // = setState();
} else {}
}
Here is my RouteHelper:
GetPage(
name: subCategory,
page: () {
var catId = Get.parameters['catId'];
return SubCategoriesPage(catId: int.parse(catId!));
},
transition: Transition.fadeIn),
And here is my UI:
GetBuilder<SubCategoriesController>(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.subCategoriesListByCategory.length, (index) {
return _buildSingleSubCategory(
index,
SubCategoryModel.fromJson(
subCategories.subCategoriesListByCategory[index]));
}),
);
})
Code from home page where i'm passing the category_id:
onTap: () {
Get.toNamed(RouteHelper.getSubCategory(category.id));
},
I'm able to print the clicked category's id in the subs page which means it's passed correctly, also i'm getting GOING TO ROUTE /sub-category?catId=3
Noting that i'm priting the specific category_id correctly in the sub categories page, I couldn't fetch the specific data related to them. Any suggestion on how to solve this?
I'm not sure if this helps you since I haven't seen your full code, but I'm guessing you want to add this as parameter to your GetBuilder
initState: (state) => state.controller?.getSubCategoriesByCategoryId(widget.cat_id),
Solved it by adding: Get.find<SubCategoriesController().getSubCategories(widget.catId); inside the GetBuilder()
I have this Account class
import 'package:project/models/category_model.dart';
enum AccountTypes {
cash,
banks,
}
class Account {
AccountTypes type;
double value;
List<BalnceCategory>? categories;
Account({
required this.type,
required this.value,
this.categories,
});
Map<String, dynamic> toJSON() {
return {
"type": type,
"value": value,
"categories": categories,
};
}
}
Map<AccountTypes, List<dynamic>> accounts = {
AccountTypes.cash: [
BalnceCategory(image: "food.png", title: "Food", value: 412.5).toJSON(),
BalnceCategory(image: "shopping.png", title: "Shopping", value: 412.5).toJSON(),
],
AccountTypes.banks: [
BalnceCategory(image: "food.png", title: "Food", value: 1242.63).toJSON(),
BalnceCategory(image: "shopping.png", title: "Shopping", value: 1242.63).toJSON(),
]
};
each Account should contain a list of BalnceCategory
class BalnceCategory {
String image;
String title;
double value;
BalnceCategory({
required this.image,
required this.title,
required this.value,
});
Map<String, dynamic> toJSON() {
return {
"image": image,
"title": title,
"value": value,
};
}
}
Now I want to display this Map Map<AccountTypes, List<dynamic>> accounts in two sections...I will refer to this map as accounts.
So in the first section I want to list all available accounts in something like a Row with a button for each account, so what I did is I mapped through accounts like this accounts.entries.map and returned a button for each account, and these buttons can set a state called currentIndex with it's index.
Now in the second section I want to list all accounts categories depending on the currentIndex state value, so for example if the currentIndex value is 0 I want to display all the categories in cash account, and if the currentIndex value is 1 I want to display all the categories in banks account.
So far all I am done the buttons section and I it is working properly and my problem is in the second section. I tried to do this
Expanded(
child: GridView.builder(
physics: const BouncingScrollPhysics(),
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
mainAxisSpacing: mainUnit / 2,
crossAxisSpacing: mainUnit / 2,
childAspectRatio: 3 / 4,
),
itemCount: accounts.keys.length,
itemBuilder: (context, index) {
return accounts.forEach((key, value) {
if (key.index == currentIndex) {
value.map((e) => {Text(e.toString())});
}
});
},
),
),
but it gives me this error: The return type 'void' isn't a 'Widget', as required by the closure's context.
The ItemBuilder should return a widget, you return accounts.forEach(...) that is a void function ( forEach() is a void function/closure).
Try this:
Text( accounts.keys.firstWhere( (item) => item.index == currentIndex,
orElse: ()=> "",).toString() );
BUT!!!!
Wait a moment!!!!!
Why don't you take a look at
https://pub.dev/packages/flutter_sticky_header
You should implement what you need: it displays an header that, in your case, could be a string AccountTypes.cash.toString() or AccountTypes.banks.toString(), and then follow the example and you should obtain what you need ( display grouped cards for AccountTypes ). more over I suggest you to use
https://pub.dev/packages/freezed
It helps you to defined your data class, and to Serialize then to JSON.
For Example:
import 'package:freezed_annotation/freezed_annotation.dart';
part 'account.g.dart';
part 'account.freezed.dart';
#freezed()
class Account with _$Account {
factory Account.cash({
#Default(0) double? value;
List<BalnceCategory>? categories;
}) = CashAccount;
factory Account.bank({
#Default(0) double? value;
List<BalnceCategory>? categories;
}) = BankAccount;
factory Account.fromJson(Map<String, dynamic> json) =>
_$AccountFromJson(json);
}
In that manner you have your data class ( account ) with its type ( cash / bank ) and serializable.
To create an account it is easy :
var myCash = Account.cash(... , ... );
Both CashAccount and BankAccount are two different classes that implement Account ( abstract class ), you can use it in a simple list of Accounts.
then , to chack for bank/cash you can use:
var myAccount = Account.cash(....);
myAccount.when(
bank: (BankAccount account) => ....,
cash: (CashAccount account) => .... ,
),
I'm making a text game with a sf fiction writer.
This game is similar to the Japanese visual novel. The story changes through choice.
DB is using sqflite.
I am loading text via listview.builder.
The list with dialogue is named Notes. I made it with reference to the memo app and did not edit it.
But I don't want to load the index sequentially.
I thought listview.builder was a for loop. Something is different. I want to change idex but it is difficult for me.
I would like to see 4,5 when it is index 2. index 6 and 7 should not be visible.
When index 3, index 4,5 should not be visible. I wish I could jump to index 6 or 7.
Actual index 2 and 3 are buttons.
I had to post a question in a hurry, so I made a new one. Can you give me a hint?
I also upload a table I made randomly.
Even if it is different from the intention of my question, please suggest a good direction.
It's ok if it's different from my code.
Not using DB, not using sqlite, dividing DB in two, using for loop….
text_game_viewer
dialogue_db.csv
Widget Builder() {
return FutureBuilder(
builder: (context, Snap) {
if ((Snap.data as List).length == 0) {
return Container(
child: Text("add a note"),
);
}
return ListView.builder(
itemCount: (Snap.data as List).length,
itemBuilder: (context, index) {
Memo memo = (Snap.data as List)[index];
getNextItem(index) {
return Column(
children: <Widget>[
Text(
memo.title,
style: TextStyle(fontWeight: FontWeight.bold),
),
Text(memo.text),
Padding(padding: EdgeInsets.only(bottom: 20))
],
);
}
return getNextItem(index);
},
);
},
future: loadMemo(),
);}
I don't know if this could help you but there is a lot of solution to do that, what I can share is:
you can use Graph approach using a simple chained object list (more complex)
you can transform the dialog_db.csv to list of object.
simple demonstration that I haven't test using the csv transformation. You need to adapt the code to your needs
For eg:
class MyDialog {
final int id;
final String type;
final String char;
final String text;
final List<int> nextIds; //min element count must be 1
MyDialog(this.id, this.char, this.type, this.text, this.nextIds);
#override
String toString() {
return "$id, $char, $type, $text";
}
}
data example
var dialog = [
MyDialog(1, "Toto", "line", "First line message", [2]),
MyDialog(2, "Toto", "choice", "Yes or no?", [4,5]),
MyDialog(3, "Toto", "line", "must be hidden", [100]),
MyDialog(4, "Toto", "choice", "YES", [7]),
MyDialog(5, "Toto", "choice", "NO", [8]),
//...
];
implementation example:
void test() {
//show the dialog 1
showDialog(1);
//then 2 and his next dialog, the dialog 3 must be skiped
showDialog(2);
}
MyDialog getDialog(int id) {
return dialog.where((element) => element.id == id).first;
}
void showDialog(int id) {
var d = getDialog(id);
print(d);
for (var i in d.nextIds) {
print("next: " + getDialog(i).toString());
}
}
I am making my own flutter application, but I ran into a problem. I am creating a Breakfast class
class Breakfast {
String foodTitle;
String foodCalories;
Breakfast({this.foodTitle, this.foodCalories});
}
From this class i create an array with objects of that class
class BreakfastFood {
List<Breakfast> _breakfastFoodData = [
Breakfast(
foodTitle: "Bread",
foodCalories: "100",
),
Breakfast(
foodTitle: "Soup",
foodCalories: "50",
),
];
int _foodTitle = 0;
int _foodCalories = 0;
String getFoodTitle() {
return _breakfastFoodData[_foodTitle].foodTitle;
}
String getFoodCalories() {
return _breakfastFoodData[_foodCalories].foodCalories;
}
}
I have created a component which gets the foodtitle and foodCalories and puts them in a widget.
Now i want to make a function that loops through the objects of the _breakfastfoodData and shows them. But I don't know how to loop through the list and show all the objects seperate from eachother.
_breakfastFoodData in your code is private property (because it begins _), you should change to breakfastFoodData.
You use ListView.builder to build your list:
List<Breakfast> datas= new BreakfastFood().breakfastFoodData;
return ListView.builder(
itemCount: datas.length,
itemBuilder: (context, index) {
return ListTile(
title: Text('${datas[index].foodTitle}'),
);
},
);
You just have to define your class as here:
class BreakfastFood {
List<Breakfast> _items = [
Breakfast(
foodTitle: "Bread",
foodCalories: "100",
),
Breakfast(
foodTitle: "Soup",
foodCalories: "50",
),
];
List<Breakfast> get items => [..._items];
}
and Then call it threw list view for display all items:
BreakfastFood foodData = BreakfastFood();
ListView.builder(
itemCount: foodData.items.length,
itemBuilder: (ctx, index) {
return ListTile(
title: Text('${foodData.items[index].foodTitle}'),
subTitle: Text('${foodData.items[index].foodCalories}'),
);
}
)
I used to use RecyclerView in AS but I have recently started learning Flutter.
I've been searching around and I can't seem to find a cohesive document/reference/example to allow an array List to appear in GridView.
List<Test> fbToJson(gdata) {
var tojson = json.decode(gdata).cast<Map<String, dynamic>>();
return tojson.map<Test>((json) => Test.fromJson(json)).toList();
}
class Test {
String imageUrl;
String name;
Test({this.imageUrl,this.name});
factory Test.fromJson(Map<String, dynamic> json) {
return Test(
imageUrl: json['imageUrl'] as String,
name: json['name'] as String
);
}
}
I was already able to pass the above list array to another activity class via Navigator.
My confusion is since this is a list array, I need to iterate through it to show the listed values eg.
for(var i in fbdata){
var myname = i.name;
}
I can't find any doc/resource to help show how to integrate this to a gridview if I wish to show both name and urlimage.
Thanks in advance.
Use GridView.builder
GridView.builder(
itemCount: fbdata.length,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: 3 / 2,
crossAxisSpacing: 10,
mainAxisSpacing: 10),
itemBuilder: (ctx, index) {
return Column(
children: <Widget>[
Text(fbdata[index].name),
Text(fbdata[index].imageUrl),
],
);
})