InitState not executed at start - flutter

Here you have part of my HomeScreen.dart file:
String _mi_email='';
String _mi_nombre='';
String _mis_apellidos='';
String _mi_foto='';
String _mi_clinica='';
String _mi_id='';
class HomeScreen extends StatefulWidget {
#override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
#override
Widget build(BuildContext context) {
void getValues() async {
SharedPreferences sharedPrefs = await SharedPreferences.getInstance();
_mi_email = sharedPrefs.getString('email');
_mi_clinica = sharedPrefs.getString('clinica') ?? "ninguna";
_mi_nombre = sharedPrefs.getString('nombre') ?? "ninguno";
_mis_apellidos = sharedPrefs.getString('apellidos') ?? "ningunos";
_mi_foto = sharedPrefs.getString('foto') ?? "ninguna";
_mi_id = sharedPrefs.getString('id') ?? "0";
}
#override
void initState() {
super.initState();
getValues();
}
...
What I need is to run getValues() every time when HomeScreen starts.
With my current code, it doesn't happen.

You need to write the initState method outside the build methord or inside the _HomeScreenState.
And your code will look like this
String _mi_email='';
String _mi_nombre='';
String _mis_apellidos='';
String _mi_foto='';
String _mi_clinica='';
String _mi_id='';
class HomeScreen extends StatefulWidget {
#override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
void getValues() async {
SharedPreferences sharedPrefs = await SharedPreferences.getInstance();
_mi_email = sharedPrefs.getString('email');
_mi_clinica = sharedPrefs.getString('clinica') ?? "ninguna";
_mi_nombre = sharedPrefs.getString('nombre') ?? "ninguno";
_mis_apellidos = sharedPrefs.getString('apellidos') ?? "ningunos";
_mi_foto = sharedPrefs.getString('foto') ?? "ninguna";
_mi_id = sharedPrefs.getString('id') ?? "0";
}
#override
void initState() {
getValues();
super.initState();
}
#override
Widget build(BuildContext context) {
...

You need to write method getValues(). into class _HomeScreenState not inside build.

Related

owner._debugCurrentBuildTarget == this is not true

There is no problem with the codes but when I run
I get error owner._debugCurrentBuildTarget == this is not true how can i solve this problem
class HomePage extends StatelessWidget{
#override
HomePageState createState() => HomePageState();
#override
dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}
class HomePageState extends State{
late int first, second;
late String islem;
late String result, sonuc;
I think you are missing the StatefulWidget format, try
class HomePage extends StatefulWidget {
const HomePage({super.key});
#override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
late int first, second;
late String islem;
late String result, sonuc;
#override
void initState() {
super.initState();
first = 1;
second = 2;
islem = "islem";
result = "A";
sonuc = "sonuc";
}
#override
Widget build(BuildContext context) {
return Container();
}
}

How to use stateful widget parameters in state class at construction without adding the widget to the tree?

I stumped into a problem where I need to use a StatefulWidget parameter in its state class when it's constructed, but I couldn't find a way to do it since using widget.[whatever variable name] in the state's class constructor returns an unexpected null value, and the initState function only runs when the widget is being drawn to the screen.
For example:
import 'package:flutter/material.dart';
class Test extends StatefulWidget {
final String text;
Test(this.text);
final state = _TestState();
#override
_TestState createState() => state;
}
class _TestState extends State<Test> {
String? changingText;
void updateChangingText(String moreText){
changingText = changingText! + moreText;
}
#override
void initState() {
super.initState();
changingText = widget.text;
}
#override
Widget build(BuildContext context) {
return Text(changingText!);
}
}
class App extends StatelessWidget {
#override
Widget build(BuildContext context) {
var w = Test('test');
w.state.updateChangingText(' text');
return MaterialApp(home: Scaffold(body:
Test('test text')
));
}
}
void main() {
runApp(App());
}
This doesn't work since changingText is being updated before initState gives it its initial value since it only runs when Text is being drawn to the screen and this:
import 'package:flutter/material.dart';
class Test extends StatefulWidget {
final String text;
Test(this.text);
final state = _TestState();
#override
_TestState createState() => state;
}
class _TestState extends State<Test> {
String? changingText;
void updateChangingText(String moreText){
changingText = changingText! + moreText;
}
_TestState(){
changingText = widget.text;
}
#override
Widget build(BuildContext context) {
return Text(changingText!);
}
}
class App extends StatelessWidget {
#override
Widget build(BuildContext context) {
var w = Test('test');
w.state.updateChangingText(' text');
return MaterialApp(home: Scaffold(body:
Test('test text')
));
}
}
void main() {
runApp(App());
}
doesn't work either since you can't use widget.[whatever] in state class constructors (for some reason).
So what can I do to use widget parameters in the state class before the widget is drawn to the screen?
Thanks in advance for the help
You should use the initState method present in the State for this instead of the constructor
#override
void initState() {
changingText = widget.text;
super.initState();
}

pass one variables value to another variable in flutter

In my flutter app I created variables var from, to; and pass those with their values to the next page. which I used it with the widget.from & widget.to.
but how can i pass this widget.from & widget.to variables to var newFrom, newTo; these variables?
class FirstPage extends StatelessWidget {
#override
Widget build(BuildContext context) {
var from = "Five", to = "Ten";
return SecondPage(from: from, to: to);
}
}
class SecondPage extends StatefulWidget {
final from, to;
const SecondPage({Key key, this.from, this.to}) : super(key: key);
#override
_SecondPageState createState() => _SecondPageState();
}
class _SecondPageState extends State<SecondPage> {
var newFrom = "", newTo = "";
#override
void initState() {
setState(() {
newFrom = widget.from;
newTo = widget.to;
});
super.initState();
}
#override
Widget build(BuildContext context) {
return Container(
child: Text("$newFrom $newTo"),
);
}
}

How to access passed value in the Statefulwidget?

I am passing an String from another StatefulWidget to the below CardItem StatefulWidget and then from here the String is passed to the _CardItemState as shown in the code below.
But how this String passed should be accessed from _CardItemState(String itemTitle);
class CardItem extends StatefulWidget {
String itemTitle;
CardItem({#required this.itemTitle});
#override
_CardItemState createState() => _CardItemState(itemTitle);
}
class _CardItemState extends State<CardItem> {
_CardItemState(String itemTitle);
void initState(){
print("INiatialize");
print("itemTitle is " + );
}
}
You can access it via widget.itemTitle. For your case you can call it like this:
printItem(){
print("itemTitle is ${widget.itemTitle}");
}
void initState(){
printItem();
super.initState();
}
You also don't need to pass the string in your state constructor. Remove this:
_CardItemState(String itemTitle);
easy! grab it using
widget.itemTitle
class CardItem extends StatefulWidget {
String itemTitle;
CardItem({#required this.itemTitle});
#override
_CardItemState createState() => _CardItemState(itemTitle);
}
class _CardItemState extends State<CardItem> {
String itemTitle; // - 1
_CardItemState(this.itemTitle); // - 2
void initState(){
itemTitle = widget.itemTitle; // - 3;
print("INiatialize");
print("itemTitle is " + itemTitle ); // - 4
print("itemTitle is " + widget.itemTitle ); // same as - 4
}
}
Best way to do this is to use
widget.fieldName
class CardItem extends StatefulWidget {
String itemTitle;
CardItem({#required this.itemTitle});
#override
_CardItemState createState() => _CardItemState(itemTitle:itemTitle);
}
class _CardItemState extends State<CardItem> {
String myItemTitle;
#override
void initState(){
super.initState();
myItemTitle=widget.itemTitle;
print("INiatialize");
print("itemTitle is $myItemTitle";
}
}
otherway round to this problem is to pass data in constructor as shown below, but the above method is recommended to be followed.
class CardItem extends StatefulWidget {
String itemTitle;
CardItem({#required this.itemTitle});
#override
_CardItemState createState() => _CardItemState(itemTitle:itemTitle);
}
class _CardItemState extends State<CardItem> {
String itemTitle;
_CardItemState({this.itemTitle});
void initState(){
print("INiatialize");
print("itemTitle is $itemTitle";
}
}

How to ensure code is run only once in a widget?

I do have a lot of code that looks like
this:
bool _somethingFromApiLoaded = false;
Something _somethingFromApi;
loadSomething() async {
final something = await ServiceProvider.of(context).apiService.getSomething();
setState(() => _somethingFromApi = something);
}
#override
Widget build(BuildContext context) {
if (!_somethingFromApiLoaded) {
loadSomething();
_somethingFromApiLoaded = true;
}
}
Note how I produce a lot of boilerplate code to ensure loadSomething is only called once.
I wonder if there isn't a lifecycle method to do so that I somehow misinterpret. I can't use initState because it does not have context.
I would try to a use a StatefulWidget and use initState() method.
That is the lifecycle you are referring to.
You should try to use a Future inside the initState()
#override
void initState() {
super.initState(); // make sure this is called in the beggining
// your code here runs only once
Future.delayed(Duration.zero,() {
_somethingFromApi = await ServiceProvider.of(context).apiService.getSomething();
});
}
As User gegobyte said, Context is available in the initState.
But apparently can't be used for everything.
You can use context in initState() by passing it to the widget:
class HomeScreen extends StatefulWidget {
final BuildContext context;
HomeScreen(this.context);
#override
State<StatefulWidget> createState() => new _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
bool _somethingFromApiLoaded = false;
Something _somethingFromApi;
loadSomething() async {
final something = await ServiceProvider.of(widget.context).apiService.getSomething();
setState(() => _somethingFromApi = something);
}
#override
void initState() {
super.initState();
if (!_somethingFromApiLoaded) {
loadSomething();
_somethingFromApiLoaded = true;
}
}
}