Passing data between two flutter classes - flutter

I am calling the below class:
`HomePage(encryptedCipher: args as Uint8List))`
I am passing encryptedCipher (important secret)
In the HomePage:
`class HomePage extends StatefulWidget {
final Uint8List encryptedCipher;
const HomePage({Key? key, required this.encryptedCipher}) : super(key:key);
#override
State<HomePage> createState() => _HomePageState();
}`
In _HomePageState() class, I am accessing it via the below method:
`#override
void initState() {
super.initState();
encryptedCipher = widget.encryptedCipher;
}`
Question: Is this safe and can a hacker have access to encryptedCipher, while it is passed between classes?
I tried doing research on if this method is safe, but have not been able to find helpful articles.

It is safe to pass an encrypted value like encryptedCipher between two classes as long as the encryption method used is secure and the key used to encrypt the data is kept secret.
Accessing the encryptedCipher via the widget property in the _HomePageState class is also safe since the widget property is only accessible within the context of the State object and is not accessible outside of it.
And since encryptedCipher is not stored in the memory of the device in a way that would allow an attacker to access it, then you should not be concerned about this.

Related

How to get the State<> instance inside of its StatefulWidget?

I have an unusual use case where I'd like to add a getter to a StatefulWidget class that accesses its State instance. Something like this:
class Foo extends StatefulWidget {
Foo({super.key});
int get bar => SomethingThatGetsFooState.bar;
#override
State<Foo> createState() => _FooState();
}
class _FooState extends State<Foo> {
int bar = 42;
#override
Widget build(BuildContext context) {
return Container();
}
}
Does SomethingThatGetsFooState exist?
I wonder, if your approach is the right way.
Flutter's way isn't 'Ask something about its state'
Flutter is much more like this: 'The consumer of a Widget passes something to another Widget, which the other Widget e.g. calls in case of certain situations (e.g. value change).'
Approach 1
You map pass a Callback Function to Foo and pass that along to _FooState.
If something special happens inside _FooState, you may call the callback and thus pass some value back to the provider of the Callback.
Approach 2
Probably use a state management solution like Flutter Redux. Using Flutter Redux, you establish a state store somewhere at the top of the widget tree, e.g. in MaterialApp.
Then you subscribe to the store at certain other locations, where dependent widgets exist, which need to update accordingly.
In one project I created certain Action classes, which I send to certain so called reducers of those states, to perform a change on the state:
StoreProvider.of<EModel>(context).dispatch( SaveToFileAction())
This call finds the relevant EModel state and asks it to perform the SaveToFileAction().
This way, a calling Widget not even needs to know, who is responsible for the Action.
The responsible Widget can even be moved around the widget tree - and the application still works. The initiator of SaveToFileAction() and the receiver are decoupled. The receiver you told a coordination 'Tell me, if someone tried to ask me for something.'
Could your provide some further details? Describe the usage pattern?
#SteAp is correct for suggesting there's a code smell in my OP. Typically there's no need to access State thru its StatefulWidget. But as I responded to his post, I'm fleshing out the first pass at a state management package, so it's an unusual case. Once I get it working, I'll revisit.
Below worked without Flutter complaining.
class _IntHolder {
int value;
}
class Foo extends StatefulWidget {
Foo({super.key});
final _intHolder = _IntHolder();
int get bar => _intHolder.value;
#override
State<Foo> createState() => _FooState();
}
class _FooState extends State<Foo> {
int value = 42;
#override
Widget build(BuildContext context) {
widget._intHolder.value = value;
return Container();
}
}

When setting up a stateful widget, does it matter if we use "const"?

I haven't given it much thought up until now, but I've seen example code with and without the const in the
class ScreenBuilder extends StatefulWidget {
ScreenBuilder({ Key? key, required this.tVars, required this.randomHash, this.overrideMe = false, this.gotoSp = 0}) : super(key:key);
final ThreadVars tVars;
final String randomHash;
final bool overrideMe;
final int gotoSp;
#override
_ScreenBuilderState createState() => _ScreenBuilderState();
}
Specifically talking about this line:
ScreenBuilder({ Key? key, required this.tVars, required this.randomHash, this.overrideMe = false, this.gotoSp = 0}) : super(key:key);
vs
const ScreenBuilder({ Key? key, required this.tVars, required this.randomHash, this.overrideMe = false, this.gotoSp = 0}) : super(key:key);
What is the difference if any? My widget seems to work the same in either permutation
For bonus points, I remember reading an article that mentioned if I were to call my ScreenBuilder(...) widget like this: const ScreenBuilder(...) I would see some performance improvements but putting a const infront of it of course throws a whole bunch of getter errors
You can use the const keyword before your constructor when all your class properties are declared as final. Eventually, it will make them immutable in any scenario in future.
For example, if you create an instance of that class you will not be able to change the value of those properties using that instance.
In fact, using const before the constructor can contribute to the betterment of performance as it prevents unnecessary rebuild of widget properties. Moreover it saves memory too.
Try this article, very well explained. I am adding an excerpt here below,
The fact that it saves memory is not the only importance of const widgets. Because an object is marked as constant, flutter knows that in the case of a rebuild, it makes no sense to rebuild that object since “it should not have changed”. This is a great performance boost as once an object is built, in the lifetime of the app, it will remain the same, and that is just spectacular and improves even the hot restart functionality of flutter as it knows where and what to rebuild based on changes.

