0

Can anyone help? I am trying to collect some data from shared preferences but getting a 'Null check operator used on a null value' message on the emulator.

I am trying to collect a list of 'Resolutions' from shared preferences within initState when i open a particular page. This is when the error occurs and I get the red screen.

That code is as follows...

class _ResolutionsListScreenState extends State<ResolutionsListScreen> {
  late List<Resolution> resolutions;

  @override
  void initState() {
    super.initState();
    resolutions = ResolutionPreferences.getResolutions();
  }

This is the bottom method of the following file...

import 'package:shared_preferences/shared_preferences.dart';
import 'dart:convert';

import 'package:resolut/model/resolution.dart';

class ResolutionPreferences {
  static SharedPreferences? _preferences;
  static const _keyResolutions = 'resolutions';

  static Future init() async {
    _preferences = await SharedPreferences.getInstance();
    print('Preferences initialised');
  }

  //add resolution object to resolutions list
  static Future addToResolutions(Resolution resolution) async {
    final idResolutions =
        _preferences!.getStringList(_keyResolutions) ?? <String>[];
    final newIDResolutions = List.of(idResolutions)..add(resolution.id);

    await _preferences!.setStringList(_keyResolutions, newIDResolutions);
  }

  //get resolution list
  static List<Resolution> getResolutions() {
    final idResolutions = _preferences!.getStringList(_keyResolutions);
    if (idResolutions == null) {
      return <Resolution>[];
    } else {
      return idResolutions.map<Resolution>(getResolution).toList();
    }
  }

  //store resolution
  static Future setResolution(Resolution resolution) async {
    final json = jsonEncode(resolution.toJson());
    final idResolution = resolution.id;
    await _preferences!.setString(idResolution, json);
  }

  // Retrieve resolution
  static Resolution getResolution(String idResolution) {
    final json = _preferences!.getString(idResolution);
    return Resolution.fromJson(jsonDecode(json!));
  }
}

Which I initialise at startup with the following code in my main.dart

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await ResolutionPreferences.init();
  runApp(const MyApp());
}

Every help article i have found tells me the problem is down to not having that WidgetsFlutterBinding.ensureInitialized(); in place... that's not the problem for me.

My suspicion is that the code doesn't like the bang operator in the final line of the method i am calling after the json

return Resolution.fromJson(jsonDecode(json!));

However I cannot remove it because I get the message 'The argument type 'String?' can't be assigned to the parameter type 'String'.

Please let me know if you need any more information, i'm new to programming and this null safety stuff blows my mind!

Below is the entire stacktrace

======== Exception caught by widgets library =======================================================
The following _CastError was thrown building Builder:
Null check operator used on a null value

The relevant error-causing widget was: 
  MaterialApp MaterialApp:file:///C:/Users/Alex/StudioProjects/resolut/lib/main.dart:25:12
When the exception was thrown, this was the stack: 
#0      ResolutionPreferences.getResolution (package:resolut/shared_preferences.dart:48:47)
#1      MappedListIterable.elementAt (dart:_internal/iterable.dart:413:31)
#2      ListIterator.moveNext (dart:_internal/iterable.dart:342:26)
#3      new _GrowableList._ofEfficientLengthIterable (dart:core-patch/growable_array.dart:188:27)
#4      new _GrowableList.of (dart:core-patch/growable_array.dart:150:28)
#5      new List.of (dart:core-patch/array_patch.dart:51:28)
#6      ListIterable.toList (dart:_internal/iterable.dart:213:44)
#7      ResolutionPreferences.getResolutions (package:resolut/shared_preferences.dart:33:61)
#8      _ResolutionsListScreenState.initState (package:resolut/screens/resolutions_list_screen.dart:21:41)
#9      StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:4728:57)
#10     ComponentElement.mount (package:flutter/src/widgets/framework.dart:4561:5)
...     Normal element mounting (169 frames)
#179    Element.inflateWidget (package:flutter/src/widgets/framework.dart:3631:14)
#180    MultiChildRenderObjectElement.inflateWidget (package:flutter/src/widgets/framework.dart:6261:36)
#181    Element.updateChild (package:flutter/src/widgets/framework.dart:3383:18)
#182    RenderObjectElement.updateChildren (package:flutter/src/widgets/framework.dart:5684:32)
#183    MultiChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:6284:17)
#184    Element.updateChild (package:flutter/src/widgets/framework.dart:3370:15)
#185    ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4613:16)
#186    StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:4763:11)
#187    Element.rebuild (package:flutter/src/widgets/framework.dart:4311:5)
#188    StatefulElement.update (package:flutter/src/widgets/framework.dart:4795:5)
#189    Element.updateChild (package:flutter/src/widgets/framework.dart:3370:15)
#190    ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4613:16)
#191    Element.rebuild (package:flutter/src/widgets/framework.dart:4311:5)
#192    ProxyElement.update (package:flutter/src/widgets/framework.dart:4943:5)
#193    Element.updateChild (package:flutter/src/widgets/framework.dart:3370:15)
#194    ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4613:16)
#195    Element.rebuild (package:flutter/src/widgets/framework.dart:4311:5)
#196    ProxyElement.update (package:flutter/src/widgets/framework.dart:4943:5)
#197    _InheritedNotifierElement.update (package:flutter/src/widgets/inherited_notifier.dart:111:11)
#198    Element.updateChild (package:flutter/src/widgets/framework.dart:3370:15)
#199    SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:6130:14)
#200    Element.updateChild (package:flutter/src/widgets/framework.dart:3370:15)
#201    ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4613:16)
#202    StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:4763:11)
#203    Element.rebuild (package:flutter/src/widgets/framework.dart:4311:5)
#204    StatefulElement.update (package:flutter/src/widgets/framework.dart:4795:5)
#205    Element.updateChild (package:flutter/src/widgets/framework.dart:3370:15)
#206    SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:6130:14)
#207    Element.updateChild (package:flutter/src/widgets/framework.dart:3370:15)
#208    SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:6130:14)
#209    Element.updateChild (package:flutter/src/widgets/framework.dart:3370:15)
#210    ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4613:16)
#211    Element.rebuild (package:flutter/src/widgets/framework.dart:4311:5)
#212    ProxyElement.update (package:flutter/src/widgets/framework.dart:4943:5)
#213    Element.updateChild (package:flutter/src/widgets/framework.dart:3370:15)
#214    ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4613:16)
#215    StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:4763:11)
#216    Element.rebuild (package:flutter/src/widgets/framework.dart:4311:5)
#217    BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2578:33)
#218    WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:882:21)
#219    RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:363:5)
#220    SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1145:15)
#221    SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1082:9)
#222    SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:996:5)
#226    _invoke (dart:ui/hooks.dart:150:10)
#227    PlatformDispatcher._drawFrame (dart:ui/platform_dispatcher.dart:270:5)
#228    _drawFrame (dart:ui/hooks.dart:114:31)
(elided 3 frames from dart:async)
====================================================================================================
Alex Cretney
  • 115
  • 9
  • Which line is causing the error? – Diwyansh Jan 12 '22 at 09:25
  • The final line of the stack track is... 'ResolutionPreferences.getResolution (package:resolut/shared_preferences.dart:44:47)' so i think it's... return Resolution.fromJson(jsonDecode(json!)); – Alex Cretney Jan 12 '22 at 09:37
  • Have you tried printing json? Is there any data in this variable? – Diwyansh Jan 12 '22 at 09:40
  • @AlexCretney please let me know if my answer helped you – Jahn E. Jan 12 '22 at 10:51
  • @Diwyansh thanks for the prompt. You are correct that the variable was null which is what was causing the crash. I have no idea how to fix but you've put me on the right path so thanks – Alex Cretney Jan 12 '22 at 15:14
  • @Jahn E. - Thanks for the assist but the issue is with a null json value rather than a null preferences instance. You're suggestion to run some if checks is definitely helpful though so thanks – Alex Cretney Jan 12 '22 at 15:15
  • But you are aware of the fact that idResolution is not mentioned in the error log, there this is not the problem, getString also takes a non-nullable value. And since you name your variable "json" and there is only 1 bang operator used in the line you mentioned (the json!) indicates that the variable json is nullable, because _preferences is null - believe me or don´t but that is your problem here - you´re welcome. – Jahn E. Jan 12 '22 at 15:48

1 Answers1

0

My assumption is, that this is the culprit:

  //get resolution list
  static List<Resolution> getResolutions() {
    final idResolutions = _preferences!.getStringList(_keyResolutions);
    if (idResolutions == null) {
      return <Resolution>[];
    }

Try moving the null check up, so if _preferences == null > return <Resolution>[], since you declared static SharedPreferences? _preferences; as a nullable variable!

EDIT: Because OP COMMENT

  // Retrieve resolution
  static Resolution getResolution(String idResolution) {
    final json = _preferences!.getString(idResolution);
    return Resolution.fromJson(jsonDecode(json!));
  }

Might be the same reason as above, can you ensure that _preferences won´t be null? Else also consider a null check here. Same goes for the json you are passing to jsonDecode, it won´t be null if you can simply make an if check like this:

if (_preferences != null) {
 final json = _preferences.getString(idResolution);
 return Resolution.fromJson(jsonDecode(json));
}
Jahn E.
  • 1,228
  • 3
  • 6
  • 21