I am trying to create a to-do list app in flutter. I am facing an issue with a widget that helps me to edit an already created to-do widget with respect to the title or description.
This is the pic of my todo list HomePage
This pic of my edit button
I am facing an issue after I press the save button in this widget
This is the error that I am getting
════════ Exception caught by gesture ═══════════════════════════════════════════
The following _CastError was thrown while handling a gesture:
Null check operator used on a null value
When the exception was thrown, this was the stack
#0 _EditTodoPageState.saveTodo
package:todolist/Edit_Todo_Page.dart:47
#1 _InkResponseState._handleTap
package:flutter/…/material/ink_well.dart:989
#2 GestureRecognizer.invokeCallback
package:flutter/…/gestures/recognizer.dart:198
#3 TapGestureRecognizer.handleTapUp
package:flutter/…/gestures/tap.dart:608
#4 BaseTapGestureRecognizer._checkUp
package:flutter/…/gestures/tap.dart:296
#5 BaseTapGestureRecognizer.handlePrimaryPointer
package:flutter/…/gestures/tap.dart:230
#6 PrimaryPointerGestureRecognizer.handleEvent
package:flutter/…/gestures/recognizer.dart:563
#7 PointerRouter._dispatch
package:flutter/…/gestures/pointer_router.dart:94
#8 PointerRouter._dispatchEventToRoutes.<anonymous closure>
package:flutter/…/gestures/pointer_router.dart:139
(elided 3 frames from dart:async)
Handler: "onTap"
Recognizer: TapGestureRecognizer#25bd2
debugOwner: GestureDetector
state: possible
won arena
finalPosition: Offset(189.1, 309.1)
finalLocalPosition: Offset(67.7, 11.1)
button: 1
sent tap down
════════════════════════════════════════════════════════════════════════════════
This is my edit todo widget
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:todolist/todo.dart';
import './todos.dart';
import './todo_form_widget.dart';
class EditTodoPage extends StatefulWidget {
final Todo todo;
const EditTodoPage({Key? key, required this.todo}) : super(key: key);
@override
State<EditTodoPage> createState() => _EditTodoPageState();
}
class _EditTodoPageState extends State<EditTodoPage> {
final _formKey = GlobalKey<FormState>();
late String title;
late String description;
@override
void initState() {
super.initState();
title = widget.todo.title;
description = widget.todo.description;
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Edit Todo"),
),
body: Padding(
padding: EdgeInsets.all(16),
child: Form(
child: TodoFormWidget(
title: title,
description: description,
onChangedTitle: (title) => setState(() => this.title = title),
onChangedDescription: (description) =>
setState(() => this.description = description),
onSavedTodo: saveTodo,
),
),
));
}
saveTodo() {
final isValid = _formKey.currentState!.validate();
if (!isValid) {
return;
} else {
final provider = Provider.of<TodosProvider>(context, listen: false);
provider.updateTodo(widget.todo, title, description);
Navigator.of(context).pop();
}
}
}
I am getting an error in the "saveTodo()" method. I am not able to solve this error.
This is my Provider widget
import 'package:flutter/cupertino.dart';
import 'package:todolist/todo.dart';
import 'package:provider/provider.dart';
class TodosProvider extends ChangeNotifier {
List<Todo> _todos = [
Todo(
createdTime: DateTime.now(),
title: "Wake up at 6:00 AM in the morning😀!!!",
),
Todo(
createdTime: DateTime.now(),
title: "Wake up at 6:00 AM in the morning😀!!!",
),
Todo(
createdTime: DateTime.now(),
title: "Wake up at 6:00 AM in the morning😀!!!",
),
Todo(
createdTime: DateTime.now(),
title: "Wake up at 6:00 AM in the morning😀!!!",
),
Todo(
createdTime: DateTime.now(),
title: "Wake up at 6:00 AM in the morning😀!!!",
),
Todo(
createdTime: DateTime.now(),
title: "Wake up at 6:00 AM in the morning😀!!!",
),
Todo(
createdTime: DateTime.now(),
title: "Wake up at 6:00 AM in the morning😀!!!",
),
Todo(
createdTime: DateTime.now(),
title: "Wake up at 6:00 AM in the morning😀!!!",
),
];
List<Todo> get todos => _todos.where((todo) => todo.isDone == false).toList();
List<Todo> get todosCompleted =>
_todos.where((todo) => todo.isDone == true).toList();
void addTodo([Todo? todo]) {
_todos.add(todo!);
notifyListeners();
}
void removeTodo(Todo todo) {
_todos.remove(todo);
notifyListeners();
}
bool toggleTodoStatus(Todo todo) {
todo.isDone = !todo.isDone;
notifyListeners();
return todo.isDone;
}
void updateTodo(Todo todo, String title, String description) {
todo.title = title;
todo.description = description;
notifyListeners();
}
}
Please help me solve this error.
I think, you haven't used _formKey
in Form
widget thats why _formKey
currentState
is getting null. Try to use _formKey
in the Form
widget and check it is not equal to null.
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:todolist/todo.dart';
import './todos.dart';
import './todo_form_widget.dart';
class EditTodoPage extends StatefulWidget {
final Todo todo;
const EditTodoPage({Key? key, required this.todo}) : super(key: key);
@override
State<EditTodoPage> createState() => _EditTodoPageState();
}
class _EditTodoPageState extends State<EditTodoPage> {
final _formKey = GlobalKey<FormState>();
late String title;
late String description;
@override
void initState() {
super.initState();
title = widget.todo.title;
description = widget.todo.description;
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Edit Todo"),
),
body: Padding(
padding: EdgeInsets.all(16),
child: Form(
key: _formKey,
child: TodoFormWidget(
title: title,
description: description,
onChangedTitle: (title) => setState(() => this.title = title),
onChangedDescription: (description) =>
setState(() => this.description = description),
onSavedTodo: saveTodo,
),
),
),
);
}
saveTodo() {
final isValid = _formKey.currentState != null && _formKey.currentState!.validate();
if (!isValid) {
return;
} else {
final provider = Provider.of<TodosProvider>(context, listen: false);
provider.updateTodo(widget.todo, title, description);
Navigator.of(context).pop();
}
}
}