After days of useless attempts, I'm new with Flutter, I can only ask for help from those who know more than me
I need to read the value of 'G'
that I get from an await that executes a query to a database and returns an eventObject object composed of:
id:
object:
(see better in the figure)
having a futures that returns exactly
return new EventObject (
id: ...,
object: gruppiJsonParsing.gruppo);
and gruppiJsonParsing that returns an instance of the Gruppi class with:
final String utente;
final String G;
with:
var groupName = eventObject.object;
I only get:
Instance of 'Gruppi'
then, since as in figure 0 = ['Gruppi']
I would think I could write
Gruppi groupName = eventObject.object;
String groupUser = groupName.G;
But so I get instead
Unhandled Exception: type 'List <Groups'' is not a subtype of type 'Gruppi'
Thanks for any precious suggestions
Aa required here the code of GruppiJsonParsing.dart
import 'package:flutter_client_php_backend/models/Gruppi.dart';
class GruppiJsonParsing {
final String result;
final String message;
final List<Gruppi> gruppo;
GruppiJsonParsing({this.result, this.message, this.gruppo});
factory GruppiJsonParsing.fromJson(Map<String, dynamic> json) {
return GruppiJsonParsing(
result: json['result'],
message: json['message'],
gruppo: parseGruppi(json['gruppo']));
}
static List<Gruppi> parseGruppi(json) {
List<Gruppi> gruppiList = new List<Gruppi>();
for (var log in json) {
gruppiList.add(new Gruppi(G: log['G']));
}
return gruppiList;
}
Map<String, dynamic> toJson() =>
<String, dynamic>{'result': result, 'message': message, 'gruppo': gruppo};
}
If you json string look like this
{"result":"success","message":"Query Successful","gruppo":
[{"utente":null,"G":"utente1"}]}
you can parse with
final eventObject = eventObjectFromJson(jsonString);
print('${eventObject.gruppo[0].g}');
related class
// To parse this JSON data, do
//
// final eventObject = eventObjectFromJson(jsonString);
import 'dart:convert';
EventObject eventObjectFromJson(String str) => EventObject.fromJson(json.decode(str));
String eventObjectToJson(EventObject data) => json.encode(data.toJson());
class EventObject {
String result;
String message;
List<Gruppo> gruppo;
EventObject({
this.result,
this.message,
this.gruppo,
});
factory EventObject.fromJson(Map<String, dynamic> json) => EventObject(
result: json["result"] == null ? null : json["result"],
message: json["message"] == null ? null : json["message"],
gruppo: json["gruppo"] == null ? null : List<Gruppo>.from(json["gruppo"].map((x) => Gruppo.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"result": result == null ? null : result,
"message": message == null ? null : message,
"gruppo": gruppo == null ? null : List<dynamic>.from(gruppo.map((x) => x.toJson())),
};
}
class Gruppo {
dynamic utente;
String g;
Gruppo({
this.utente,
this.g,
});
factory Gruppo.fromJson(Map<String, dynamic> json) => Gruppo(
utente: json["utente"],
g: json["G"] == null ? null : json["G"],
);
Map<String, dynamic> toJson() => {
"utente": utente,
"G": g == null ? null : g,
};
}
full code
import 'package:flutter/material.dart';
// To parse this JSON data, do
//
// final eventObject = eventObjectFromJson(jsonString);
import 'dart:convert';
EventObject eventObjectFromJson(String str) => EventObject.fromJson(json.decode(str));
String eventObjectToJson(EventObject data) => json.encode(data.toJson());
class EventObject {
String result;
String message;
List<Gruppo> gruppo;
EventObject({
this.result,
this.message,
this.gruppo,
});
factory EventObject.fromJson(Map<String, dynamic> json) => EventObject(
result: json["result"] == null ? null : json["result"],
message: json["message"] == null ? null : json["message"],
gruppo: json["gruppo"] == null ? null : List<Gruppo>.from(json["gruppo"].map((x) => Gruppo.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"result": result == null ? null : result,
"message": message == null ? null : message,
"gruppo": gruppo == null ? null : List<dynamic>.from(gruppo.map((x) => x.toJson())),
};
}
class Gruppo {
dynamic utente;
String g;
Gruppo({
this.utente,
this.g,
});
factory Gruppo.fromJson(Map<String, dynamic> json) => Gruppo(
utente: json["utente"],
g: json["G"] == null ? null : json["G"],
);
Map<String, dynamic> toJson() => {
"utente": utente,
"G": g == null ? null : g,
};
}
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
// This is the theme of your application.
//
// Try running your application with "flutter run". You'll see the
// application has a blue toolbar. Then, without quitting the app, try
// changing the primarySwatch below to Colors.green and then invoke
// "hot reload" (press "r" in the console where you ran "flutter run",
// or simply save your changes to "hot reload" in a Flutter IDE).
// Notice that the counter didn't reset back to zero; the application
// is not restarted.
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
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();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
String jsonString = '{"result":"success","message":"Query Successful","gruppo":[{"utente":null,"G":"utente1"}]}';
void _incrementCounter() {
final eventObject = eventObjectFromJson(jsonString);
print('${eventObject.gruppo[0].g}');
setState(() {
// This call to setState tells the Flutter framework that something has
// changed in this State, which causes it to rerun the build method below
// so that the display can reflect the updated values. If we changed
// _counter without calling setState(), then the build method would not be
// called again, and so nothing would appear to happen.
_counter++;
});
}
#override
Widget build(BuildContext context) {
// This method is rerun every time setState is called, for instance as done
// by the _incrementCounter method above.
//
// The Flutter framework has been optimized to make rerunning build methods
// fast, so that you can just rebuild anything that needs updating rather
// than having to individually change instances of widgets.
return Scaffold(
appBar: AppBar(
// Here we take the value from the MyHomePage object that was created by
// the App.build method, and use it to set our appbar title.
title: Text(widget.title),
),
body: Center(
// Center is a layout widget. It takes a single child and positions it
// in the middle of the parent.
child: Column(
// Column is also a layout widget. It takes a list of children and
// arranges them vertically. By default, it sizes itself to fit its
// children horizontally, and tries to be as tall as its parent.
//
// Invoke "debug painting" (press "p" in the console, choose the
// "Toggle Debug Paint" action from the Flutter Inspector in Android
// Studio, or the "Toggle Debug Paint" command in Visual Studio Code)
// to see the wireframe for each widget.
//
// Column has various properties to control how it sizes itself and
// how it positions its children. Here we use mainAxisAlignment to
// center the children vertically; the main axis here is the vertical
// axis because Columns are vertical (the cross axis would be
// horizontal).
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.display1,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
Output
I/flutter (19854): utente1
Related
https://flutterigniter.com/checking-null-aware-operators-dart/
Null check operator used on a null value
These links say that if the value can be null then we can use ?? operator to assign a value to it. I tried it, it still shows the same error:
This is the data structure.
main.dart
import 'package:flutter/material.dart';
import 'dart:convert';
BigData bigDataFromJson(String str) => BigData.fromJson(json.decode(str));
class BigData {
BigData({
this.data,
});
Data? data;
factory BigData.fromJson(Map<String, dynamic> json) => BigData(
data: Data.fromJson(json["data"]),
);
Map<String, dynamic> toJson() => {
"data": data!.toJson(),
};
}
class Data {
Data({
this.lockoutDetails,
});
bool? lockoutDetails;
factory Data.fromJson(Map<String, dynamic> json) => Data(
lockoutDetails: json["lockout_details"],
);
Map<String, dynamic> toJson() => {
"lockout_details": lockoutDetails,
};
}
Here from the default application of Flutter starts:
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
#override
State<MyHomePage> createState() => _MyHomePageState();
}
Here I have used the variable lockoutDetails from the above datastructures and it shows the error null check operator used on a null value.
class _MyHomePageState extends State<MyHomePage> {
BigData d = BigData();
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child:
d.data!.lockoutDetails ?? true
? const Text(
'AAA',
)
: Container(),
));
}
}
What is the way to correct it?
you can use ? instead of ! which means that it may or maynot be null. If you add ! you are mentioning that its not null but the value is unknown
d.data?.lockoutDetails ?? true
d.data is null in this case, you can replace
d.data!.lockoutDetails ?? true
with
d.data?.lockoutDetails ?? true
Your d.data is null.
For test run use d.data?.lockoutDetails.
Think to set data for to have value.
I followed the docs to integerate a native libarary into flutter. https://docs.flutter.dev/development/platform-integration/platform-channels?tab=android-channel-java-tab.
Every things working when I use one method channel as in the mentioned docs. But as I Call result.success(); multiple times flutter is giving expection.
Native Code of Android.
package com.example.batterylevel;
import androidx.annotation.NonNull;
import io.flutter.embedding.android.FlutterActivity;
import io.flutter.embedding.engine.FlutterEngine;
import io.flutter.plugin.common.MethodChannel;
import android.content.ContextWrapper;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.BatteryManager;
import android.os.Build.VERSION;
import android.os.Build.VERSION_CODES;
public class MainActivity extends FlutterActivity {
private static final String CHANNEL = "samples.flutter.dev/battery";
#Override
public void configureFlutterEngine(#NonNull FlutterEngine flutterEngine) {
super.configureFlutterEngine(flutterEngine);
new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), CHANNEL)
.setMethodCallHandler(
(call, result) -> {
if (call.method.equals("getBatteryLevel")) {
int batteryLevel = getBatteryLevel();
if (batteryLevel != -1) {
result.success(batteryLevel);
} else {
result.error("UNAVAILABLE", "Battery level not available.", null);
}
}
if(call.method.equals("getPluginData")){
String pluginData = getPluginData();
result.success(pluginData);
// if (batteryLevel != -1) {
//
// result.success(batteryLevel);
// } else {
// result.error("UNAVAILABLE", "Battery level not available.", null);
// }
}
//
else {
result.notImplemented();
}
}
);
}
private int getBatteryLevel() {
int batteryLevel = -1;
if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) {
BatteryManager batteryManager = (BatteryManager) getSystemService(BATTERY_SERVICE);
batteryLevel = batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY);
} else {
Intent intent = new ContextWrapper(getApplicationContext()).
registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
batteryLevel = (intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1) * 100) /
intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
}
return batteryLevel;
}
private String getPluginData(){
return "This is the plugin Data";
}
}
Flutter Dart Code.
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:flutter/services.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
// This is the theme of your application.
//
// Try running your application with "flutter run". You'll see the
// application has a blue toolbar. Then, without quitting the app, try
// changing the primarySwatch below to Colors.green and then invoke
// "hot reload" (press "r" in the console where you ran "flutter run",
// or simply save your changes to "hot reload" in a Flutter IDE).
// Notice that the counter didn't reset back to zero; the application
// is not restarted.
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required 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
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
static const platform = MethodChannel('samples.flutter.dev/battery');
String _batteryLevel = 'Unknown battery level.';
String _pluginData = 'Unknow Plugin Data';
Future<void> _getBatteryLevel() async {
String batteryLevel;
try {
final int result = await platform.invokeMethod('getBatteryLevel');
batteryLevel = 'Battery level at $result % .';
} on PlatformException catch (e) {
batteryLevel = "Failed to get battery level: '${e.message}'.";
}
setState(() {
_batteryLevel = batteryLevel;
});
}
Future<void> _getPluginData() async {
String pluginData;
try {
final String result = await platform.invokeMethod('getPluginData');
pluginData = 'Plugin Data at $result % .';
} on PlatformException catch (e) {
pluginData = "Failed to get Plugin Data: '${e.message}'.";
}
setState(() {
_pluginData = pluginData;
});
}
int _counter = 0;
void _incrementCounter() {
setState(() {
// This call to setState tells the Flutter framework that something has
// changed in this State, which causes it to rerun the build method below
// so that the display can reflect the updated values. If we changed
// _counter without calling setState(), then the build method would not be
// called again, and so nothing would appear to happen.
_counter++;
});
_getBatteryLevel();
_getPluginData();
}
#override
Widget build(BuildContext context) {
// This method is rerun every time setState is called, for instance as done
// by the _incrementCounter method above.
//
// The Flutter framework has been optimized to make rerunning build methods
// fast, so that you can just rebuild anything that needs updating rather
// than having to individually change instances of widgets.
return Scaffold(
appBar: AppBar(
// Here we take the value from the MyHomePage object that was created by
// the App.build method, and use it to set our appbar title.
title: Text(widget.title),
),
body: Center(
// Center is a layout widget. It takes a single child and positions it
// in the middle of the parent.
child: Column(
// Column is also a layout widget. It takes a list of children and
// arranges them vertically. By default, it sizes itself to fit its
// children horizontally, and tries to be as tall as its parent.
//
// Invoke "debug painting" (press "p" in the console, choose the
// "Toggle Debug Paint" action from the Flutter Inspector in Android
// Studio, or the "Toggle Debug Paint" command in Visual Studio Code)
// to see the wireframe for each widget.
//
// Column has various properties to control how it sizes itself and
// how it positions its children. Here we use mainAxisAlignment to
// center the children vertically; the main axis here is the vertical
// axis because Columns are vertical (the cross axis would be
// horizontal).
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
Text(_batteryLevel),
Text(_pluginData),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: const Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
I am getting incomplete data from a StreamProvider.
The next minimum widget tree reproduces my problem: A SreamProvider over a Tabbed Screen.
My User object contains a map of several values (among other properties) and I use these values for one screen of the Tabbed View by calling final user = Provider.of<User>(context); inside the build() method in order to get these values in this screen whenever the app starts or is completely rebuilt (i.e. hot reload).
The problem: Whenever I switch tabs and go back to this tab, the build() method is called only once with final user = Provider.of<User>(context); returning an incomplete copy of User: some data is missing (some properties of a map inside the User object) and build() is never called again to complete the data (given that the StreamProvider should return the complete object at some point, possibly causing some rebuilds. The result: some data is missing and some widgets of the Screen cannot be built.
class Wrapper extends StatelessWidget {
#override
Widget build(BuildContext context) {
final firebaseUser = Provider.of<FirebaseUser>(context);
// return either Home or Authenticate widget:
if (firebaseUser == null) {
return WelcomeScreen();
} else {
return StreamProvider<User>.value(
value: FirestoreService(uid: firebaseUser.uid).user,
child: TabsWrapper(),
);
}
}
}
class TabsWrapper extends StatefulWidget {
final int initialIndex;
TabsWrapper({this.initialIndex: 0});
#override
_TabsWrapperState createState() => _TabsWrapperState();
}
class _TabsWrapperState extends State<TabsWrapper> with TickerProviderStateMixin {
TabController tabController;
#override
void initState() {
super.initState();
tabController = TabController(vsync: this, length: choices.length);
}
#override
Widget build(BuildContext context) {
return DefaultTabController(
initialIndex: widget.initialIndex,
length: 3,
child: Scaffold(
backgroundColor: lightBlue,
bottomNavigationBar: TabBar(
controller: tabController,
labelStyle: navi.copyWith(color: darkBlue),
unselectedLabelColor: darkBlue,
labelColor: darkBlue,
indicatorColor: darkBlue,
tabs: choices.map((TabScreen choice) {
return Tab(
text: choice.title,
icon: Icon(choice.icon, color: darkBlue),
);
}).toList(),
),
body: TabBarView(
controller: tabController,
children: <Widget>[
FirstScreen(),
SecondScreen(),
ThirdScreen(),
],
),
),
);
}
}
The problematic Screen (FirstScreen):
class FirstScreen extends StatelessWidget {
final TabController tabController;
final User user;
FirstScreen ();
#override
Widget build(BuildContext context) {
final user = Provider.of<User>(context);
print('**************************************** ${user.stats}'); //Here I can see the problem
return SomeBigWidget(user: user);
}
}
The print(${user.stats}) shows the incomplete map (stats) and the build() is never called again (with the remaining data) so the User object remains incomplete. It is only called twice (and the data returned with the complete object) when reloading or launching the app.
Any solution will be welcome!
PD: I found a simpler way to reproduce the situation. No need to change tabs:
Inside FirstScreen() I have a column of StatelessWidgets. If I call Provider.of<User>(context) within one of them I get an incomplete version of the object. The user.stats map has half of the key-value pairs that it has when accesing it through Provider.of some widgets above.
This is how the stream is updated from Firebase. (the object is created every time):
Stream<User> get user {
Stream<User> userStream = usersCollection.document(uid).snapshots().map((s) => User.fromSnapshot(s));
return userStream;
}
I also have updateShouldNotify = (_,__) => true;
The User model:
class User {
String uid;
String name;
String country;
Map stats;
User.fromUID({#required this.uid});
User.fromSnapshot(DocumentSnapshot snapshot)
: uid = snapshot.documentID,
name = snapshot.data['name'] ?? '',
country = snapshot.data['country'] {
try {
stats = snapshot.data['stats'] ?? {};
} catch (e) {
print('[User.fromSnapshot] Exception building user from snapshot');
print(e);
}
}
}
This is the stats data Map in Firestore:
Although firebase does allow you to use a map as a type for you to use I don't think it is your best option in this case, as it seems to be confusing.
There are multiple solutions to your problem.
The best one I think is to make a collection side by side your users collection called "stats" and have the docid of each stat = the userid of the user with that stats, this makes querying easier for you in the future.
after this you can use the method you have already used to get the stats just like you get the users.
class Stat {
String statid;
int avg;
int avg_score;
List<int> last_day;
int n_samples;
int total_score;
int words;
Stat.fromSnapshot(DocumentSnapshot snapshot){
statid = snapshot.documentID,
avg = snapshot.data['average'] ?? '',
//rest of data
}
}
perhaps the simple solution that you need is to change your map in the User class to this.
Map<String, dynamic> stats = Map<String, dynamic>();
remove the try and catch block, then you should be able to access your data like this user.stats['average'];
hope this helps, I will update my answer when I can actually put this to the test in an emulator, but if you try it and it works let me know.
I'm using MaterialApp with router to navigate to the next screen, i'm Using this for navigate to another screen with passing the Arguments :
onTap: () => Navigator.of(context).pushNamed(
DetailDebt.routedName,
arguments: {
'receiverName': debtListView.receiverName,
'amount': debtListView.amount,
'dateReturn': debtListView.dateReturn,
'pathImage': debtListView.imageReceiver,
'signatureImage': debtListView.imageSignature,
},
),
In the next screen i'm make variable to store the argument like this :
final Map arguments = ModalRoute.of(context).settings.arguments as Map;
return Scaffold(
body: Container(
child: Text(
arguments['receiverName'],
),
),
);
My question is , How to store the Argument in variable then i can call it something like this :
// I want Store the Arguments in the variable , so i can call it something like this :
final Map arguments = ModalRoute.of(context).settings.arguments as Map;
final loadedArguments = arguments; // <= ???
return Scaffold(
body: Container(
child: Text(
loadedArguments.receiverName,
),
),
);
And It's My Model if you need it :
import 'dart:typed_data';
import 'package:hive/hive.dart';
part 'debt_model_hive.g.dart';
#HiveType()
class DebtModelHive extends HiveObject {
#HiveField(0)
String receiverName;
#HiveField(1)
int amount;
#HiveField(2)
DateTime dateReturn;
#HiveField(3)
String imageReceiver;
#HiveField(4)
Uint8List imageSignature;
DebtModelHive({
this.receiverName,
this.amount,
this.dateReturn,
this.imageReceiver,
this.imageSignature,
});
// Hive fields go here
}
Thank's
I'll show you a simple example how to pass arguments to your page. Here I push a new named route with int value in arguments:
onPressed: () {
Navigator.of(context).pushNamed('my_route', arguments: 100);
},
In my MaterialApp I set onGenerateRoute parameter to generate a new route with given arguments:
onGenerateRoute: (settings) {
switch (settings.name) {
case 'my_route': return MaterialPageRoute(
builder: (context) => HomePage(settings.arguments as int), // passing arguments
settings: settings,
);
default: throw Exception('Unknown route');
}
},
Now I can access the value inside of build method:
class HomePage extends StatefulWidget {
final int arguments;
HomePage(this.arguments, {Key key}) : super(key: key);
#override
State<StatefulWidget> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
int value;
#override
void initState() {
super.initState();
value = widget.arguments;
}
#override
Widget build(BuildContext context) {
return Text('Value from arguments: ${widget.arguments}');
}
}
Alternatively, you can set the value from route's arguments inside of initState like this:
int value;
#override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
setState(() {
value = ModalRoute.of(this.context).settings?.arguments;
});
print('setting value from route arguments');
});
}
Though, it's pretty dirty and I don't recommend doing this.
"Only static members can be accessed in initializers" is shown when I call my variable usertype.
This variable usertype is declared inside my extends class.
String usertype;
Then inside my extends class I made another variable where I set it as final data.
final data = Data(
typeofUser: usertype
);
You can init with initState()
code snippet
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
String usertype = "abc";
Data data;
#override
void initState() {
data = Data(
typeofUser: usertype
);
super.initState();
}
full code
import 'package:flutter/material.dart';
// To parse this JSON data, do
//
// final data = dataFromJson(jsonString);
import 'dart:convert';
Data dataFromJson(String str) => Data.fromJson(json.decode(str));
String dataToJson(Data data) => json.encode(data.toJson());
class Data {
String typeofUser;
Data({
this.typeofUser,
});
factory Data.fromJson(Map<String, dynamic> json) => Data(
typeofUser: json["typeofUser"] == null ? null : json["typeofUser"],
);
Map<String, dynamic> toJson() => {
"typeofUser": typeofUser == null ? null : typeofUser,
};
}
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
// This is the theme of your application.
//
// Try running your application with "flutter run". You'll see the
// application has a blue toolbar. Then, without quitting the app, try
// changing the primarySwatch below to Colors.green and then invoke
// "hot reload" (press "r" in the console where you ran "flutter run",
// or simply save your changes to "hot reload" in a Flutter IDE).
// Notice that the counter didn't reset back to zero; the application
// is not restarted.
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
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();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
String usertype = "abc";
Data data;
#override
void initState() {
data = Data(
typeofUser: usertype
);
super.initState();
}
void _incrementCounter() {
print('${data.typeofUser}');
setState(() {
// This call to setState tells the Flutter framework that something has
// changed in this State, which causes it to rerun the build method below
// so that the display can reflect the updated values. If we changed
// _counter without calling setState(), then the build method would not be
// called again, and so nothing would appear to happen.
_counter++;
});
}
#override
Widget build(BuildContext context) {
// This method is rerun every time setState is called, for instance as done
// by the _incrementCounter method above.
//
// The Flutter framework has been optimized to make rerunning build methods
// fast, so that you can just rebuild anything that needs updating rather
// than having to individually change instances of widgets.
return Scaffold(
appBar: AppBar(
// Here we take the value from the MyHomePage object that was created by
// the App.build method, and use it to set our appbar title.
title: Text(widget.title),
),
body: Center(
// Center is a layout widget. It takes a single child and positions it
// in the middle of the parent.
child: Column(
// Column is also a layout widget. It takes a list of children and
// arranges them vertically. By default, it sizes itself to fit its
// children horizontally, and tries to be as tall as its parent.
//
// Invoke "debug painting" (press "p" in the console, choose the
// "Toggle Debug Paint" action from the Flutter Inspector in Android
// Studio, or the "Toggle Debug Paint" command in Visual Studio Code)
// to see the wireframe for each widget.
//
// Column has various properties to control how it sizes itself and
// how it positions its children. Here we use mainAxisAlignment to
// center the children vertically; the main axis here is the vertical
// axis because Columns are vertical (the cross axis would be
// horizontal).
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.display1,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
output
I/flutter (30889): abc