This question already has answers here:
Dart Multiple Constructors
(10 answers)
How can I create multiple constructors in dart?
(3 answers)
Closed 2 years ago.
class HomePage extends StatefulWidget {
final String uid;
HomePage({Key key, #required this.uid}) : super(key: key);
final FirebaseUser user;
HomePage({this.user});
#override
_HomePageState createState() => _HomePageState(uid);
}
The default constructor is already defined.
Try giving one of the constructors a name.dart(duplicate_constructor)
i want this two construters to pass on any one can help me in his
You're getting the error because you're trying to make two default constructor. Try making the second one a named constructor to fix the issue.
Note : Dart doesn't support's constructor and method overloading. That's why it comes with named methods that makes them more readable and easy to manage.
class HomePage extends StatefulWidget {
final String uid;
HomePage({Key key, #required this.uid}) : super(key: key);
final FirebaseUser user;
HomePage.user({this.user});
#override
_HomePageState createState() => _HomePageState(uid);
}
Related
I have been working on a flutter project and I have noticed Avoid using private types in public APIs.
Is there a way to fix this warning?
class SubCategoriesPage extends StatefulWidget {
final MainModel mainModel;
// final Ads ad;
const SubCategoriesPage(this.mainModel, {Key? key}) : super(key: key);
#override
_SubCategoriesPage createState() { // Avoid using private types in public APIs.
return _SubCategoriesPage();
}
}
Because createState method return State<Example> so it's preventing returning any private State.
You need to update your code like this.
class SubCategoriesPage extends StatefulWidget {
final MainModel mainModel;
// final Ads ad;
const SubCategoriesPage(this.mainModel, {Key? key}) : super(key: key);
#override
State<SubCategoriesPage> createState() { // Avoid using private types in public APIs.
return _SubCategoriesPage();
}
}
Since this is a StatefulWidget, I'm guessing the _SubCategoriesPage class inherits from State, since it's being returned by createState().
If so, the return type can be changed to State. Since State is public, it can safely be returned from the public createState() method.
Just change _SubCategoriesPage by State
For those using Riverpod, change _SubCategoriesPage by ConsumerState
I had the same issue using this code
class MyPage extends StatefulWidget {
const MyPage({super.key});
#override
_MyPageState createState() => _MyPageState();
}
I tried using this method - State createState() { // Avoid using private types in public APIs.
return _MyPageState();
but than I got this error message - The name MyPageState isn't a type so it can't be used a type argument.
So basically I got an error that says
The instance member 'key' can't be accessed in an initializer.
Try replacing the reference to the instance member with a different expression when I try to make a StatefulWidget as shown below
class UserPage extends StatefulWidget {
UserData userData;
UserPage(this.userData) : super(key: key);
#override
State<StatefulWidget> createState() => new _UserPageState(userData);
}
any solution for this one?
I tried to add 'late' at every point but it doesn't seem to work.
You should do something like this:
class UserPage extends StatefulWidget {
const UserPage({required this.userData, Key? key}) : super(key: key);
final UserData userData;
#override
State<UserPage> createState() => _UserPageState();
}
The key param is not always required. So you can just delete the super part.
class UserPage extends StatefulWidget {
UserData userData;
UserPage(this.userData);
#override
State<StatefulWidget> createState() => new _UserPageState(userData);
}
I try to add multiple constructor in my code but it shows error. help me to solve this.
code :
class NoteModify {
const NoteModify({Key? key}) : super(key: key);
String NoteID;
NoteModify(String x) {
NoteID = x;
}
}
I need to use both constructor. Because I am working with 2 buttons and one button for navigate without sending data to another activity and one button for navigate with data to another activity.
As #Jigar Fumakiya said in his answer, dart doesn't support overloading.
You need to use differently named constructors to fix the error
NoteModify is already declared in this scoped
However, you have another issue, you declared a const constructor and String NoteID is not a final. To declare a const constructor, all the fields must be final.
That is why you get the error
Error: Constructor is marked as 'const' so all fields must be final
If you need the const constructor:
class NoteModify{
const NoteModify({Key? key}) : NoteID = null, super(key: key);
NoteModify.formId({this.NoteID});
final String? NoteID;
}
If you need NoteID to be a variable instead, you'll have to remove the const keyword:
class NoteModify{
NoteModify({Key? key}): super(key: key);
NoteModify.formId({this.NoteID});
String? NoteID;
}
Dart doesn't support methods/constructor overloading. But you can have multiple named constructor
Here
class NoteModify{
String NoteID;
NoteModify({Key key}) {
// main constructor
}
NoteModify.formId({this.NoteID}){
//Here is the named constructor
}
}
Given a stateful widget which takes arguments when it's called, there are two options (that I know of).
I can either use widget.arg to access the data in the state object, or I can create new variables and a new constructor in the state object.
Now I've mostly used the second one and there are some use cases in which the first one causes some problems. However, it looks more concise and readable (I guess).
My question is which one is a better practice?
Example code:
First option:
class Home extends StatefulWidget {
final String email;
const Home({Key key, this.email}) : super(key: key);
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
String example() {
return widget.email;
}
Second option:
class Home extends StatefulWidget {
final String email;
const Home({Key key, this.email}) : super(key: key);
#override
_HomeState createState() => _HomeState(email);
}
class _HomeState extends State<Home> {
final String email;
_HomeState(this.email);
String example() {
return email;
}
I use both approaches, however, i don't use a constructor for the second approach because idk i don't like it. I store a reference in initState. Something like email = widget.email;.
It really depends. It's mostly preference. But i use the widget. approach often, it avoids boilerplate code, and it's a way of identifying which arguments come from the widget vs whcih arguments come from the state.
The flutter team also uses this approach. A LOT. Check the Material AppBar source code. It would be a mess to declare the arguments twice and pass them to _AppBarState. It's cleaner and it works for them. And for me ;)
Don't use the second option, aka having a constructor on State. This is a bad practice.
Use the .widget.property syntax instead.
If you purposefully want to ignore the updates of a property, instead use initState:
class Example {
Example(this.initialText);
final String initialText;
#override
_ExampleState createState() => _ExampleState();
}
class _ExampleState extends State<Example> {
String text;
#override
void initState() {
text = widget.initialText;
}
}
This question already has answers here:
Passing data to StatefulWidget and accessing it in it's state in Flutter
(7 answers)
Closed 3 years ago.
I have a string that contains an information that was passed from previous classes. But i need to use that variable in the state class.
Class of stateful widget that contains the information (String text):
class CreateLevelScreen extends StatefulWidget {
String text;
CreateLevelScreen({Key key, #required this.text}) : super(key: key);
#override
State<StatefulWidget> createState() => _CreateLevelState();
}
State class of stateful widget to retrieve that information text too.
class _CreateLevelState extends State<CreateLevelScreen> {
//need to pass text in here to use it too.
}
When you say
class _CreateLevelState extends State<CreateLevelScreen>
it means _CreateLevelState will manage the state of CreateLevelScreen
so the variables are directly accessible as widget.<variable_name>
thus you have widget.textto be used in _CreateLevelState class if there is a variable text in your CreateLevelScreen class.
You can use text in _CreateLevelState using widget.text.