VB10 / vboverflow

Yes you can always ask to me anything but do you search problem or can you write any solutions?
123 stars 3 forks source link

Bad state: Tried to read a provider that threw during the creation of its value. The exception occurred during the creation of type CustomProvider. #141

Closed udanaDbb closed 2 years ago

udanaDbb commented 2 years ago

Merhaba bir page içinde iki ayrı dropdownda ilçe ve mahalle verilerini göstermek istiyorum. Bunun için provider temelli bir yapı oluşturdum lakin sayfa ilk açıldığında yukarıdaki hatayı alıyorum. Programı kapatmadan ana sayfaya geçip tekrardan dropdown sayfasına geçince veriler listeleniyor. Yani ilk build işleminde yukarıdaki hatayı alıyorum. Bunun sebebi ne olabilir ?

Provider sınıfı ` import 'package:dbb_mobile_application/utils/app_strings.dart'; import 'package:flutter/material.dart';

class CustomProvider extends ChangeNotifier { CustomProvider({required this.myList}) { initialValue = myList.first; }

List myList; List myMahalleList = []; late String initialValue; String initialMahalleValue = "TÜM MAHALLELER";

bool listState = true;

void setList(String value) { if (listState) {

  getNewList(value);
  initialValue = value;
  listState = false;
} else {
  initialValue = value;
  getNewList(value);
}
notifyListeners();

}

void updateList(String value) { initialMahalleValue = value; notifyListeners(); }

List getNewList(String value) { myMahalleList = AppStrings.itemsList[value]!; initialMahalleValue = myMahalleList.first;

return myMahalleList;

} } `

Custom dropdown widget

` import 'package:flutter/material.dart';

class CustomDropDownWidget extends StatelessWidget { const CustomDropDownWidget( {Key? key, required this.initialValue, required this.list, required this.onPressed}) : super(key: key);

final String initialValue; final List list; final ValueChanged onPressed;

@override Widget build(BuildContext context) { return DropdownButton( isExpanded: true, iconSize: 36, value: initialValue, items: list .asMap() .map((key, value) => MapEntry( key, DropdownMenuItem(value: value, child: Text(value)))) .values .toList(), onChanged: (value) { onPressed(value!); }); } } `

BildirimlerPage

