Since I don’t know the number of elements I will receive from my HTTP request with Flutter and Dart, I want to automatically generate cards or even containers to display my results. Here is my code that doesn’t work:
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
class StfNouveauCompte extends StatefulWidget {
const StfNouveauCompte({super.key});
@override
State<StfNouveauCompte> createState() => _StfNouveauCompteState();
}
class _StfNouveauCompteState extends State<StfNouveauCompte> {
String msg="";
var jsonList;
final _formKey=GlobalKey<FormState> ();
final controllernom=TextEditingController();
final controllernconfirmationmotdepasse=TextEditingController();
@override
void dispose() {
super.dispose();
controllernom.dispose();
controllernconfirmationmotdepasse.dispose();
}
Future<void> register(String nom,String prenoms,String mail, telephone,naissance, pseudo, passe1,
passe2
) async {
setState(() {
msg='';
});
try {
var url = Uri.parse('https://konamicash.com/register_app');
var response = await http.post(url, headers: {
"Accept": "application/json",
"Access-Control-Allow-Origin": "*"
},body: {
"nom_utilisateur":nom,
"confirmation_du_mot_de_passe":passe2,
});var codes= response.statusCode;
if(response.statusCode == 200) {
setState(() {
var data= json.decode(response.body);
});
print('it works: ${data}');
print(data.length);var count=data.length;
final List<int> _itemList=List<int>.generate(count,(index)=>index);
ListView.builder(itemBuilder: (BuildContext context,int index){
return Card(
key:Key('$index'),
child: ListTile(
title: Text('$data[0]'),
),
);
},);
} else {
print('Error: ${response.statusCode}');
}
} catch (e) {
print('An error occurred: $e');
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Namis.com'),
backgroundColor: Colors.pink,
),
body:Center(
child: SingleChildScrollView(
child: Form(
key: _formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Container(
margin: EdgeInsets.only(bottom: 15),
child: Text(
'Register',
style: TextStyle(
fontSize: 35,
fontWeight: FontWeight.bold,
color: Colors.grey.shade400),
textAlign: TextAlign.center,
),
),
Container(
padding: EdgeInsets.all(20),
margin: EdgeInsets.only(bottom: 10),
child: TextFormField(
keyboardType: TextInputType.text,
decoration: InputDecoration(
labelText: 'Nom',
border: OutlineInputBorder(),
suffixIcon: Align(
widthFactor: 1.0,
heightFactor: 1.0,
child: Icon(
Icons.person,
),
),
),),),
Container(
padding: EdgeInsets.all(20),
margin: EdgeInsets.only(bottom: 10),
child: TextFormField(
obscureText: true,
keyboardType: TextInputType.text,
decoration: InputDecoration(
labelText: 'password',
border: OutlineInputBorder(),
),
controller: controllernconfirmationmotdepasse,
),
),
SizedBox(
width: double.infinity,
height: 50,
child: ElevatedButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
final nom = controllernom.text;
final confirmationmotdepasse =controllernconfirmationmotdepasse.text;
FocusScope.of(context).requestFocus(FocusNode());
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Envoi en cours')));
register(nom,prenoms,adressemail,telephone,datedenaissance,pseudo,motdepasse,confirmationmotdepasse);
}
},
child: Text('Créer le compte'),
),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text("J'ai déjà un compte..."),
TextButton(
onPressed: () {},
child: Text(
'Je me connecte',
style:
TextStyle(color: Color.fromARGB(255, 245, 11, 11)),
),
),
],
),
//just bellow the sized box where i want to display my different message result_message
SizedBox(height:30 ,),
Text(msg, style: TextStyle(color: Colors.red),),
],
),
),
),
),
);
}
}
To create the right number of containers or cards to put the results of my HTTP request in.
1
Use FutureBuilder
you can check the link for more details about FutureBuilder
edit your register function to return data then use FutureBuilder
to view list of data inside build
Future register(String nom,String prenoms,String mail, telephone,naissance, pseudo, passe1,
passe2
) async {
setState(() {
msg='';
});
try {
var url = Uri.parse('https://konamicash.com/register_app');
var response = await http.post(url, headers: {
"Accept": "application/json",
"Access-Control-Allow-Origin": "*"
},body: {
"nom_utilisateur":nom,
"confirmation_du_mot_de_passe":passe2,
});var codes= response.statusCode;
if(response.statusCode == 200) {
return json.decode(response.body);
} else {
print('Error: ${response.statusCode}');
}
} catch (e) {
print('An error occurred: $e');
}
}
i try to fix you code.
In condition we already know the response will be Map
:
{'status':0, 'message': 'success'}
I already commented what i add and the use of the code.
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
class StfNouveauCompte extends StatefulWidget {
const StfNouveauCompte({super.key});
@override
State<StfNouveauCompte> createState() => _StfNouveauCompteState();
}
class _StfNouveauCompteState extends State<StfNouveauCompte> {
String msg = "";
var jsonList;
final _formKey = GlobalKey<FormState>();
final controllernom = TextEditingController();
final controllernconfirmationmotdepasse = TextEditingController();
// New variable to save the data from API.
//
// [dataFromApi] is nullabel since we need to wait the response from API.
Map<String, dynamic>? dataFromApi;
@override
void dispose() {
super.dispose();
controllernom.dispose();
controllernconfirmationmotdepasse.dispose();
}
String getRegisterStatus() {
// If dataFromApi is null or empty return 'none'
if (dataFromApi == null || dataFromApi!.isEmpty) {
return 'None';
} else {
// If [dataFromApi] is already assigned by response data then returning
// the status from response data.
return '${dataFromApi?['message']}';
}
}
Future<void> register(String nom, String prenoms, String mail, telephone,
naissance, pseudo, passe1, passe2) async {
setState(() {
msg = '';
});
try {
var url = Uri.parse('https://konamicash.com/register_app');
var response = await http.post(url, headers: {
"Accept": "application/json",
"Access-Control-Allow-Origin": "*"
}, body: {
"nom_utilisateur": nom,
"confirmation_du_mot_de_passe": passe2,
});
var codes = response.statusCode;
if (codes == 200) {
// Show response in console log
print('[INFO] your response:n$dataFromApi');
// assign response data to [dataFromApi]
dataFromApi = json.decode(response.body);
// Rebuild state to inform state that [dataFromApi] is changed it's value
setState(() {});
} else {
print('Error: ${response.statusCode}');
}
} catch (e) {
print('An error occurred: $e');
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Namis.com'),
backgroundColor: Colors.pink,
),
body: Center(
child: SingleChildScrollView(
child: Form(
key: _formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Container(
margin: EdgeInsets.only(bottom: 15),
child: Text(
'Register',
style: TextStyle(
fontSize: 35,
fontWeight: FontWeight.bold,
color: Colors.grey.shade400),
textAlign: TextAlign.center,
),
),
Container(
padding: EdgeInsets.all(20),
margin: EdgeInsets.only(bottom: 10),
child: TextFormField(
keyboardType: TextInputType.text,
decoration: InputDecoration(
labelText: 'Nom',
border: OutlineInputBorder(),
suffixIcon: Align(
widthFactor: 1.0,
heightFactor: 1.0,
child: Icon(
Icons.person,
),
),
),
),
),
Container(
padding: EdgeInsets.all(20),
margin: EdgeInsets.only(bottom: 10),
child: TextFormField(
obscureText: true,
keyboardType: TextInputType.text,
decoration: InputDecoration(
labelText: 'password',
border: OutlineInputBorder(),
),
controller: controllernconfirmationmotdepasse,
),
),
SizedBox(
width: double.infinity,
height: 50,
child: ElevatedButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
final nom = controllernom.text;
final confirmationmotdepasse =
controllernconfirmationmotdepasse.text;
FocusScope.of(context).requestFocus(FocusNode());
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Envoi en cours')));
register(
nom,
prenoms,
adressemail,
telephone,
datedenaissance,
pseudo,
motdepasse,
confirmationmotdepasse);
}
},
child: Text('Créer le compte'),
),
),
// New widget to show your response data
Center(
child: Padding(
padding: const EdgeInsets.all(16),
child: Text('Register status = ${getRegisterStatus()}'),
),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text("J'ai déjà un compte..."),
TextButton(
onPressed: () {},
child: Text(
'Je me connecte',
style:
TextStyle(color: Color.fromARGB(255, 245, 11, 11)),
),
),
],
),
//just bellow the sized box where i want to display my different message result_message
SizedBox(
height: 30,
),
Text(
msg,
style: TextStyle(color: Colors.red),
),
],
),
),
),
),
);
}
}
This is just the basic example to use the data for the widget. I suggest you to learn FutureBuilder
for data fetching from API.
Hope it helps! If you have any question please just ask:) thanks.
40