Flutter Stateful Widget Constructor That Does Not Include All Members

I am building a Stateful Widget in Flutter, and as such, there is a requirement for all arguments passed in the constructor to be final (since Stateful widgets are marked with the #immutable annotation).
Thing is, I want to have two different constructors for my widget and to exclude some of the members of the Stateful widget, depending on the constructor used. I have to stress, that I do not want these arguments to be optional, but mandatory.
For example,
class MyWidget extends StatefulWidget {
MyWidget.first({this.firstArgument}};
MyWidget.second({this.secondArgument});
final int firstArgument;
final String secondArgument;
#override
MyWidget createState() => MyWidgetState();
}
When I write this, I get a compiler error, telling me that:
All final variables must be initialized, but 'firstArgument' isn't.
The same goes for the second member variable.
How can I overcome this?
I can't move firstArgument and secondArgument to the state of MyWidget, since I want them to be initialized in the constructor(s) and also because they should not be changed.
I can't mark them as not final since then I will get a compiler warning and also break the Stateful widget paradigm.
Is there a different approach I should use?
Thing is, I want to have two different constructors for my widget and to exclude some of the members of the Stateful widget, depending on the constructor used. I have to stress, that I do not want these arguments to be optional, but mandatory.
If you don't want them to be optional, you need to mark them as required:
MyWidget.first({required this.firstArgument}};
MyWidget.second({required this.secondArgument});
(If you don't have null-safety enabled, you will instead need to use the weaker #required annotation from package:meta.)
My understanding is that you want firstArgument and secondArgument to be required for MyWidget.first and MyWidget.second respectively but that they are not intended to be required together (that is, only one should be set).
You could fix this by explicitly initializing both values in the constructors:
MyWidget.first({required this.firstArgument}} : secondArgument = null;
MyWidget.second({required this.secondArgument}): firstArgument = null;
If you have null-safety enabled, you also would need to make your members nullable:
final int? firstArgument;
final String? secondArgument;
Maybe factory constructors would help?
class MyWidget extends StatefulWidget {
MyWidget._({this.firstArgument, this.secondArgument}};
factory MyWidget.first({#required int first})=>MyWidget._(firstArgument: first, );
factory MyWidget.second({#required String second})=>MyWidget._(secondArgument: second, );
final int firstArgument;
final String secondArgument;
#override
MyWidget createState() => MyWidgetState();
}
This way, you'll only be able to build this widget using these constructors (since the class constructor is private) and when you call MyWidget.first the value for secondArgument for the widget will be null, and the same applies when you use MyWidget.second with firstArgument

What does this (initialisation?) line do in the flutter example app Flutter?

I'm teaching myself Dart and Flutter, and I'm having a look at the example app that is loaded when you generate a fresh Dart project in IntelliJ.
The first line of the MyHomePage class is confusing me, I'm not actually sure what it is doing. Obviously the call to super is passing the key to the inherited class, which makes me think the MyHomePage call is the constructor of the class.
But then the {Key key, this.title}, is creating an object with a key and title variable, where exactly is it getting key from? Is it automatically injecting the value of title in this object to the final string title below it?
If someone could explain this line I'd appreciate it.
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
// This widget is the home page of your application. It is stateful, meaning
// that it has a State object (defined below) that contains fields that affect
// how it looks.
// This class is the configuration for the state. It holds the values (in this
// case the title) provided by the parent (in this case the App widget) and
// used by the build method of the State. Fields in a Widget subclass are
// always marked "final".
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
These are optional parameters when you want to pass a parameter to a class at creation, you will put a variable of your preference
final String title;
and you can pass it as a parameter when creating an object
_MyHomePageState(title : 'hello world');
Keep in mind these are named optional parameters you can ignore them if you like as the example used none of them.
_MyHomePageState();//no parameters passed.
and for more kinds of parameters such as named, optional and others check this link

Flutter StatefulWidget

Looking at the StatefulWidget usage, I am wondering about the design decision to have circular dependency like this:
class YellowBird extends StatefulWidget {
const YellowBird({ Key key }) : super(key: key);
#override
_YellowBirdState createState() => _YellowBirdState();
}
class _YellowBirdState extends State<YellowBird> {
#override
Widget build(BuildContext context) {
return Container(color: const Color(0xFFFFE306));
}
}
example is taken from Flutter StatefulWidget docs
Any thoughts?
This is (one of the) correct way's to build a stateful widget and is properly in line with the flutter documentation.
This is not a circular dependency. You are defining a Stateful Widget class, and a corresponding State class.
The Widget contains a State object (or rather a sub-class of it), using the principle of composition-over-inheritance.
From the Stateful widget documentation:
StatefulWidget instances themselves are immutable and store their mutable state either in separate State objects that are created by the createState method, or in objects to which that State subscribes, for example Stream or ChangeNotifier objects, to which references are stored in final fields on the StatefulWidget itself.
This way Flutter framework can better manage the manipulation and change of this Widget's data. For example (from the link above):
[...] multiple State objects might be associated with the same StatefulWidget if that widget has been inserted into the tree in multiple places.
This principle of composition-over-inheritance is a core-concept of Flutter framework and most IDE's can create this boilerplate code for you automatically (e.g. typing stful on AndroidStudio suggests the StatefulWidgets class and its State related class) so you don't have to worry about it.