I'm studying flutter for a personal project and i'm struggling in this error:
NoSuchMethodErro: '[]'
Dynamic call of null
Receiver: Instance of 'LinkedSet<Object>'
Arguments [0]
Here is my simple code:
//main.dart
import 'package:flutter/material.dart';
import 'package:mictch_koko_course/pages/home_page.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: HomePage(),
theme: ThemeData(
primaryColor: Colors.yellow,
),
);
}
}
//pages/home_page.dart
import 'package:flutter/material.dart';
import 'package:mictch_koko_course/util/todo_tile.dart';
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
List toDoList = [
{"Make Tutorial", false},
{"Do Exercise", false}
];
void checkBoxChanged(bool? value, int index){
setState(() {
toDoList[index][1] = !toDoList[index][1];
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.yellow[200],
appBar: AppBar(
backgroundColor: Theme.of(context).primaryColor,
title: Center(child: Text("TO DO")),
elevation: 0,
),
body: ListView.builder(
itemCount: toDoList.length,
itemBuilder: (context, index){
return TodoTile(
taskName: toDoList[index][0],
taskCompleted: toDoList[index][1],
onChanged: (value) => checkBoxChanged(value, index),
);
}
)
);
}
}
//util/todo_tile.dart
import 'package:flutter/material.dart';
class TodoTile extends StatelessWidget {
final String taskName;
final bool taskCompleted;
Function(bool?)? onChanged;
TodoTile({
super.key,
required this.taskName,
required this.taskCompleted,
required this.onChanged,
});
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(25.0),
child: Container(
padding: EdgeInsets.all(12),
decoration: BoxDecoration(
color: Colors.yellow,
borderRadius: BorderRadius.circular(12),
),
child: Row(
children: [
Checkbox(value: taskCompleted, onChanged: onChanged),
Text(taskName),
],
),
),
);
}
}
I tried some fixes with this dynamic onChanged method, but I can't figure out how to fix this error. I also removed every dynamic function to test if this was the problem, but unfortunately, it wasn't.
Any help or tips to how to fix it will be welcome!
I'm studying flutter for a personal project and i'm struggling in this error:
NoSuchMethodErro: '[]'
Dynamic call of null
Receiver: Instance of 'LinkedSet<Object>'
Arguments [0]
Here is my simple code:
//main.dart
import 'package:flutter/material.dart';
import 'package:mictch_koko_course/pages/home_page.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: HomePage(),
theme: ThemeData(
primaryColor: Colors.yellow,
),
);
}
}
//pages/home_page.dart
import 'package:flutter/material.dart';
import 'package:mictch_koko_course/util/todo_tile.dart';
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
List toDoList = [
{"Make Tutorial", false},
{"Do Exercise", false}
];
void checkBoxChanged(bool? value, int index){
setState(() {
toDoList[index][1] = !toDoList[index][1];
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.yellow[200],
appBar: AppBar(
backgroundColor: Theme.of(context).primaryColor,
title: Center(child: Text("TO DO")),
elevation: 0,
),
body: ListView.builder(
itemCount: toDoList.length,
itemBuilder: (context, index){
return TodoTile(
taskName: toDoList[index][0],
taskCompleted: toDoList[index][1],
onChanged: (value) => checkBoxChanged(value, index),
);
}
)
);
}
}
//util/todo_tile.dart
import 'package:flutter/material.dart';
class TodoTile extends StatelessWidget {
final String taskName;
final bool taskCompleted;
Function(bool?)? onChanged;
TodoTile({
super.key,
required this.taskName,
required this.taskCompleted,
required this.onChanged,
});
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(25.0),
child: Container(
padding: EdgeInsets.all(12),
decoration: BoxDecoration(
color: Colors.yellow,
borderRadius: BorderRadius.circular(12),
),
child: Row(
children: [
Checkbox(value: taskCompleted, onChanged: onChanged),
Text(taskName),
],
),
),
);
}
}
I tried some fixes with this dynamic onChanged method, but I can't figure out how to fix this error. I also removed every dynamic function to test if this was the problem, but unfortunately, it wasn't.
Any help or tips to how to fix it will be welcome!
Share Improve this question asked Mar 24 at 0:48 Bruno BevilaquaBruno Bevilaqua 33 bronze badges 1- It would help if you included the stack trace, or at least point at the line that is throwing the exception. – Randal Schwartz Commented Mar 24 at 0:55
2 Answers
Reset to default 0The issue is that you are treating Map
as a list and accessing the values as an index which is not allowed accessing values from the map is done through keys like this:
final taskName = toDoList[0]["task"]; // which will take the name of the first task in the list.
// as you can see the first level is List so we are accessing values using index
// `0` then we have Map and accessing its values through key `task`, `completed`
correct code is:
class _HomePageState extends State<HomePage> {
List<Map<String, dynamic>> toDoList = [
{"task": "Make Tutorial", "completed": false},
{"task": "Do Exercise", "completed": false}
];
void checkBoxChanged(bool? value, int index) {
setState(() {
toDoList[index]["completed"] = !toDoList[index]["completed"];
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.yellow[200],
appBar: AppBar(
backgroundColor: Theme.of(context).primaryColor,
title: Center(child: Text("TO DO")),
elevation: 0,
),
body: ListView.builder(
itemCount: toDoList.length,
itemBuilder: (context, index) {
return TodoTile(
taskName: toDoList[index]["task"], // Corrected key
taskCompleted: toDoList[index]["completed"], // Corrected key
onChanged: (value) => checkBoxChanged(value, index),
);
},
),
);
}
}
Firstly, make Function(bool?)? onChanged;
final to allow constant constructor for widget.
Secondly, the main problem is in
List toDoList = [
{"Make Tutorial", false},
{"Do Exercise", false}
];
I would reccommend not to use raw types because IDE shows you that the type of toDoList
is List<dynamic>
. But if you would write this like
final toDoList = [ // or var but you never override it
{"Make Tutorial", false},
{"Do Exercise", false}
];
you would see that the type is actually List<Set<Object>>
.
void checkBoxChanged(bool? value, int index){
setState(() {
toDoList[index][1] = !toDoList[index][1];
});
}
Here, you are trying to get item of Set<Object> by index but it's impossible because set is not sorted as it calculates hashes to store items.
Make data class for todo items containing
String name
andbool isChecked
Don't use raw generics like
List
. Always specifiy the type or leave it to the compiler.
Also, you could replace Set
in toDoList with List
and it would worked but it's very nasty and unstable solution)