` class BildirimlerPage extends StatefulWidget { const BildirimlerPage({Key? key}) : super(key: key);

@override State createState() => _BildirimlerPageState(); }

class _BildirimlerPageState extends State { bool valHaber = true; bool valDuyuru = true; bool valIhale = true; bool valUlasim = true; String textHaber = "Haber Bildirimleri"; String textDuyuru = "Duyuru Bildirimleri"; String textIhale = "İhale Bildirimleri"; String textUlasim = "Ulaşım Bildirimleri";

final url = Uri.parse(ProjectServiceUrl().mahalleServiceUrl); int counter = 0; int mahalleCounter = 0; Map<String, List> ilceList = {}; final mappedValues = <Map<String, List>>[]; String valueIlce = "TÜM İLÇELER"; String valueMahalle = "TÜM MAHALLELER";

@override void initState() { // TODO: implement initState super.initState(); getApiData(); prepareSharedPreferences(); }

@override Widget build(BuildContext context) { print(ilceList.keys.toList()); return ChangeNotifierProvider( create: (context) => CustomProvider(myList: getListDropdown().keys.toList()), child: Scaffold( appBar: AppBar( iconTheme: const IconThemeData(color: Colors.black), title: Text( ProjectTitleTextConstant().bildirimlerKucuk, style: const TextStyle(color: Colors.black), ), ), body: Column( children: [ customSwitch(textHaber, valHaber, onChangeFunctionHaber), customSwitch(textDuyuru, valDuyuru, onChangeFunctionDuyuru), customSwitch(textIhale, valIhale, onChangeFunctionIhale), customSwitch(textUlasim, valUlasim, onChangeFunctionUlasim), const Divider( color: Colors.black, ), const Padding( padding: EdgeInsets.only(top: 16, bottom: 16), child: Text( "Su Kesintisi Bildirimleri", style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16), ), ), const Align( alignment: Alignment.bottomLeft, child: Padding( padding: EdgeInsets.only(left: 14), child: Text( "İlçeler", style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold), ))), Container( margin: const EdgeInsets.all(16), padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 4), decoration: BoxDecoration( borderRadius: BorderRadius.circular(12), border: Border.all(color: Colors.black, width: 2)), child: Consumer( builder: (context, notifier, child) => CustomDropDownWidget( initialValue: notifier.initialValue, list: notifier.myList, onPressed: (String? value) { notifier.setList(value!); }), )), const Align( alignment: Alignment.bottomLeft, child: Padding( padding: EdgeInsets.only(left: 14), child: Text( "Mahalleler", style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold), ))), Container( margin: const EdgeInsets.all(16), padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 4), decoration: BoxDecoration( borderRadius: BorderRadius.circular(12), border: Border.all(color: Colors.black, width: 2)), child: Consumer( builder: (context, notifier, child) => CustomDropDownWidget( initialValue: notifier.initialMahalleValue, list: notifier.myMahalleList, onPressed: (String? value) { notifier.updateList(value!); }), )), ElevatedButton( onPressed: () {}, style: ButtonStyle( shape: MaterialStateProperty.all(RoundedRectangleBorder( borderRadius: BorderRadius.circular(12))), fixedSize: MaterialStateProperty.all(const Size.fromWidth(200))), child: const Text("EKLE"), ) ], ), ), ); }

Widget customSwitch(String text, bool val, Function onChangeMethod) { return Padding( padding: const EdgeInsets.only(top: 20, left: 20, right: 20), child: Row( mainAxisAlignment: MainAxisAlignment.start, children: [ Text( text, style: const TextStyle(fontSize: 20, fontWeight: FontWeight.bold), ), const Spacer(), CupertinoSwitch( trackColor: Colors.grey, activeColor: Colors.green, value: val, onChanged: (newValue) { onChangeMethod(newValue); }) ], ), ); }

Future getApiData() async { try { final response = await http.get(url); if (response.statusCode == 200) { var result = mahalleFromJson(response.body);

    for (final element in result) {
      final ilceAd = element.ilceAdi;
      final mahAd = element.mahAdi;

      final contains = mappedValues
          .where((element) => element.keys.contains(ilceAd))
          .toList();

      if (contains.isNotEmpty) {
        if (contains.first.isNotEmpty) {
          if (contains.first.containsKey(ilceAd)) {
            contains.first[ilceAd]!.add(mahAd!);
          }
        }
      } else {
        mappedValues.add({
          ilceAd as String: [mahAd!]
        });
      }
    }
    //print(mappedValues.length);

    //print(ilceList.keys);
    var mahalleList = mappedValues.map((e) => e.values.toList());
    //print(mappedValues.map((e) => e.keys).toList());
    if (mounted) {
      setState(() {
        counter = result.length;
        for (var i = 0; i < mappedValues.length; i++) {
          ilceList.addAll(mappedValues.elementAt(i));
        }
        //print(counter);
      });

      for (var i = 0; i < counter; i++) {
        //print(result[i].mahAdi);
      }
    }
  }
} catch (e) {
  print(e.toString());
}

}

Map<String, List> getListDropdown() { for (var i = 0; i < mappedValues.length; i++) { ilceList.addAll(mappedValues.elementAt(i)); } return ilceList; }

onChangeFunctionHaber(bool newValHaber) { setState(() { valHaber = newValHaber; saveData("haber", valHaber); if (valHaber == true) { subscribeHaber(context); } else if (valHaber == false) { unSubscribeHaber(context); } }); }

onChangeFunctionDuyuru(bool newValDuyuru) { setState(() { valDuyuru = newValDuyuru; saveData("duyuru", valDuyuru);

  if (valDuyuru == true) {
    subscribeDuyuru(context);
  } else if (valDuyuru == false) {
    unSubscribeDuyuru(context);
  }
});

}

onChangeFunctionIhale(bool newValIhale) { setState(() { valIhale = newValIhale; saveData("ihale", valIhale); }); }

onChangeFunctionUlasim(bool newValUlasim) { setState(() { valUlasim = newValUlasim; saveData("ulasim", valUlasim); }); }

Future saveData(String sharedKey, bool value) async { var prefs = await SharedPreferences.getInstance(); prefs.setBool(sharedKey, value); }

Future prepareSharedPreferences() async { var prefs = await SharedPreferences.getInstance(); valHaber = prefs.getBool("haber") ?? true; valDuyuru = prefs.getBool("duyuru") ?? true; valIhale = prefs.getBool("ihale") ?? true; valUlasim = prefs.getBool("ulasim") ?? true; setState(() {}); } }

void subscribeHaber(BuildContext context) async { await FirebaseMessaging.instance .subscribeToTopic("haber") .then((value) => print("haber subscribed")); }

void unSubscribeHaber(BuildContext context) async { await FirebaseMessaging.instance .unsubscribeFromTopic("haber") .then((value) => print("haber unsubscribed")); }

void subscribeDuyuru(BuildContext context) async { await FirebaseMessaging.instance .subscribeToTopic("duyuru") .then((value) => print("duyuru subscribed")); }

void unSubscribeDuyuru(BuildContext context) async { await FirebaseMessaging.instance .unsubscribeFromTopic("duyuru") .then((value) => print("duyuru unsubscribed")); }

`

mysCod3r commented 2 years ago

kodları kod tagi içinde atmadığın için okunurluğu yok ama hatanın dediğine göre veriler tam yüklenmeden sayfa build edilmeye çalışıyor.

Future<void>_init() async{
         await fetchItem();
         await someOther();
}
@OverRide
void initState() {
super.initState();
_init();
}

ya da

@override
void initState() {
  Future.delayed(Duration.zero,() async {
        // fonksiyonları burada çağırabilirsin
  });
  super.initState();
}
udanaDbb commented 2 years ago

evet haklısınız. Hatayı ana ekranda liseyi doldurarak çözdüm şu an stabil çalışıyor. Yanıt için teşekkürler.