Constructors with named arguments setting private variables post validations - flutter

For a StatelessWidget, how can I have a constructor with named arguments and set private final variables after doing certain validations.
class MyWidget extends StatelessWidget {
const MyWidget({bool foo}) : /*do validation e.g. ArgumentError.checkNotNull(foo)*/ _foo = foo;
final bool _foo;
#override
Widget build(BuildContext context) {...}
}

Try this:
class MyWidget extends StatelessWidget {
MyWidget({bool foo})
: assert(foo != null), // validation
_foo = foo; // assigning value
final bool _foo;
#override
Widget build(BuildContext context) {...}
}

Related

How to use obs before return widget

I want to use obs before return any widget, how to set this observable action?
class TestController extends GetxController {
var condition = ''.obs;
}
class TestScreen extends StatelessWidget {
final TestController testController = Get.find();
#override
Widget build(BuildContext context) {
// How to set the if conditional statement in obx?
if (testController.condition.value != '') {
...
}
return ...
}
}
class TestScreen extends StatelessWidget {
final TestController testController = Get.find();
#override
Widget build(BuildContext context) {
// How to set the if conditional statement in obx?
return Obx((){
if (testController.condition.value != '') {
return ...
}
return ...
});
}
That's how you use it.

Flutter Class Properties (basics)

How do you pass properties to a widget class in flutter.
Here is a basic class
class ToolbarToggle extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Text(label);
}}
I want to be able to call it
ToolbarToggle(label: 'a label')
Forgive the elementary question.
First you declare a label property, like this:
class ToolbarToggle extends StatelessWidget {
final String label;
#override
Widget build(BuildContext context) {
return Text(label);
}
}
final means the value is immutable, you should add it to every property on a StatelessWidget.
Now we need to declare a Constructor, here is how we do that:
ToolbarToggle(this.label);
This means that when creating a ToolbarToggle, we can do this: ToolbarToggle('some label');. In order to make parameters named, we need to declare the constructor like so:
ToolbarToggle({this.label});
Now it is possible to call ToolbarToggle(label: 'my label');. But this will give an error, because it's possible you don't actually pass any value when calling the constructor. To fix this, you should either make it a required parameter, or give it a default value:
ToolbarToggle({required this.label});
ToolbarToggle({this.label=''});
Here is the final class code:
class ToolbarToggle extends StatelessWidget {
ToolbarToggle({required this.label});
final String label;
#override
Widget build(BuildContext context) {
return Text(label);
}
}
class ToolbarToggle extends StatelessWidget {
final String? label;
const ToolbarToggle({this.label, Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Text(label ?? 'label is null');
}}
Like this, you can pass properties,
Its recommended to use const constructor and a key param ( to uniquely identify incase)
You missed using the label
class ToolbarToggle extends StatelessWidget {
final String label;
ToolbarToggle({required this.label});
#override
Widget build(BuildContext context) {
return Text(label);
}}

All final variables must be initialized, but '' isn't. Try adding an initializer for the field.dartfinal_not_initialized_constructor

I just need to pass an attribute to a constructor AppTheme, but i received an error:
All final variables must be initialized, but '' isn't.
Try adding an initializer for the field.dartfinal_not_initialized_constructor
the code is:
class AppTheme extends StatelessWidget {
const AppTheme({required this.navigator}); // => Cursor error
final Widget navigator,
#override
Widget build(BuildContext context) {
throw UnimplementedError();
}}
class AppTheme extends StatelessWidget {
const AppTheme({required this.navigator});
final Widget navigator; // from , to ;
#override
Widget build(BuildContext context) {
throw UnimplementedError();
}}

How do I access an variable from a StatefulWidget inside an StatelessWidget?

How do I access the variable "selectedTag" from this statefulWidget:
class _AlertDialogOneState extends State<AlertDialogOne> {
Item selectedTag;
...
}
}
inside this statelessWidget :
class CardTile extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Container(...
Pass it as parameter,
class CardTile extends StatelessWidget {
final Item selectedTag;// Add this
CardTile(this.selectedTag); // Add this
#override
Widget build(BuildContext context) {
return Container(...
To pass this variable, you have multiple ways:
Pass it as a constructor when u navigate to this class using your navigator
Navigator.push(
context,
MaterialPageRoute(builder: (context) => CardTile(selectedTag)),
);
class CardTile extends StatelessWidget {
Item selectedTag;
CardTile(this.selectedTag);
#override
Widget build(BuildContext context) {
return Container(...
Use a state management like provider
class ProviderData with ChangeNotifier {
Item selected;
void changeSelection(newSelect) {
selected = newSelect;
changeNotifier();
}
}
and inside any class you need call this:
final providerData = Provider.of<ProviderData>(context);
so you can access the variable or change it using this instance like this:
final variable = providerData.selected;
providerData.changeSelection(newValue);
print(variable);
hope this help but i see that it is better to pass it through the constructor if you are not using a state managemnt, however i just gave you an example for illustration

The value of local variable isn't used

I am new to flutter and I was following a tutorial when this error popped up. The ancestorRenderObjectOfType has deprecated and been replaced by findAncestorRenderObjectOfType so dart is throwing me errors.
What the tutor did in his video of old dart:
static T of<T extends BlocBase>(BuildContext context) {
final type = _typeOf<BlocProvider<T>>();
BlocProvider<T> provider = context
.context.ancestorRenderObjectOfType(type);
return provider.bloc;
}
static Type _typeOf() => T;
}
What I did in my code
static T of<T extends BlocBase>(BuildContext context) {
final type = _typeOf<BlocProvider<T>>();
BlocProvider<T> provider = context
.findAncestorRenderObjectOfType();
return provider.bloc;
}
static Type _typeOf<T>() => T;
}
If I put
BlocProvider<T> provider = context
.findAncestorRenderObjectOfType(type);
I get an error saying
Too many positional arguements. 0 expected, but 1 found.
The ENTIRE code
abstract class BlocBase {
void dispose();
}
//Genric Bloc provider
class BlocProvider<T extends BlocBase> extends StatefulWidget {
BlocProvider({
Key key,
#required this.child,
#required this.bloc,
}) : super(key: key);
final T bloc;
final Widget child;
#override
_BlocProviderState<T> createState() => _BlocProviderState<T>();
static T of<T extends BlocBase>(BuildContext context) {
final type = _typeOf<BlocProvider<T>>();
BlocProvider<T> provider = context
.findAncestorRenderObjectOfType(); //context.ancestorRenderObjectOfType(type); GOTCHA
return provider.bloc;
}
static Type _typeOf<T>() => T;
}
class _BlocProviderState<T> extends State<BlocProvider<BlocBase>> {
#override
void dispose() {
widget.bloc.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return widget.child;
}
}
Thank you!
findAncestorRenderObjectOfType doesnt take the type as argument instead it is a generic method where you can provide the type while calling the method. So your code will be as below:
static T of<T>(BuildContext context) {
BlocProvider<T> provider = context
.findAncestorRenderObjectOfType<BlocProvider<T>>();
return provider.bloc;
}