简体   繁体   中英

Flutter - Could not find the correct provider in widget

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM