Home > OS >  Shared preferences - _CastError (Null check operator used on a null value)
Shared preferences - _CastError (Null check operator used on a null value)

Time:09-15

I'm following the tutorial about shared preferences and I'm stuck with _CastError (Null check operator used on a null value). I've already found a few solutions but they are not perfect for my case or I just simply can't implement them properly :( On the screen, you can see where this error appears: _CastError

My files below:

main.dart

import 'package:day08_user_settings/preferences_service.dart';
import 'package:flutter/material.dart';

import 'models.dart';

void main() {
  runApp(
    MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyApp(),
    ),
  );
}

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  final _preferencesService = PreferencesService();
  final _usernameController = TextEditingController();

  var _selectedGender = Gender.FEMALE;
  final _selectedLanguages = Set<ProgrammingLanguage>();
  var _isEmployed = false;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('User settings'),
      ),
      body: ListView(
        children: [
          ListTile(
            title: TextField(
              controller: _usernameController,
              decoration: const InputDecoration(labelText: 'Username'),
            ),
          ),
          RadioListTile(
              title: const Text('Female'),
              value: Gender.FEMALE,
              groupValue: _selectedGender,
              onChanged: (newValue) =>
                  setState(() => _selectedGender = newValue!)),
          RadioListTile(
              title: const Text('Male'),
              value: Gender.MALE,
              groupValue: _selectedGender,
              onChanged: (newValue) =>
                  setState(() => _selectedGender = newValue!)),
          RadioListTile(
              title: const Text('Other'),
              value: Gender.OTHER,
              groupValue: _selectedGender,
              onChanged: (newValue) =>
                  setState(() => _selectedGender = newValue!)),
          CheckboxListTile(
            title: const Text('Dart'),
            value: _selectedLanguages.contains(ProgrammingLanguage.DART),
            onChanged: (_) {
              setState(() {
                _selectedLanguages.contains(ProgrammingLanguage.DART)
                    ? _selectedLanguages.remove(ProgrammingLanguage.DART)
                    : _selectedLanguages.add(ProgrammingLanguage.DART);
              });
            },
          ),
          CheckboxListTile(
            title: const Text('JavaScript'),
            value: _selectedLanguages.contains(ProgrammingLanguage.JAVASCRIPT),
            onChanged: (_) {
              setState(() {
                _selectedLanguages.contains(ProgrammingLanguage.JAVASCRIPT)
                    ? _selectedLanguages.remove(ProgrammingLanguage.JAVASCRIPT)
                    : _selectedLanguages.add(ProgrammingLanguage.JAVASCRIPT);
              });
            },
          ),
          CheckboxListTile(
            title: const Text('Kotlin'),
            value: _selectedLanguages.contains(ProgrammingLanguage.KOTLIN),
            onChanged: (_) {
              setState(() {
                _selectedLanguages.contains(ProgrammingLanguage.KOTLIN)
                    ? _selectedLanguages.remove(ProgrammingLanguage.KOTLIN)
                    : _selectedLanguages.add(ProgrammingLanguage.KOTLIN);
              });
            },
          ),
          CheckboxListTile(
            title: const Text('Swift'),
            value: _selectedLanguages.contains(ProgrammingLanguage.SWIFT),
            onChanged: (_) {
              setState(() {
                _selectedLanguages.contains(ProgrammingLanguage.SWIFT)
                    ? _selectedLanguages.remove(ProgrammingLanguage.SWIFT)
                    : _selectedLanguages.add(ProgrammingLanguage.SWIFT);
              });
            },
          ),
          SwitchListTile(
            title: const Text('Is Employed'),
            value: _isEmployed,
            onChanged: (newValue) => setState(
              () => _isEmployed = newValue,
            ),
          ),
          TextButton(
            onPressed: _saveSettings,
            child: const Text('Save Settings'),
          )
        ],
      ),
    );
  }

  void _saveSettings() {
    final newSettings = Settings(
      username: _usernameController.text,
      gender: _selectedGender,
      programmingLanguages: _selectedLanguages,
      isEmployed: _isEmployed,
    );
    print(newSettings);
    _preferencesService.saveSettings(newSettings);
  }
}

models.dart

enum Gender { FEMALE, MALE, OTHER }

enum ProgrammingLanguage { DART, JAVASCRIPT, KOTLIN, SWIFT }

class Settings {
  String? username;
  Gender? gender;
  Set<ProgrammingLanguage>? programmingLanguages;
  bool? isEmployed;

  Settings({
    required String username,
    required Gender gender,
    required Set<ProgrammingLanguage> programmingLanguages,
    required bool isEmployed,
  });
}

preferences-service.dart

import 'package:day08_user_settings/models.dart';
import 'package:shared_preferences/shared_preferences.dart';

class PreferencesService {
  Future saveSettings(Settings settings) async {
    final preferences = await SharedPreferences.getInstance();

    await preferences.setString('username', settings.username ?? '');
    await preferences.setBool('isEmployed', settings.isEmployed ?? false);
    await preferences.setInt('Gender', settings.gender?.index ?? 0);
    await preferences.setStringList(
      'ProgrammingLanguages',
      settings.programmingLanguages!
          .map((lang) => lang.index.toString())
          .toList(),
    );

    print('Save Settings');
  }
}

Please help with this because I don't have any idea at this point and I'm still learning.

CodePudding user response:

As you can see from the error setting.programmingLanguages is null. What do you want to do if the list is empty?

  1. If you want to remove whatever is in preferences from before use remove('ProgrammingLanguages').
  2. You can just skip setString() if setting.programmingLanguages==null

P.S. I advice you to have keys as constant values at the top of the file, so you don't have to copy paste and less chance for a typo. Like const programLang = 'ProgrammingLanguages'

CodePudding user response:

The _CastError (Null check operator used on a null value) error is triggered because you tried to use a null-valued variable. When you enter "!" in settings.programmingLanguages!.map((lang) => lang.index.toString()).toList(), , in theory you are ensuring that the value of programmingLanguages is not null. I suggest you do a check first to verify that the value is not null, and only then use the "!" in your variable.

  • Related