Related
I have a barchart ,when I click line it will navigate to new page.
I use model.selectedDatum.clear();
but when back to chart page , it is still select,it not working.
How can I set it unselect , when I back to chart page, thank you.
Widget build(BuildContext context) {
return SizedBox(
height: 400,
child: charts.BarChart(
_createSampleData(),
animate: true,
vertical: false,
selectionModels: [
charts.SelectionModelConfig(
type: charts.SelectionModelType.info,
changedListener: (charts.SelectionModel model) {
if (model.hasDatumSelection) {
int month = model.selectedDatum[0].index! + 1;
Get.toNamed(RouteTable.expenseDetailList,
arguments: [_.currentYear, month, _.barSegmentIndex])?.then((value)=>
model.selectedDatum.clear());
}
},)
],
barRendererDecorator: charts.BarLabelDecorator<String>(
labelAnchor: charts.BarLabelAnchor.end),
));
}
List<charts.Series<double, String>> _createSampleData() {
return [
charts.Series<double, String>(
id: 'Month',
domainFn: (value, ix) => months[ix ?? 0],
measureFn: (value, ix) => value,
colorFn: ((value, ix) => charts.Color.fromHex(code: colors[index])),
data: data,
labelAccessorFn: (value, _) => nf.format(value))
];
}
Override userManagedState to handle selectionModels
final _myState = charts.UserManagedState<String>();
#override
Widget build(BuildContext context) {
final chart = charts.BarChart(
// ...
// 1. override userManagedState
userManagedState: _myState,
selectionModels: [
charts.SelectionModelConfig(
changedListener: (model) {
// 2. clear selectionModels
setState(() {
_myState.selectionModels[charts.SelectionModelType.info] = charts.UserManagedSelectionModel();
});
},
],
);
// ...
}
I am using flutter_login for my user onboarding functionality. My only problem is that I cannot override the verification code sent to the email section. How can I send the OTP using a custom API call and also verify the same?. Below is my register screen. I would appreciate any leads on the same or an alternative approach to OTP login using google without firebase. Thank you
import 'package:email_validator/email_validator.dart';
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart' show timeDilation;
import 'package:flutter_login/flutter_login.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:google_sign_in/google_sign_in.dart';
import 'package:konnectsoko/managers/app_state_manager.dart';
import 'package:konnectsoko/managers/profile_manager.dart';
import 'package:provider/provider.dart';
import '../pages/konnectmart_pages.dart';
class RegisterScreen extends StatelessWidget {
static MaterialPage page = MaterialPage(
name: KonnectmartPages.registerPath,
key: ValueKey(KonnectmartPages.registerPath),
child: RegisterScreen());
static const routeName = '/auth';
RegisterScreen({Key? key}) : super(key: key);
Duration get loginTime => Duration(milliseconds: timeDilation.ceil() * 1150);
Future<String?> _loginUser(LoginData data) {
//add login logic here
print(data);
return Future.delayed(Duration(milliseconds: 300));
}
Future<String?> _signupUser(SignupData data) {
//prepare data from the form
final Map<String, dynamic> userData = {
'phone': data.name,
'firstname': data.additionalSignupData!['First Name'],
'lastname': data.additionalSignupData!['Last Name'],
'dob': data.additionalSignupData!['Date Of Birth'],
'gender': data.additionalSignupData!['Gender'],
'email': data.additionalSignupData!['Email'],
'password': data.password
};
//call api endpoint for reg
return Future.delayed(loginTime).then((_) {
return null;
});
}
// Future<String?> _recoverPassword(String name) {
// return Future.delayed(loginTime).then((_) {
// if (!mockUsers.containsKey(name)) {
// return 'User not exists';
// }
// return null;
// });
// }
Future<String?> _signupConfirm(String error, SignupData data) {
return Future.delayed(loginTime).then((_) {
});
}
#override
Widget build(BuildContext context) {
return FlutterLogin(
title: 'Konnectmart',
logo: const AssetImage('image/img2.png'),
navigateBackAfterRecovery: true,
onConfirmSignup: (String error, LoginData data) {
//we have phone
//invoke otp endpoint here
//confirm otp
return Future.delayed(loginTime).then((_) {
Provider.of<AppStateManager>(context, listen: false).login();
});
},
hideForgotPasswordButton: false,
loginAfterSignUp: true,
loginProviders: [
LoginProvider(
button: Buttons.Facebook,
label: 'Sign in with Facebook',
callback: () async {},
providerNeedsSignUpCallback: () {
// put here your logic to conditionally show the additional fields
return Future.value(true);
},
),
LoginProvider(
icon: FontAwesomeIcons.google,
label: 'Google',
callback: () async {
final _googleSignIn = GoogleSignIn();
await _googleSignIn.signIn();
print(_googleSignIn.currentUser);
Provider.of<AppStateManager>(context, listen: false).login();
Provider.of<ProfileManager>(context, listen: false)
.showGoogleProfile(_googleSignIn.currentUser);
},
),
],
termsOfService: [
TermOfService(
id: 'general-term',
mandatory: true,
text: 'Term of services',
linkUrl: 'https://github.com/Dmaina5054/'),
],
additionalSignupFields: [
// const UserFormField(
// keyName: 'Username', icon: Icon(FontAwesomeIcons.userLarge)),
UserFormField(
keyName: 'Date Of Birth',
fieldValidator: (value) {
//perform date validation here
},
),
const UserFormField(keyName: 'First Name'),
const UserFormField(keyName: 'Last Name'),
UserFormField(keyName: 'Email', fieldValidator: _emailValidator),
const UserFormField(keyName: 'Gender'),
],
initialAuthMode: AuthMode.signup,
scrollable: true,
hideProvidersTitle: false,
disableCustomPageTransformer: true,
messages: LoginMessages(
additionalSignUpFormDescription:
'Tell us more about you. \n Please fill the details below',
confirmationCodeHint: 'Enter code sent to your phone',
userHint: 'Phone',
passwordHint: 'Password',
confirmPasswordHint: 'Confirm Password',
loginButton: 'LOG IN',
signupButton: 'REGISTER',
forgotPasswordButton: 'Forgot password?',
recoverPasswordButton: 'Reset',
goBackButton: 'GO BACK',
confirmPasswordError: 'Not match!',
recoverPasswordIntro: 'Don\'t feel bad. Happens all the time.',
recoverPasswordDescription: 'Your password will be reset',
recoverPasswordSuccess: 'Password rescued successfully',
flushbarTitleError: 'Oh no!',
flushbarTitleSuccess: 'Succes!',
),
buttonTheme: LoginButtonTheme(
// splashColor: Colors.blue,
// backgroundColor: Colors.blue,
highlightColor: Colors.lightGreen,
elevation: 9.0,
highlightElevation: 6.0,
shape: BeveledRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
),
),
userValidator: (value) {
var phoneRegExp = RegExp(
'^(\\+\\d{1,2}\\s)?\\(?\\d{3}\\)?[\\s.-]?\\d{3}[\\s.-]?\\d{4}\$');
if (value != null && value.length < 9 && !phoneRegExp.hasMatch(value)) {
return "Please enter a valid phonenumber";
}
return null;
},
passwordValidator: (value) {
if (value!.isEmpty) {
return 'Password is empty';
}
return null;
},
onLogin: (loginData) {
debugPrint('Login info');
debugPrint('Name: ${loginData.name}');
debugPrint('Password: ${loginData.password}');
Provider.of<AppStateManager>(context, listen: false).login();
return _loginUser(loginData);
},
onSignup: (signupData) {
debugPrint('Signup info');
debugPrint('Name: ${signupData.name}');
debugPrint('Password: ${signupData.password}');
signupData.additionalSignupData?.forEach((key, value) {
debugPrint('$key: $value');
});
if (signupData.termsOfService.isNotEmpty) {
debugPrint('Accept Terms of service: ');
for (var element in signupData.termsOfService) {
debugPrint(
' - ${element.term.id}: ${element.accepted == true ? 'accepted' : 'rejected'}');
}
}
final Map<String, dynamic> userData = {
'phone': signupData.name,
'firstname': signupData.additionalSignupData!['First Name'],
'lastname': signupData.additionalSignupData!['Last Name'],
'dob': signupData.additionalSignupData!['Date Of Birth'],
'gender': signupData.additionalSignupData!['Gender'],
'email': signupData.additionalSignupData!['Email'],
'password': signupData.password
};
//hit our endpoint
Provider.of<ProfileManager>(context, listen: false).registerUser(
firstname: userData['firstname'],
lastname: userData['lastname'],
phone: userData['phone'],
email: userData['email'],
gender: userData['gender'],
dob: userData['dob'],
password: userData['password']);
return _signupConfirm('noerr',signupData);
},
onSubmitAnimationCompleted: () {
print('completed');
},
onRecoverPassword: (name) {
debugPrint('Recover password info');
debugPrint('Name: $name');
return _recoverPassword(name);
// Show new password dialog
},
showDebugButtons: false,
userType: LoginUserType.phone,
);
}
_recoverPassword(String name) {
print(name);
}
Widget buildDateField(BuildContext context) {
// 1
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// 2
Row(
// 3
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
// 4
Text(
'Date',
style: GoogleFonts.lato(fontSize: 28.0),
),
// 5
],
),
// 9
],
);
}
String? _emailValidator(String? value) {
if (value!.isEmpty) {
return 'Email needed';
} else if (!EmailValidator.validate(value, true)) {
return 'Enter a valid email';
} else {
return null;
}
}
}
The methods provider either expects a return of null if otp entered by user was correct or a message indicating what failed. I added my verify otp endpoint call and now works as expected.
I have a list of items that were received from API. I want to print a particular value of that selected item from the list. The list is,
[
{
'id': '1',
'name': 'roy',
'designation': 'engineer',
},
{
'id': '2',
'name': 'john',
'designation': 'doctor',
},
{
'id': '3',
'name': 'rose',
'designation': 'clerk',
}
];
From this list, if I select john from the dropdown menu then it should print the designation in the console. If I select rose then it prints clerk in the console. How to achieve this. Below is my code,
import 'package:flutter/material.dart';
class TestPage extends StatefulWidget {
const TestPage({Key? key}) : super(key: key);
#override
State<TestPage> createState() => _TestPageState();
}
class _TestPageState extends State<TestPage> {
List users = [
{
'id': '1',
'name': 'roy',
'designation': 'engineer',
},
{
'id': '2',
'name': 'john',
'designation': 'doctor',
},
{
'id': '3',
'name': 'rose',
'designation': 'clerk',
}
];
String? userId;
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: DropdownButtonHideUnderline(
child: DropdownButton(
isExpanded: true,
hint: const Padding(
padding: EdgeInsets.all(8.0),
child: Text('Select Item'),
),
value: userId,
items: users.map((item) {
return DropdownMenuItem(
child: Text(item['name']),
value: item['id'].toString(),
);
}).toList(),
onChanged: (String? newValue) {
setState(() {
userId = newValue;
});
},
),
),
),
);
}
}
What code I need to add inside onChanged function to get designation of that selected user.
I have 2 JSON file like this:
json1 (API):
[
{
"json1Language": "English",
"json1Icon": "https://www.countryflags.io/gb/flat/64.png",
"json1Code": "en"
},
{
"json1Language": "French",
"json1Icon": "https://www.countryflags.io/fr/flat/64.png",
"json1Code": "fr"
},
{
"json1Language": "Spanish",
"json1Icon": "https://www.countryflags.io/es/flat/64.png",
"json1Code": "es"
}
]
json2 (API):
[
{
"json2Country": "Canada",
"json2Continent": "North American",
"json2Language": [
"French",
"English"
]
},
{
"json2Country": "Mexico",
"json2Continent": "North American",
"json2Language": [
"Spanish",
"English"
]
},
{
"json2Country": "United Kingdom",
"json2Continent": "Europe",
"json2Language": [
"English"
]
},
{
"json2Country": "France",
"json2Continent": "Europe",
"json2Language": [
"French"
]
},
{
"json2Country": "Spain",
"json2Continent": "Europe",
"json2Language": [
"Spanish"
]
}
]
I tried to show the data of json1Code from Json1, it shows an error Flutter: RangeError (index): Invalid value: Valid value range is empty: -1 for a few seconds then shows the data correctly, I'm not sure where I did wrong
I think maybe something wrong in the Build class:
════════ Exception caught by widgets library ═══════════════════════════════════════════════════════
The following RangeError was thrown building Builder(dirty):
RangeError (index): Invalid value: Valid value range is empty: -1
The relevant error-causing widget was:
Builder file:///D:/Flutter/Test/load_data/lib/json2_page3.dart:80:17
When the exception was thrown, this was the stack:
#0 List.[] (dart:core-patch/growable_array.dart:177:60)
#1 _ShowContinentState.build.<anonymous closure> (package:load_data/json2_page3.dart:83:38)
#2 Builder.build (package:flutter/src/widgets/basic.dart:7183:48)
#3 StatelessElement.build (package:flutter/src/widgets/framework.dart:4644:28)
#4 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4570:15)
please help me, this is main file
import 'package:flutter/material.dart';
import 'package:load_data/model/json2_model.dart';
import 'package:load_data/service/json1_service.dart';
import 'package:load_data/service/json2_service.dart';
import 'model/json1_model.dart';
class Json2Page3 extends StatefulWidget {
#override
_Json2Page3State createState() => _Json2Page3State();
}
class _Json2Page3State extends State<Json2Page3> {
List<Json2> json2 = [];
List<String> _continent = [];
#override
void initState() {
super.initState();
setState(() {
Json2Services.getData().then((data) {
setState(() {
json2 = data;
_continent = json2.map<String>((x) => x.json2Continent).toSet().toList();
});
});
});
}
#override
Widget build(BuildContext context) {
return DefaultTabController(
length: _continent.length,
child: Scaffold(
appBar: AppBar(
title: Text('Page 2'),
bottom: TabBar(tabs: _continent.map((String name) => Tab(text: name)).toList()),
),
body: TabBarView(
children: _continent.map((String name) {
return ShowContinent(
json2: List<Json2>.from(json2)..retainWhere((e) => e.json2Continent == name),
);
}).toList()),
));
}
}
class ShowContinent extends StatefulWidget {
final List<Json2> json2;
ShowContinent({this.json2});
#override
_ShowContinentState createState() => _ShowContinentState(json2);
}
class _ShowContinentState extends State<ShowContinent> {
final List<Json2> json2;
List<Json1> json1 = [];
_ShowContinentState(this.json2);
#override
void initState() {
super.initState();
Json1Services.getData().then((data) {
setState(() {
json1 = data;
});
});
}
#override
Widget build(BuildContext context) {
return Column(
children: [
for (Json2 j2 in json2)
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Text(j2.json2Country.toUpperCase()),
for (int i = 0; i < j2.json2Language.length; i++)
Builder(
builder: (_) {
int index = json1.indexWhere((e) => e.json1Language == j2.json2Language[i]);
return Row(
children: [
Image.network(json1[index].json1Icon),
Text(json1[index].json1Code),
],
);
},
)
],
),
],
);
}
}
You can copy paste run full code below
You can use addPostFrameCallback and bool isLoading to check loading status
when isLoading == true, return CircularProgressIndicator()
code snippet
bool isLoading = true;
#override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
Json1Services.getData().then((data) {
setState(() {
json1 = data;
isLoading = false;
});
});
});
}
#override
Widget build(BuildContext context) {
return isLoading
? Center(child: CircularProgressIndicator())
: Column(
working demo
full code
import 'package:flutter/material.dart';
import 'dart:convert';
List<Json2> json2FromJson(String str) =>
List<Json2>.from(json.decode(str).map((x) => Json2.fromJson(x)));
String json2ToJson(List<Json2> data) =>
json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
List<Json1> json1FromJson(String str) =>
List<Json1>.from(json.decode(str).map((x) => Json1.fromJson(x)));
String json1ToJson(List<Json1> data) =>
json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
class Json1 {
Json1({
this.json1Language,
this.json1Icon,
this.json1Code,
});
String json1Language;
String json1Icon;
String json1Code;
factory Json1.fromJson(Map<String, dynamic> json) => Json1(
json1Language: json["json1Language"],
json1Icon: json["json1Icon"],
json1Code: json["json1Code"],
);
Map<String, dynamic> toJson() => {
"json1Language": json1Language,
"json1Icon": json1Icon,
"json1Code": json1Code,
};
}
class Json2 {
Json2({
this.json2Country,
this.json2Continent,
this.json2Language,
});
String json2Country;
String json2Continent;
List<String> json2Language;
factory Json2.fromJson(Map<String, dynamic> json) => Json2(
json2Country: json["json2Country"],
json2Continent: json["json2Continent"],
json2Language: List<String>.from(json["json2Language"].map((x) => x)),
);
Map<String, dynamic> toJson() => {
"json2Country": json2Country,
"json2Continent": json2Continent,
"json2Language": List<dynamic>.from(json2Language.map((x) => x)),
};
}
class Json2Services {
static Future<List<Json2>> getData() async {
await Future.delayed(Duration(seconds: 5), () {});
String jsonString = '''
[
{
"json2Country": "Canada",
"json2Continent": "North American",
"json2Language": [
"French",
"English"
]
},
{
"json2Country": "Mexico",
"json2Continent": "North American",
"json2Language": [
"Spanish",
"English"
]
},
{
"json2Country": "United Kingdom",
"json2Continent": "Europe",
"json2Language": [
"English"
]
},
{
"json2Country": "France",
"json2Continent": "Europe",
"json2Language": [
"French"
]
},
{
"json2Country": "Spain",
"json2Continent": "Europe",
"json2Language": [
"Spanish"
]
}
]
''';
return Future.value(json2FromJson(jsonString));
}
}
class Json1Services {
static Future<List<Json1>> getData() async {
await Future.delayed(Duration(seconds: 5), () {});
String jsonString = '''
[
{
"json1Language": "English",
"json1Icon": "https://www.countryflags.io/gb/flat/64.png",
"json1Code": "en"
},
{
"json1Language": "French",
"json1Icon": "https://www.countryflags.io/fr/flat/64.png",
"json1Code": "fr"
},
{
"json1Language": "Spanish",
"json1Icon": "https://www.countryflags.io/es/flat/64.png",
"json1Code": "es"
}
]
''';
return Future.value(json1FromJson(jsonString));
}
}
class Json2Page3 extends StatefulWidget {
#override
_Json2Page3State createState() => _Json2Page3State();
}
class _Json2Page3State extends State<Json2Page3> {
List<Json2> json2 = [];
List<String> _continent = [];
#override
void initState() {
super.initState();
setState(() {
Json2Services.getData().then((data) {
setState(() {
json2 = data;
_continent =
json2.map<String>((x) => x.json2Continent).toSet().toList();
});
});
});
}
#override
Widget build(BuildContext context) {
return DefaultTabController(
length: _continent.length,
child: Scaffold(
appBar: AppBar(
title: Text('Page 2'),
bottom: TabBar(
tabs:
_continent.map((String name) => Tab(text: name)).toList()),
),
body: TabBarView(
children: _continent.map((String name) {
return ShowContinent(
json2: List<Json2>.from(json2)
..retainWhere((e) => e.json2Continent == name),
);
}).toList()),
));
}
}
class ShowContinent extends StatefulWidget {
final List<Json2> json2;
ShowContinent({this.json2});
#override
_ShowContinentState createState() => _ShowContinentState(json2);
}
class _ShowContinentState extends State<ShowContinent> {
final List<Json2> json2;
List<Json1> json1 = [];
_ShowContinentState(this.json2);
bool isLoading = true;
#override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
Json1Services.getData().then((data) {
setState(() {
json1 = data;
isLoading = false;
});
});
});
}
#override
Widget build(BuildContext context) {
return isLoading
? Center(child: CircularProgressIndicator())
: Column(
children: [
for (Json2 j2 in json2)
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Text(j2.json2Country.toUpperCase()),
for (int i = 0; i < j2.json2Language.length; i++)
Builder(
builder: (_) {
int index = json1.indexWhere(
(e) => e.json1Language == j2.json2Language[i]);
return Row(
children: [
Image.network(json1[index].json1Icon),
Text(json1[index].json1Code),
],
);
},
)
],
),
],
);
}
}
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: Json2Page3(),
);
}
}
When build() is called, json data is not ready.
So you need to fix code asynchronous.
I suggest one solution 'FutureBuilder'
https://api.flutter.dev/flutter/widgets/FutureBuilder-class.html
I have 2 JSON file:
Json1 file:
[
{
"json1language": "English"
},
{
"json1language": "French"
},
{
"json1language": "Spanish"
}
]
Json2 file:
[
{
"json2country": "Canada",
"json2languages": [
{
"json2language": "English"
},
{
"json2language": "French"
}
]
},
{
"json2country": "Mexico",
"json2languages": [
{
"json2language": "English"
},
{
"json2language": "Spanish"
}
]
},
{
"json2country": "France",
"json2languages": [
{
"json2language": "French"
}
]
}
]
I want that when I click on json1language => showDialog show json2country and json2language that match the condition json2language == json1language
Example: click "English" => show json2country: "Canada"; json2language: "English","French" & json2country: "Mexico"; json2language: "English","Spanish" (because json2language contains "English")
So pls help me, this is the main file
import 'package:flutter/material.dart';
import 'dart:convert';
List<Json1> json1FromJson(String str) => List<Json1>.from(json.decode(str).map((x) => Json1.fromJson(x)));
String json1ToJson(List<Json1> data) => json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
class Json1 {
Json1({
this.json1Language,
});
String json1Language;
factory Json1.fromJson(Map<String, dynamic> json) => Json1(
json1Language: json["json1language"],
);
Map<String, dynamic> toJson() => {
"json1language": json1Language,
};
}
List<Json2> json2FromJson(String str) => List<Json2>.from(json.decode(str).map((x) => Json2.fromJson(x)));
String json2ToJson(List<Json2> data) => json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
class Json2 {
Json2({
this.json2Country,
this.json2Languages,
});
String json2Country;
List<Json2Language> json2Languages;
factory Json2.fromJson(Map<String, dynamic> json) => Json2(
json2Country: json["json2country"],
json2Languages: List<Json2Language>.from(json["json2languages"].map((x) => Json2Language.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"json2country": json2Country,
"json2languages": List<dynamic>.from(json2Languages.map((x) => x.toJson())),
};
}
class Json2Language {
Json2Language({
this.json2Language,
});
String json2Language;
factory Json2Language.fromJson(Map<String, dynamic> json) => Json2Language(
json2Language: json["json2language"],
);
Map<String, dynamic> toJson() => {
"json2language": json2Language,
};
}
class Json1Services {
static Future<List<Json1>> getData() {
String jsonString = '''
[
{
"json1language": "English"
},
{
"json1language": "French"
},
{
"json1language": "Spanish"
}
]
''';
return Future.value(json1FromJson(jsonString));
}
}
class Json2Services {
static Future<List<Json2>> getData() {
String jsonString = '''
[
{
"json2country": "Canada",
"json2languages": [
{
"json2language": "English"
},
{
"json2language": "French"
}
]
},
{
"json2country": "Mexico",
"json2languages": [
{
"json2language": "English"
},
{
"json2language": "Spanish"
}
]
},
{
"json2country": "France",
"json2languages": [
{
"json2language": "French"
}
]
}
]
''';
return Future.value(json2FromJson(jsonString));
}
}
class Json extends StatefulWidget {
#override
_JsonState createState() => _JsonState();
}
class _JsonState extends State<Json> {
List<Json1> _json1 = [];
List<Json2> _json2 = [];
#override
void initState() {
super.initState();
setState(() {
Json1Services.getData().then((data) {
setState(() {
_json1 = data;
});
});
Json2Services.getData().then((data) {
setState(() {
_json2 = data;
});
});
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: SingleChildScrollView(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
for (Json1 j1 in _json1)
RaisedButton(
child: Text(j1.json1Language),
onPressed: () => showDialog(
context: context,
builder: (_) {
return AlertDialog(
content: null,
);
}))
],
),
));
}
}
You can copy paste run full code below
code snippet
filtered = [];
_json2.forEach((element) {
for (int i = 0;
i < element.json2Languages.length;
i++) {
if (element.json2Languages[i].json2Language ==
j1.json1Language) {
filtered.add(element);
}
}
});
...
return AlertDialog(
content: SizedBox(
width: 300,
height: 70,
child: Row(
children: [
Expanded(
flex: 2,
child: Column(
mainAxisAlignment:
MainAxisAlignment.spaceAround,
crossAxisAlignment:
CrossAxisAlignment.center,
children: [
for (int i = 0;
i < filtered.length;
i++)
Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text(
filtered[i].json2Country,
),
for (int j = 0;
j <
filtered[i]
.json2Languages
.length;
j++)
Column(children: [
Text(filtered[i]
.json2Languages[j]
.json2Language)
]),
],
working demo
full code
import 'package:flutter/material.dart';
import 'package:flutter/material.dart';
import 'dart:convert';
List<Json1> json1FromJson(String str) =>
List<Json1>.from(json.decode(str).map((x) => Json1.fromJson(x)));
String json1ToJson(List<Json1> data) =>
json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
class Json1 {
Json1({
this.json1Language,
});
String json1Language;
factory Json1.fromJson(Map<String, dynamic> json) => Json1(
json1Language: json["json1language"],
);
Map<String, dynamic> toJson() => {
"json1language": json1Language,
};
}
List<Json2> json2FromJson(String str) =>
List<Json2>.from(json.decode(str).map((x) => Json2.fromJson(x)));
String json2ToJson(List<Json2> data) =>
json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
class Json2 {
Json2({
this.json2Country,
this.json2Languages,
});
String json2Country;
List<Json2Language> json2Languages;
factory Json2.fromJson(Map<String, dynamic> json) => Json2(
json2Country: json["json2country"],
json2Languages: List<Json2Language>.from(
json["json2languages"].map((x) => Json2Language.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"json2country": json2Country,
"json2languages":
List<dynamic>.from(json2Languages.map((x) => x.toJson())),
};
}
class Json2Language {
Json2Language({
this.json2Language,
});
String json2Language;
factory Json2Language.fromJson(Map<String, dynamic> json) => Json2Language(
json2Language: json["json2language"],
);
Map<String, dynamic> toJson() => {
"json2language": json2Language,
};
}
class Json1Services {
static Future<List<Json1>> getData() {
String jsonString = '''
[
{
"json1language": "English"
},
{
"json1language": "French"
},
{
"json1language": "Spanish"
}
]
''';
return Future.value(json1FromJson(jsonString));
}
}
class Json2Services {
static Future<List<Json2>> getData() {
String jsonString = '''
[
{
"json2country": "Canada",
"json2languages": [
{
"json2language": "English"
},
{
"json2language": "French"
}
]
},
{
"json2country": "Mexico",
"json2languages": [
{
"json2language": "English"
},
{
"json2language": "Spanish"
}
]
},
{
"json2country": "France",
"json2languages": [
{
"json2language": "French"
}
]
}
]
''';
return Future.value(json2FromJson(jsonString));
}
}
class Json extends StatefulWidget {
#override
_JsonState createState() => _JsonState();
}
class _JsonState extends State<Json> {
List<Json1> _json1 = [];
List<Json2> _json2 = [];
#override
void initState() {
super.initState();
setState(() {
Json1Services.getData().then((data) {
setState(() {
_json1 = data;
});
});
Json2Services.getData().then((data) {
setState(() {
_json2 = data;
});
});
});
}
List<Json2> filtered = [];
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: SingleChildScrollView(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
for (Json1 j1 in _json1)
RaisedButton(
child: Text(j1.json1Language),
onPressed: () => showDialog(
context: context,
builder: (_) {
filtered = [];
_json2.forEach((element) {
for (int i = 0;
i < element.json2Languages.length;
i++) {
if (element.json2Languages[i].json2Language ==
j1.json1Language) {
filtered.add(element);
}
}
});
return AlertDialog(
content: SizedBox(
width: 300,
height: 70,
child: Row(
children: [
Expanded(
flex: 2,
child: Column(
mainAxisAlignment:
MainAxisAlignment.spaceAround,
crossAxisAlignment:
CrossAxisAlignment.center,
children: [
for (int i = 0;
i < filtered.length;
i++)
Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text(
filtered[i].json2Country,
),
for (int j = 0;
j <
filtered[i]
.json2Languages
.length;
j++)
Column(children: [
Text(filtered[i]
.json2Languages[j]
.json2Language)
]),
],
)
],
),
)
],
),
),
);
}))
],
),
));
}
}
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: Json(),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}