I am quite new on flutter and I try to use providers to fetch / add equipment in a list. Problem I still have a little trouble to understand how to declare and use it in my component.
Here is the code of my Dashboard page, where I declare a provider to fetch, and a floating button to add (random data for the moment):
import 'package:auth_app_v2/models/equipment.dart';
import 'package:auth_app_v2/models/user.dart';
import 'package:auth_app_v2/providers/auth_provider.dart';
import 'package:auth_app_v2/providers/equipment_provider.dart';
import 'package:auth_app_v2/providers/user_provider.dart';
import 'package:auth_app_v2/utility/shared_preferences.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class DashBoard extends StatefulWidget {
@override
_DashBoardState createState() => _DashBoardState();
}
class _DashBoardState extends State<DashBoard> {
@override
Widget build(BuildContext context) {
User user = Provider.of<UserProvider>(context).user;
Future<List<Map>> getEquipment() => EquipmentProvider().fetchEquipment();
return MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => EquipmentProvider()),
],
child: Scaffold(
appBar: AppBar(
title: Text("Dashboard"),
elevation: 0.1,
actions: <Widget>[
Padding(
padding: EdgeInsets.only(right: 20.0),
child: GestureDetector(
onTap: () {
UserPreferences().removeUser();
Navigator.pushReplacementNamed(context, '/login');
},
child: Icon(
Icons.logout,
size: 26.0,
),
)),
],
),
body: SingleChildScrollView(
child: FutureBuilder(
future: getEquipment(),
builder: (context, AsyncSnapshot<List<Map>> snapshot) {
var equips = snapshot.data != null
? snapshot.data!.map((doc) => Equipment.fromMap(doc))
: [];
return Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: const [
SizedBox(
height: 100,
),
// ListView.builder(
// padding: EdgeInsets.all(8),
// itemCount: ,
// itemBuilder: (BuildContext context, int index) {
// return Text("Hi");
// },
// )
],
);
}),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
Provider.of<EquipmentProvider>(context, listen: false)
.addEquipment();
},
child: const Icon(Icons.add_a_photo),
),
),
);
}
}
Here is the code of my EquipmentProvider, This is just the beginning, I haven't implemented all the functions and status yet. :
import 'dart:convert';
import 'package:auth_app_v2/models/equipment.dart';
import 'package:auth_app_v2/utility/equipment_storage.dart';
import 'package:flutter/cupertino.dart';
enum Status {
loading,
NotLoaded,
Loaded,
}
class EquipmentProvider extends ChangeNotifier {
late List<Equipment> equipments;
Future<List<Map>> fetchEquipment() async {
var result;
return [];
}
Future<Equipment> getEquipmentById() async {
var result;
return result;
}
Future addEquipment() async {
var json = [
{"id": 1, "name": "Pompe 1"},
{"id": 2, "name": "Pompe 2"}
];
EquipmentStorage().writeEquipment(jsonEncode(json));
return;
}
}
The problem is in the floating button (for the moment the list does not appear, I already try to make the addition work).When I press the button the error occurs:
This happens because you used a `BuildContext` that does not include the provider
of your choice. There are a few common scenarios :
I'm sure I missed a step somewhere but despite my research I can't find it...
Could someone tell me where the problem comes from and explain to me how to properly declare a provider to use it correctly?
Short answer is: move creation of your EquipmentProvider
up in the tree, because you are trying to get the provider from context
is not aware of it.
Your DashBoard
widget contains a Scaffold
so I assume it's a separate page. If yes then you can create EquipmentProvider
in a previous screen (one that is leading to DashBoard
).
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.