RangeError (index): Invalid value. Valid value range is empty: 0 - list

Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Icon(
password[0] == null ? unchangedPassword : changedPassword, //Error happens here
color: Colors.white,
size: 20,
),
)
]
)
Can someone please explain why I can't write an if statement that checks if the value at the index is equal to a null value?

Use password.isEmpty instead of password[0] == null

password[0] doesn't exist.
It appears password is a List
you could do password[0] == null if it was a map, but it's not. It's a list. That value doesn't exist. It's not null. It doesn't exist. So it blows up.
Why doesn't it exist? Because the memory wasn't allocated. Flutter will allocated the memory automatically when you need it. If you do password.add(value), then password[0] will exist at that point. But since you're getting the range error you haven't used password.add
For lists, use password.isNotEmpty or password.length == 0;

I have been also facing this issue and following checking solved my issue
Text("${(subjects.isEmpty) ? "" : subjects.name}"),

Related

tristate || value != null': is not true for a list of CheckBoxListTiles

I am facing this error all of a sudden even when I havn't changed any logic in my code. So apparently the list of CheckBoxListTiles is not being built and this error is being thrown to me. I have no idea why it is being thrown since this is my first time facing this error. Thanks in advance for the help. Also I am attaching the Widget below to which the error is pointing to.
Widget checklistOptions1(String title) {
return CheckboxListTile(
title: Text(
title,
style: Theme.of(context).textTheme.subtitle1,
),
value: values1[title],
onChanged: (isFalse) {
setState(() {
values1[title] = isFalse!;
});
},
activeColor: redAccentColor,
checkboxShape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(4),
),
controlAffinity: ListTileControlAffinity.trailing,
);
}
This is the widget to which the error is pointing to and I dont see anything wrong with it although this widget was working perfectly fine a while ago.
It must mean that values1[title] is null but it needs to be true or false.
Alternatively you indicate tristate: true on the Checkbox. Then null is also allowed

Unable to load asset: Image

I have this code for asset image
Image.asset(
'${listPic[1]}',
),
the images are located in a List
final List<Image> listPic= <Image>[ Image.asset('assets/images/pic1.jpg'), Image.asset('assets/images/pic2.jpg'), ];
I know the pubsec works, because when I directly type the image location like this
Image.asset(
'assets/images/pic1.jpg',
),
the image is displayed,
Is there something wrong with the list or Image.asset()
I have tried using .toString after the ${listPic[0]} it didn't do anything instead said unnecessary string interpolation.
gives this error
The following assertion was thrown resolving an image codec: Unable to load asset: Image(image: AssetImage(bundle: null, name: "assets/images/pic1.jpg"), frameBuilder: null, loadingBuilder: null, alignment: Alignment.center, this.excludeFromSemantics: false, filterQuality: low)
The list you declared is a List<Image> type, but you are using it as if it's a List<String>.
Try this instead:
final List<String> imagePaths = [
'your/path/pic1.jpg',
'your/path/pic2.jpg',
];
Image.asset(
toolImage[1],
)

How to make a list with a for in Dart

This is my first question so I'm sorry if it's not well formatted.
So, I have this object called book with the property "rating," which is an int of the number of stars. My idea is to show in a row said rating as icons and I thought I'd do it with a spread operator and a for.
I don't know if it's possible because I don't find any documentation about it or if the syntax is wrong because it expects and identifier and a ')' See issue. I would appreciate help with this.
child: Row(
children: [...(for (var i = 0; i < book.rating; i++) => Icon(Icons.star))],
),
You can also made by using List generate.
Row(
children: List<Widget>.generate(book.rating, (idx) => Icon(Icons.star)),
);
There are syntax errors. Remove =>, () from start, ...:
child: Row(
children: [for (var i = 0; i < book.rating; i++) Icon(Icons.star)],
),

How do I loop and render through a list of predefined widgets?

So I have a list of predefined choices that I defined below
final List<DropdownMenuItem> grades = <DropdownMenuItem>[
DropdownMenuItem(value: "Highschool", child: Text('Highschool')),
DropdownMenuItem(value: "Senior High", child: Text('Senior High')),
DropdownMenuItem(value: "College", child: Text('College'))];
And what I want to do is traverse through the list and put it under the drop down menu
Form(
child: DropdownButtonHideUnderline(
child: ButtonTheme(
alignedDropdown: true,
child: DropdownButton<String>(
value: defState,
onChanged: (String? newValue) {
setState(() {
defState = newValue!;
});
},
items: grades.map((items) => return items),
hint: Text("Grade"),
),
)),
)
But it's giving me these two errors
The argument type 'Iterable<DropdownMenuItem<dynamic>>' can't be assigned to the parameter type 'List<DropdownMenuItem<String>>?'.
Unexpected text 'return'.
Try removing the text.
Is there a way to iterate the list so I can just immediately return?
A few things:
First, arrow functions don't need the return keyword. For example, the following 2 functions are equivalent:
grades.map((_) => 'hello')
grades.map((_) {
return 'hello';
})
Secondly, the error message says: "you gave me an Iterable<DropdownMenuItem<dynamic>>, but I need a List<DropdownMenuItem<String>>".
You're creating a DropdownButton<String>, which takes a List<DropdownMenuItem<String>> as its items parameter, but you pass in grades.map( ... ).
map() is defined in Iterable, and has the following signature:
Iterable<T> map<T>(T f(E e))
This is a little bit opaque, but crucially, it returns an Iterable<T>, where T is the return type of the function you pass in, for example:
List<int> ints = [1, 2, 3];
Iterable<String> strings = ints.map((i) => i.toString());
To fix your problem, you should do the following:
instead of having a final field with widgets inside, make it a function. You should avoid caching widgets like this (unless they are const) as it interferes with hot-reload. Importantly, the function should also specify the type of DropdownMenuItem it returns:
List<DropdownMenuItem<String>> get grades => [
DropdownMenuItem<String>(...),
...
]
Your map function is invalid, but if you remove the return keyword, it would be (items) => items, which is the identity function (i.e. it does nothing). You can remove this and it will work.
Alternatively, if you want to call some function, you then need to call toList() on the result, since items expects a list:
items: grades,
// or
items: grades.map((grade) => ...).toList(),
Change the type of grades list to List<DropdownMenuItem<String>>:
final List<DropdownMenuItem<String>> grades = [
DropdownMenuItem(value: "Highschool", child: Text('Highschool')),
DropdownMenuItem(value: "Senior High", child: Text('Senior High')),
DropdownMenuItem(value: "College", child: Text('College'))
];
And just use grades instead of a map:
DropdownButton<String>(
value: defState,
onChanged: (String? newValue) {
setState(() {
defState = newValue!;
});
},
items: grades,
hint: Text("Grade"),
),

Iterate with index

Is there a way to iterate through a list having access to the object and the index?
For example, I have:
Row(
children: items.map((item) {
int index = items.indexOf(item);
return widget(index);
}).toList()),
I would like to have something that gives me directly the item and its index, so that I don't have to evaluate the index with:
int index = items.indexOf(item);
but write only:
Row(
children: items.functionThatIWant((index,item) {
return widget(index);
}).toList()),
If you have _current as your index, then you can get the item at the desired index by doing
items.elementAt(_current);
That is assuming that items is indeed a List<T>