Home > Back-end >  The following _CastError was thrown building FutureBuilder<DatabaseNote>
The following _CastError was thrown building FutureBuilder<DatabaseNote>

Time:12-21

═══════ Exception caught by widgets library ═══════════════════════════════════
The following _CastError was thrown building FutureBuilder<DatabaseNote>(dirty, state: _FutureBuilderState<DatabaseNote>#aa5d0):
type 'Null' is not a subtype of type 'DatabaseNote' in type cast

The relevant error-causing widget was
FutureBuilder<DatabaseNote>
package:mynotes/…/notes/new_note_view.dart:84
When the exception was thrown, this was the stack

my code.

import 'package:flutter/material.dart';
import 'package:mynotes/services/auth/auth_service.dart';
import 'package:mynotes/services/crud/notes_service.dart';

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

  @override
  State<NewNoteView> createState() => _NewNoteViewState();
}

class _NewNoteViewState extends State<NewNoteView> {
  DatabaseNote? _note;
  late final NotesService _notesService;
  late final TextEditingController _textController;

  @override
  void initState() {
    _notesService = NotesService();
    _textController = TextEditingController();
    super.initState();
  }

  void _textControllerListener() async {
    final note = _note;
    if (note == null) {
      return;
    }
    final text = _textController.text;
    await _notesService.updateNote(
      note: note,
      text: text,
    );
  }

  void _setupTextControllerListener() {
    _textController.removeListener(_textControllerListener);
    _textController.addListener(_textControllerListener);
  }

  Future<DatabaseNote> createNewNote() async {
    final existingNote = _note;
    if (existingNote != null) {
      return existingNote;
    }
    final currentUser = AuthService.firebase().currentUser!;
    final email = currentUser.email!;
    final owner = await _notesService.getUser(email: email);
    return await _notesService.createNote(owner: owner);
  }

  void _deleteNoteIfTextIsEmpty() {
    final note = _note;
    if (_textController.text.isEmpty && note != null) {
      _notesService.deleteNote(id: note.id);
    }
  }

  void _saveNoteIfTextNotEmpty() async {
    final note = _note;
    final text = _textController.text;
    if (note != null && text.isNotEmpty) {
      await _notesService.updateNote(
        note: note,
        text: text,
      );
    }
  }

  @override
  void dispose() {
    _deleteNoteIfTextIsEmpty();
    _saveNoteIfTextNotEmpty();
    _textController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('New Note'),
      ),
      body: FutureBuilder(
        future: createNewNote(),
        builder: (context, snapshot) {
          switch (snapshot.connectionState) {
            case ConnectionState.done:
              _note = snapshot.data as DatabaseNote;
              _setupTextControllerListener();
              return TextField(
                controller: _textController,
                keyboardType: TextInputType.multiline,
                maxLines: null,
                decoration: const InputDecoration(
                  hintText: 'Start typing your note...',
                ),
              );
            default:
              return const CircularProgressIndicator();
          }
        },
      ),
    );
  }
}

CodePudding user response:

Basically, this error indicates that when building the FutureBuilder widget's builder, you perform a cast to an explicitly non-null object, which is in fact null.

You may replace :

_note = snapshot.data as DatabaseNote;

with

_note = snapshot.data as DatabaseNote?;

Also, you need to make sure that your Future<DatabaseNote?> createNewNote() method always returns a DatabaseNote (ie. non-null). Otherwise you may replace its signature by Future<DatabaseNote?> createNewNote().

When writing Dart code, you should always keep in mind your object's nullability and explicitly state it in your code to prevent such errors.

Null safety prevents errors that result from unintentional access of variables set to null. For example, if a method expects an integer but receives null, your app causes a runtime error. This type of error, a null dereference error, can be difficult to debug.

Source: https://dart.dev/null-safety

  • Related