Flutter invalid constant value (on excercise from flutter apprentice book) - flutter

When creating this stateless widget I try to assign a TextDecoration value to a widget attribute based on the value of a boolean attribute from the object being passed to it on creation.
textDecoration = item.isComplete ? TextDecoration.lineThrough : TextDecoration.none,
On this row it marks item.isComplete as an error, saying invalid constant value.
Is it because isComplete in the class is defined with the late keyword and therefore it could be null? I checked all the possible causes for which the invalid constant value error migh arise and I still haven't made any sort of dent into it.
The widget:
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:intl/intl.dart';
import '../models/grocery_item.dart';
class GroceryTile extends StatelessWidget {
final GroceryItem item;
final Function(bool?)? onComplete;
final TextDecoration textDecoration;
const GroceryTile({
Key? key,
required this.item,
this.onComplete,
}) : textDecoration = item.isComplete // Error here
? TextDecoration.lineThrough
: TextDecoration.none,
super(key: key);
#override
Widget build(BuildContext context) {
return Container();
}
}
The class:
import 'package:flutter/painting.dart';
enum Importance { low, medium, high }
class GroceryItem {
final String id;
final String name;
final Importance importance;
final Color color;
final int quantity;
final DateTime date;
late bool isComplete;
GroceryItem({
required this.id,
required this.name,
required this.importance,
required this.color,
required this.quantity,
required this.date,
this.isComplete = false,
});
GroceryItem copyWith({
String? id,
String? name,
Importance? importance,
Color? color,
int? quantity,
DateTime? date,
bool? isComplete,
}) {
return GroceryItem(
id: id ?? this.id,
name: name ?? this.name,
importance: importance ?? this.importance,
color: color ?? this.color,
quantity: quantity ?? this.quantity,
date: date ?? this.date,
isComplete: isComplete ?? this.isComplete);
}
}

The const constructor cannot have a body and if you want to initialize some value in the constructor body you need to remove the const keyword
//...
GroceryTile({ // <- Remove `const`here
Key? key,
required this.item,
this.onComplete,
}) : textDecoration = item.isComplete
? TextDecoration.lineThrough
: TextDecoration.none,
super(key: key);
//...

Try this:
class GroceryTile extends StatelessWidget {
final GroceryItem item;
final Function(bool?)? onComplete;
final TextDecoration textDecoration;
GroceryTile({
Key? key,
required this.item,
this.onComplete,
}) : textDecoration = item.isComplete
? TextDecoration.lineThrough
: TextDecoration.none,
super(key: key);
#override
Widget build(BuildContext context) {
return Container();
}
}

Related

how to target an element of our class with hive to change it

good morning,
I don't know how to access an element of my boxHive without rebuilding it
I would like to be able to update some information without changing the existing one
Here is how I do it here, I use the constructor of my model class to add notes but it rebuilds all my class at the same time I would like it to rebuild only ListNote
class InformationPatient extends StatefulWidget {
final Patients patients;
final int index;
const InformationPatient(this.patients, this.index, {Key? key})
: super(key: key);
#override
State<InformationPatient> createState() => _InformationPatientState();
}
class _InformationPatientState extends State<InformationPatient> {
late Box<Patients> boxPatient;
#override
void initState() {
super.initState();
boxPatient = Hive.box('Patient');
}
void _addNote(String newtitle, String newnote, String newconclusion) {
final newNOTE = Patients(
listOfNotes: [
ListNote(title: newtitle, note: newnote, conclusion: newconclusion)
],
);
boxPatient.put(widget.index, newNOTE);
Navigator.of(context).pop();
}
And here is my class model
import 'package:hive_flutter/hive_flutter.dart';
part 'listpatient.g.dart';
#HiveType(typeId: 0)
class Patients {
#HiveField(0)
final String? name;
#HiveField(1)
final String? firstname;
#HiveField(3)
final String? dateofbirth;
#HiveField(4)
final String? email;
#HiveField(5)
final String? phonenumber;
#HiveField(6)
final DateTime? date;
#HiveField(7)
final int? id;
#HiveField(8)
final List<ListNote>? listOfNotes;
const Patients({
this.name,
this.firstname,
this.dateofbirth,
this.email,
this.phonenumber,
this.date,
this.id,
this.listOfNotes,
});
}
#HiveType(typeId: 10)
class ListNote {
#HiveField(1)
final String? title;
#HiveField(2)
final String? note;
#HiveField(3)
final String? conclusion;
ListNote({
this.title,
this.note,
this.conclusion,
});
}
Actually Hive offers only Write and Read operations, as you can see from its official documentation for flutter
so in order to update an Object in your boxPatient Box you need to get it with this:
Patients patients = boxPatient.get(widget.index);
then make your edits over it, then save it again on that same key:
boxPatient.put(widget.index, patients);
you can say we just updated it with this process.

How to pass function to class attribute in flutter?

I am trying to assign a function to an class attribute. HOw can i assign that value to that class' attribue.
return MyCartListItem(
cartName: cartList[index]['english_name'],
cartQuantity: 2,
cartImage: path + img,
cartPrice: cartList[index]['mrp'].toString(),
cartIndex: cartList[index],
onItemRemoved: ?? ,
//trying to assing function here
);
const MyCartListItem(
{Key? key,
...
required this.onItemRemoved,
required this.onItemRemoved(index)})
: super(key: key);
final String cartName;
final int cartQuantity;
final String cartImage;
final String cartPrice;
final int cartIndex;
final Function onItemRemoved;
// func here
#override
State<MyCartListItem> createState() => _MyCartListItemState();
}
onItemRemoved(){
}
return MyCartListItem(
cartName: cartList[index]['english_name'],
cartQuantity: 2,
cartImage: path + img,
cartPrice: cartList[index]['mrp'].toString(),
cartIndex: cartList[index],
onItemRemoved: onItemRemoved ,
//trying to assing function here
);
so you have a function like this:
onTap({required String message}){
print(message);
}
in your class pass function argument like this:
class ClassTest extends StatelessWidget {
final Function({required String message}) onTap;
const ClassTest({Key? key, required this.onTap}) : super(key: key);
#override
Widget build(BuildContext context) {
return InkWell(
onTap: ()=>onTap(message: 'your mesage'),
child: Container(),
);
}
}

