FLUTER DART
I have two files like this
one is stful class like this
class Test extends StatefulWidget {
const Test({Key? key}) : super(key: key);
#override
_TestState createState() => _TestState();
}
class _TestState extends State<Test> {
#override
Widget build(BuildContext context) {
return TextButton(
onPressed: () {
updateField() // here i call function from other page
},
child: null,
);
}
}
and one is function into other file or page like this
updateField()async{
FirebaseFirestore.instance.collection("users").doc(currentUser.uid).update({
"faceType" : currentUser.faceType ,
});
setState(() {
currentUser.faceType= faceType;
});
}
but once i use setstate it says setstate is not defined , how can i use it please
thanks
Make sure you're calling setState within the stateful widget.
The setState is a method available within only Stateful widgets.
Anyone outside the stateful widget is just a custom method you wrote.
That being said you can use a state management library of your choice and you'll be able to easily change different states within your stateful widget.
The best part is that the logic code would not have to be within the UI.
You should have a function in the Statefull widget that handles SetState Cases.
and within this function you call whatever functions in other files of your project.
So, in your case you can have a function in the Statfull widget as follows:
class Test extends StatefulWidget {
const Test({Key? key}) : super(key: key);
#override
_TestState createState() => _TestState();
}
class _TestState extends State<Test> {
_updateScreen() async {
try{
await updateField();
setState(() {
// handle the new state with Provider or whatever you prefer
});
}catch(error){
// handle errors
}
}
#override
Widget build(BuildContext context) {
return TextButton(
onPressed: () {
_updateScreen()
},
child: null,
);
}
}
and the other file could has the function as follows:
updateField()async{
FirebaseFirestore.instance.collection("users").doc(currentUser.uid).update({
"faceType" : currentUser.faceType ,
});
}
Related
I want to fire Bloc Event when Screen loads but ..add is not working , also tried using initState() still State is intial.
Also used MultiblocProvider it works but in multiBlocProvider cant pass aurgumnets Required to call API.
class AboutThisProfile extends StatefulWidget {
String seed;
AboutThisProfile({
Key? key,
required this.seed,
}) : super(key: key);
#override
_AboutThisProfileState createState() => _AboutThisProfileState();
}
class _AboutThisProfileState extends State<AboutThisProfile> {
Widget build(BuildContext context) {
return BlocProvider<AboutBloc>(
create: (_) => AboutBloc(widget.seed)..add(CallforAbout()),
child: AboutScafold(
seed: widget.seed,
),
);
}
}
There quote is from Riverpod documentation:
A StatefulWidget that can use Hook
It's usage is very similar to StatefulWidget, but use hooks inside
State.build.
The difference is that it can use Hook, which allows HookWidget to
store mutable data without implementing a State.
besides this, I can't find any sample code or another tutorial or any description more than the quote.
in this simple HookWidget how can I implement that with StatefulHookWidget?
class MyHomePage extends HookWidget {
#override
Widget build(BuildContext context) {
final store = useMemoized(() => MyStore());
return Container();
}
}
A StatefulHookWidget is for when you need to use any of the overridable functions of a regular StatefulWidget - like didChangeDependencies, or initState, or dispose.
Generally, unless you have a really good or niche reason to use StatefulHookWidget, do prefer HookWidget.
Essentially, if we replicate your example, both Class1 and Class2 are equivalent in terms of the end product. The only difference is the verbiage needed to get there.
class Class1 extends HookWidget {
const Class1({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
final store = useMemoized(() => MyStore());
return Container();
}
}
class Class2 extends StatefulHookWidget {
const Class2({Key? key}) : super(key: key);
#override
_Class2State createState() => _Class2State();
}
class _Class2State extends State<Class2> {
#override
Widget build(BuildContext context) {
final store = useMemoized(() => MyStore());
return Container();
}
}
I am on the latest version of riverpod so I am using StatefulHookConsumerWidget
Following is one way to implement StatefulHookConsumerWidget. This might give you a hint for your answer
class MyHomePage extends StatefulHookConsumerWidget {
#override
_MyHomePage State createState() => _SocietyHomeState();
}
class MyHomePage extends ConsumerState<SocietyHome> {
Widget build(BuildContext context) {
return Container();
}
}
I have a stateful widget that has one method called in initialisation. I wanna know how to be able to get a parameter from the previous screen and pass it in initState to my initialisation method
class LabDetalheWidget extends StatefulWidget {
final String path;
const LabDetalheWidget({
Key key,
this.path,
}) : super(key: key);
You can pass parameter like that
class MyWidget extends StatefulWidget {
final String param;
const MyWidget({
Key key,
this.param,
}) : super(key: key);
#override
_MyWidgetState createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
#override
void initState() {
print(widget.param);
super.initState();
}
#override
Widget build(BuildContext context) {
return Container(
);
}
}
Inside the state you can access the parameter like that
print(widget.param)
I believe you wanna pass data across routes.. If so then read this flutter cookbook's section you might get the idea
https://flutter.dev/docs/cookbook/navigation/passing-data
I am using the ScopedModel pattern, but I am also interested how this same problem is addressed in the similar Provider pattern.
Currently I have a ScopedModel with a bool exposed called loggedIn. When the FirebaseonAuthStateChanged stream changes user log in state, my ScopedModel changes that bool, and calls NotifyListeners. All straight forward stuff.
Now I am confused as to the best way to push or pop routes based on this ScopedModel.
Should all my logged in screens (screens that require a user) have the following code in build method?
WidgetsBinding.instance.addPostFrameCallback((_) {
if (!auth.hasUser)
Navigator.of(context).pushNamedAndRemoveUntil('/entry', (Route<dynamic> route) => });
});
That seems a little excessive to have this code on every single screen. Is there a way I can define this log screen change behaviour somewhere only once?
create a Widget for it ;)
class Validation extends StatefulWidget {
final Function validator;
final Widget child;
const Validation({Key key, this.validator, this.child}) : super(key: key);
#override
_ValidationState createState() => _ValidationState();
}
class _ValidationState extends State<Validation> {
#override
void initState() {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
widget.validator();
});
super.initState();
}
#override
Widget build(BuildContext context) {
return widget.child;
}
}
now use it everywhere
#override
Widget build(BuildContext context) {
return Validation(
validator: (){
if (!auth.hasUser){
Navigator.of(context).pushNamedAndRemoveUntil('/entry', (Route<dynamic> route) => false);
}
},
child: MyAwesomePage(),
);
}
you can further simplify if the validation is same everywhere or create multiple validation widget according to the validations required,
FOR YOUR CASE
class LoginValidation extends StatefulWidget {
final String routeIfNotLoggedIn;
final Widget child;
const LoginValidation({Key key, this.routeIfNotLoggedIn, this.child}) : super(key: key);
#override
_LoginValidationState createState() => _LoginValidationState();
}
class _LoginValidationState extends State<LoginValidation> {
#override
void initState() {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
if (!auth.hasUser){
Navigator.of(context).pushNamedAndRemoveUntil(widget.routeIfNotLoggedIn, (Route<dynamic> route) => false);
}
});
super.initState();
}
}
and use it
#override
Widget build(BuildContext context) {
return LoginValidation(
routeIfNotLoggedIn: "/myLoginRoute",
child: MyAwesomePage(),
);
}
In main, the body of my scaffold is a custom stateful widget. This custom widget has a function inside its state class. Is it possible to call this function from the floating action button in the main file's scaffold?
I don't see how 'wire' the onPressed function of the floating action button to call the function inside the state class of the widget in the scaffold's body.
You can use function callback like this
class Screen extends StatefulWidget {
Screen({Key key}) : super(key: key);
#override
_ScreenState createState() => _ScreenState(methodCaller: myMethod);
String myMethod(int value) {
return 'example';
}
}
class _ScreenState extends State<Screen> {
final String Function(int value) methodCaller;
_ScreenState({this.methodCaller});
#override
Widget build(BuildContext context) {
var value = methodCaller(12);
return Container();
}
}
Hope this is helpful!