Flutter: вызов метода с нулевым значением при использовании общих предпочтений

#api #flutter #dart #sharedpreferences #provider

#API #flutter #dart #sharedpreferences #поставщик

Вопрос:

Я хочу использовать общие настройки для сохранения входа пользователя в систему, и я использую api с провайдером. я попытался поместить его в main, но не знаю, как это сделать, потому что мне нужно перейти на две разные страницы, поэтому я использовал его на первой странице, но обнаружил другую ошибку

[ОШИБКА: flutter/lib/ui/ui_dart_state.cc(177)] Необработанное исключение: ошибка NoSuchMethodError: метод «login» был вызван с нулевым значением. E / flutter (4199): приемник: null

и это метод, который я использовал

 UserProvider userProvider;
  ServiceProvider serviceProvider;
  bool alive = true;
  bool isLoading = false;
  var page;

  @override
  initState() {
    init();
    super.initState();
  }

  init() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    bool language = prefs.getBool('language');
    bool type = prefs.getBool('type');
    bool login = prefs.getBool('islog');
    if (alive) {
      if (language == true amp;amp; type == true amp;amp; login == true) {
        signIn();
      } else if ((language == true amp;amp; type == false amp;amp; login == true)) {
        visitor();
      }
    } else {
      if (alive) {
        setState(() {
          isLoading = false;
        });
      }
    }
  }

  signIn() async {
    //var res = await userProvider.residentLogin(context, phone, pass);
    SharedPreferences prefs = await SharedPreferences.getInstance();
    var phone = prefs.getString('phone');
    String pass = prefs.getString("pass");
    bool type = prefs.getBool('type');
      print("Shared ***************resident********************************");
      await userProvider.residentLogin(context, phone, pass);
      await serviceProvider.getHomeServiceList(context);
      await serviceProvider.getAdsList(context);
      await serviceProvider.getVideosList(context);
      Navigator.pushReplacement(context,
          MaterialPageRoute(builder: (context) => ResidentBottomTab()));
      print('Hello Tourist !!');
    
  }

  visitor() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    var phone = prefs.getString('phone');
    String pass = prefs.getString("pass");
    await userProvider.login(context, phone, pass);
    await serviceProvider.getVisitorAdsList(context);
    await serviceProvider.getVisitorVideosList(context);
    bool type = prefs.getBool('type');
    print("Shared ******************visitor*****************************");
    if (alive) {
      Navigator.pushReplacement(
          context, MaterialPageRoute(builder: (context) => VisitorHome()));
      print('Hello Tourist !!');
    }
  }

  @override
  void dispose() {
    alive = false;
    super.dispose();
  }
 

метод входа в систему

 Future<VisitorLoginModel> login(BuildContext context, phone, pass) async {
    final Map<String, dynamic> body = {
      'phone': phone,
      'password': pass,
      'token': '123',
      'serial_number': '123',
      'lang': 'en',
      'os': 'android',
    };

    _isLoading = true;
    notifyListeners();
    print('Starting request');
    http.Response response = await http.post(Environment.userLogin,
        body: json.encode(body), headers: Environment.requestHeader);
    print('Completed request');
    print('user SignUp response : ${response.body}');
    //print(body.toString());
    Map<String, dynamic> res = json.decode(response.body);
    var results;
    if (res['status'] == 1) {
      // login successful
      _visitorLoginModel = parseVisitorLogin(response.body);
      Provider.of<LoginVisitorUserProvider>(context, listen: false).userData =
          visitorLoginModel;
      Provider.of<LoginVisitorUserProvider>(context, listen: false)
          .sessionToken = visitorLoginModel.data.token;
      headers = Provider.of<LoginVisitorUserProvider>(context, listen: false)
          .httpHeader;
      // print('token');
      print('this is session token'  
          Provider.of<LoginVisitorUserProvider>(context, listen: false)
              .sessionToken);
    } else {
      // login failed;
      results =
          FailedRequest(code: 401, message: res['massage'], status: false);
    }
    _isLoading = false;
    notifyListeners();
    return visitorLoginModel;
  }
 

итак, у кого-нибудь есть идея решить этот случай!

Ответ №1:

Вызов метода await userProvider.login(context, phone, pass); выполняется для неинициализированной переменной. UserProvider userProvider; был объявлен, но не инициализирован

Комментарии:

1. это верно, пожалуйста, не могли бы вы указать, как использовать его в main?

2. @MariamYounes Пожалуйста, обратитесь к ответу, который я прикрепил сейчас. Вы должны инициализировать его в initState

3. я задал вопрос, пожалуйста, проверьте его

4. но все еще не знаю, как использовать метод общих предпочтений в main

Ответ №2:

Проблема здесь userProvider в том, что объявляется, но не инициализируется, и то же самое касается serviceProvider

В Flutter любой неинициализированной переменной неявно присваивается значение null, поэтому в строке await userProvider.login(context, phone, pass); , где вы вызываете login метод, в котором UserProvider не только инициализируется

Чтобы решить проблему, выполните следующие действия в initState,

 userProvider = Provider.of<UserProvider>(context, listen: false);