How to make widget without '?' and 'required'

so im working on company project and realize the widget doesn't need Key? and required costructor, and when i try to make it like that it occur red underline.
my project i want to remove the required and '?'
example of what i want
It should view like that:
class CustomButton extends StatelessWidget {
final double? height;
final double width;
final String title;
final double margin;
final Function() onPressed;
const CustomButton ({
Key? key,
this.height,
required this.width,
required this.title,
required this.margin,
required this.onPressed,
}) : super (key: key);
}
If you want to preserve the non-nullable state of your class, you have to pass an initial value for the CustomButton height property.
class CustomButton extends StatelessWidget {
final double height;
final double width;
final String title;
final double margin;
final Function() onPressed;
const CustomButton ({
Key? key,
this.height = 100,
required this.width,
required this.title,
required this.margin,
required this.onPressed,
}) : super (key: key);
}
you have probably defined height as final and that's why it is asking it.
define height as
double? height

How to make a widget require one of two properties?

So I have a widget that can accept a color or a gradient property :
class OuterWheel extends StatelessWidget {
final double outerRadius;
final double innerRadius;
final TextStyle textStyle;
final double percentage;
final int decimals;
final Color? color;
final List<Color>? gradient;
const OuterWheel({
Key? key,
required this.outerRadius,
required this.innerRadius,
required this.textStyle,
required this.percentage,
required this.decimals,
this.color,
this.gradient,
}) : super(key: key);
I would like to make it like in TypeScript where you could have a union type like Color|List<Color> , so I could only use one property, but apparently we don't have that in Dart.
So how can I make so that you have to choose one of these two fields?
What about mutual exclusive operator?
const OuterWheel({
Key? key,
required this.outerRadius,
required this.innerRadius,
required this.textStyle,
required this.percentage,
required this.decimals,
this.color,
this.gradient,
}) : assert((color == null) ^ (gradient == null), 'color and gradient are mutually exclusive'), super(key: key);
This way you ensure that only one of them, but not both, is not null.

Null check operator used on a null value inherited widget flutter

i am having this null check error, i am creating a inherited widget of global keys , can anyone pls help me to solve this
class KeysToBeInherited extends InheritedWidget {
const KeysToBeInherited(
{Key? key,
required this.add,
required this.card,
required this.color,
required this.bepy,
required this.me,
required this.publish,
required this.child})
: super(key: key, child: child);
final GlobalKey add;
final GlobalKey card;
final GlobalKey color;
final GlobalKey me;
final GlobalKey bepy;
final GlobalKey publish;
final Widget child;
static KeysToBeInherited of(BuildContext context) {
final KeysToBeInherited? result =
context.dependOnInheritedWidgetOfExactType<KeysToBeInherited>();
return result!;
}
#override
bool updateShouldNotify(covariant KeysToBeInherited oldWidget) {
return true;
}
}
..........................................................................................................................................................................................................................................................................
Check if result is not null and then use result!