I am trying to instantiate a provider with an id passed through a route, the db call keeps failling as the id passed to it is blank not the value passed in.
(Feel free to ignore this next wordy bit if it isn't appropriate for your preffered method of communication.) Thank you in advance for any help, Im a newbie and have been trying for a while to get this working. Its a fairly standard pattern of handling data, but I can't find the standard way(s) to implement it. I have tried instantiating the provider in an init state with no luck. I have researched some options but Future Provider doesn't do what I need as that only returns static information.
Here is the ChangeNotifier I am using:
class MetaDataBrain extends ChangeNotifier {
List<Meta> _meta = [];
late String _dataId;
List<Meta> get metaData => _meta;
String get dataId => _dataId;
set dataId(String dataId) {
_dataId = dataId;}
MetaDataBrain({required String dataId}) {
_dataId = dataId;
init();
}
Future<void> init() async {
List<Map<String, Object?>> json = await DataDatabase.instance.getAllByFk(tableName: tableMetaData, columnName: MetaFields.fk, fk: _dataId);
MetaHelper helper = MetaHelper();
_meta = helper.fromJsonList(json);
notifyListeners();
}
}
Here is the stateful page where the provider is instantiated:
class LoadingDetailScreen extends StatefulWidget {
const LoadingDetailScreen({super.key, required this.dataId});
final String dataId;
@override
State<LoadingDetailScreen> createState() => _LoadingDetailScreenState();
}
class _LoadingDetailScreenState extends State<LoadingDetailScreen> {
@override
Widget build(BuildContext context) {
return MultiProvider(providers: [
ChangeNotifierProvider<MetaDataBrain>(
create: (context) => MetaDataBrain(dataId: widget.dataId)),
], child: const DetailScreen());
}
Here is the DetailScreen:
class DetailScreen extends StatelessWidget {
const DetailScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("this is a title")),
body: SafeArea(child: Padding(padding: const EdgeInsets.fromLTRB(10, 10, 10, 10), child: Column(children: <Widget>[
Expanded(flex: 1, child: Consumer<MetaDataBrain>(builder: (context, metaList, child) {
return ListView.separated(
itemCount: metaList.metaData.length,
separatorBuilder: (context, index) {return const SizedBox(height: 10);},
itemBuilder: (context, index) {return InformationCard(title: metaList.metaData[index].title, line1: metaList.metaData[index].description);}
);})),
]))
));
}
}
Here is the call to the DB
Future<List<Map<String, Object?>>> getAllByFk({required String tableName, required String fk, required String columnName}) async {
final db = await instance.database;
final maps = await db.rawQuery('SELECT * FROM $tableName WHERE $columnName = ?', [fk]);
if (maps.isNotEmpty) {return maps;} else {throw Exception('nothing found in $tableName with fk $fk in $columnName');}
}