You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter报错求助:Null check operator used on a null value

Flutter学习用电商APP API调用空指针错误求助

调用API获取数据时反复出现以下错误:

Null check operator used on a null value

调试定位到错误发生在Cubit文件的getHomeData方法中,尝试多种方式仍无法解决,以下是相关代码片段:

Main文件

void main() async
{
  //this line of code ensures that all the data are set and get before running the app
  WidgetsFlutterBinding.ensureInitialized();

  Bloc.observer = MyBlocObserver();
  DioHelper.init();
  await CacheHelper.init();

  Widget? widget;
  bool? isDarkTheme = CacheHelper.getData(key: 'isDark') ?? false;
  bool? onBoarding = CacheHelper.getData(key: 'onBoarding') ?? false;
  token = CacheHelper.getData(key: 'token')??'';
  print(token);

  if(onBoarding != null && onBoarding)
  {
    widget = token.isNotEmpty? ShopLayout() : ShopLoginScreen();
  }
  else {
    widget = OnBoardingScreen();
  }

  runApp(MyApp(isDarkTheme: isDarkTheme ,startWidget: widget));
}

class MyApp extends StatelessWidget
{
  final bool? isDarkTheme;
  final Widget? startWidget;

  MyApp({@required this.isDarkTheme, @required this.startWidget});
  @override
  Widget build(BuildContext context) {
      return MultiBlocProvider(
        providers:
        [
          BlocProvider(create: (BuildContext context) => ShopCubit()..changeAppMode(isDarkFromPreferences: isDarkTheme)),
          BlocProvider(create: (BuildContext context) => ShopCubit()..getHomeData()),
          BlocProvider(create: (BuildContext context) => WhatsappCubit()),
        ],
        child: BlocConsumer<ShopCubit, ShopStates>(
          listener: (context, state){},
          builder: (context, state) => MaterialApp
          (
            theme: lightTheme,
            darkTheme: darkTheme,
            themeMode: ThemeMode.light,//isDarkTheme!? ThemeMode.dark: ThemeMode.dark,
            debugShowCheckedModeBanner: false,
            home: startWidget,
          ),
        ),
      );
  }

}

Cubit文件

class ShopCubit extends Cubit<ShopStates>
{
  ShopCubit() : super(ShopInitialState());

  static ShopCubit get(context) => BlocProvider.of(context);

  int currentIndex = 0;

  bool isDark = true;
  ThemeMode? appTheme;

  List<Widget> screens =
  [
    ProductsScreen(),
    CategoriesScreen(),
    FavouritesScreen(),
    SettingsScreen(),
  ];

  void changeBottomSheetIndex(int index)
  {
    currentIndex = index;
    emit(ShopChangeBottomNavCurrentIndexState());
  }

  HomeModel? homeModel;
  void getHomeData()
  {
    emit(ShopLoadingHomeDataState());

    DioHelper.getData(path: HOME, token: token).then((value) {
      if (value.data != null) {

        homeModel = HomeModel.fromJson(value.data);
        print('Data fetched successfully');
        printFullText(homeModel!.data!.banners[0].image);
        emit(ShopSuccessHomeDataState());
      }
      else
      {
        emit(ShopErrorHomeDataState('Response data is null'));
      }
    }).catchError((error) {
      emit(ShopErrorHomeDataState(error.toString()));
      print('Error fetching data: ${error.toString()}');
    });

  }

  void changeAppMode({bool? isDarkFromPreferences})
  {
    if(isDarkFromPreferences != null)
    {
      isDark = isDarkFromPreferences;
      emit(ShopChangeAppModeState());
    }
    else
    {
      isDark = !isDark;
    }

        if(isDark)
        {
          appTheme = ThemeMode.dark;
          CacheHelper.saveData(key: 'isDark', value: isDark).then((value)
          {
            emit(ShopChangeAppModeState());
          }).catchError((error)
          {
            print('An error occurred while trying to set a new value as a shared preference');
          });
        } else
        {
          appTheme = ThemeMode.light;
          CacheHelper.saveData(key: 'isDark', value: isDark).then((value)
          {
            emit(ShopChangeAppModeState());
          }).catchError((error)
          {
            print('An error occurred while trying to set a new value as a shared preference');
          });
        }
  }
}

Dio Helper文件

class DioHelper {
  static Dio? dio;

  static void init() {
    dio = Dio(
      BaseOptions(
        baseUrl: 'https://student.valuxapps.com/api/',
        receiveDataWhenStatusError: true,
      ),
    );
  }

  static Future<Response> getData({
    @required String? path,
    Map<String, dynamic>? query,
    String lang = 'en',
    String? token,
  })
  async
  {
    dio!.options.headers = {
      'Content-Type':'application/json',
      'lang':lang,
      'Authorization':token??'',
    };

    return await dio!.get(path!, queryParameters: query!);
  }

  static Future<Response> postData({
    @required String? url,
    Map<String, dynamic>? query,
    @required Map<String, dynamic>? data,
    String lang = 'en',
    String? token,
  }) async
  {
    dio!.options.headers = {
      'Content-Type':'application/json',
      'lang':lang,
      'Authorization':token??'',
    };
    return dio!.post(url!, queryParameters: query, data: data);
  }
}

Cache Helper文件

class CacheHelper
{
  static SharedPreferences? sharedPreferences;

  static Future<void> init() async
  {
    sharedPreferences = await SharedPreferences.getInstance();
  }

  static dynamic getData({@required String? key})
  {
    if(sharedPreferences == null) {
      return 'error this value is null';
    }
    return sharedPreferences!.get(key!);
  }

  static Future<bool> saveData({
    @required String? key,
    @required dynamic value,
  }) async
  {
    if(value is String) return await sharedPreferences!.setString(key!, value);
    if(value is int) return await sharedPreferences!.setInt(key!, value);
    if(value is bool) return await sharedPreferences!.setBool(key!, value);
    return await sharedPreferences!.setDouble(key!, value);
  }

  static Future<bool> removeData({@required String? key}) async
  {
    return await sharedPreferences!.remove(key!);
  }
}

数据模型文件

class HomeModel
{
    bool? status;
    HomeDataModel? data;

    HomeModel.fromJson(Map<String, dynamic> json)
    {
      status = json['status'];
      data = HomeDataModel.fromJson(json['data']);
    }
}

class HomeDataModel
{
  List<BannerModel> banners = [];
  List<ProductModel> products = [];

  HomeDataModel.fromJson(Map<String, dynamic> json)
  {
    json['banners'].forEach((element)
    {
      banners.add(element);
    });

    json['products'].forEach((element)
    {
      products.add(element);
    });
  }
}

class BannerModel
{
  int? id;
  String? image;

  BannerModel.fromJson(Map<String, dynamic> json)
  {
    id = json['id'];
    image = json['image'];
  }
}

class ProductModel
{
  int? id;
  dynamic price;
  dynamic oldPrice;
  dynamic discount;
  String? image;
  String? name;
  bool inFavourites = false;
  bool inCart = false;

  ProductModel.fromJson(Map<String, dynamic> json)
  {
    id = json['id'];
    price = json['price'];
    oldPrice = json['old_price'];
    discount = json['discount'];
    image = json['image'];
    name = json['name'];
    inFavourites = json['in_favourites'];
    inCart = json['in_cart'];
  }
}

补充说明:已通过调试确认错误源于Cubit文件的getHomeData方法,暂未找到解决方案,恳请帮忙排查。

内容的提问来源于stack exchange,提问作者Unknown

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 14:08:11