Flutter Streambuilder to Datatable Headings Repeated - flutter

I am trying to work out how I can get the following data into data table, but I have really struggled, as it keeps repeating the header
import 'dart:async';
import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
class PlayerList extends StatefulWidget {
#override
_PlayerListState createState() => new _PlayerListState();
}
class _PlayerListState extends State<PlayerList> {
StreamController<List<Map<String, dynamic>>> _postsController;
final GlobalKey<ScaffoldState> scaffoldKey = new GlobalKey<ScaffoldState>();
List<Map<String, dynamic>> _list = List();
ScrollController _scrollController = new ScrollController();
int count = 0;
var url = '';
bool fetching = false, endReached = false;
List data;
Future<List<dynamic>> fetchPlayer() async {
url =
'https://supercoach.heraldsun.com.au/2020/api/afl/classic/v1/players-cf?embed=notes%2Codds%2Cplayer_stats%2Cpositions';
final response = await http.get(url);
if (response.statusCode == 200) {
print('fetching player');
return json.decode(response.body);
} else {
throw Exception('Failed to load players');
}
}
loadPlayers() async {
fetchPlayer().then((res) async {
res.forEach((model) => _list.add(model));
_postsController.add(_list);
return res;
});
}
Future<Null> _handleRefresh() async {
fetching = true;
fetchPlayer().then((res) async {
if (res != null) {
res.forEach((model) => _list.add(model));
_postsController.add(_list);
if (res.length < 10) {
endReached = true;
_list.add(Map());
_postsController.add(_list);
}
} else {
_postsController.add(null);
}
fetching = false;
return null;
});
}
#override
void initState() {
_postsController = new StreamController();
loadPlayers();
_scrollController
..addListener(() {
var triggerFetchMoreSize =
0.9 * _scrollController.position.maxScrollExtent;
if (_scrollController.position.pixels > triggerFetchMoreSize &&
!fetching &&
!endReached) {
_handleRefresh();
}
});
super.initState();
}
#override
Widget build(BuildContext context) {
return new Scaffold(
key: scaffoldKey,
appBar: AppBar(
title: Text('Exploring Players'),
),
backgroundColor: Color.fromRGBO(246, 249, 255, 1),
body: Column(children: <Widget>[
Expanded(
child: StreamBuilder(
stream: _postsController.stream,
builder: (BuildContext context, AsyncSnapshot snapshot) {
print('Has error: ${snapshot.hasError}');
print('Has data: ${snapshot.hasData}');
// print('Snapshot Data ${snapshot.data}');
print('Connection State ${snapshot.connectionState}');
if (snapshot.hasError) {
return Text(snapshot.error);
}
if (snapshot.connectionState == ConnectionState.waiting ||
snapshot.hasData == false) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
CircularProgressIndicator(
valueColor: new AlwaysStoppedAnimation<Color>(
Colors.purple)),
// Loader Animation Widget
Padding(padding: const EdgeInsets.only(top: 20.0)),
],
),
);
}
if (snapshot.data == null || snapshot.data.length == 0) {
return Column(
children: <Widget>[
Center(child: Text("Unable to find any players"))
],
);
}
// if (snapshot.hasData == false) {
// return Scaffold(
// backgroundColor: Colors.white,
// body: new Stack(
// fit: StackFit.expand,
// children: <Widget>[
// // Render the Title widget, loader and messages below each other
// new Column(
// mainAxisAlignment: MainAxisAlignment.start,
// children: <Widget>[
// Expanded(
// flex: 1,
// child: Column(
// mainAxisAlignment: MainAxisAlignment.center,
// children: <Widget>[
// CircularProgressIndicator(
// valueColor: AlwaysStoppedAnimation<Color>(
// Colors.purple)),
// // Loader Animation Widget
// Padding(
// padding:
// const EdgeInsets.only(top: 20.0)),
// Text("Finding players"),
// ],
// ),
// ),
// ],
// ),
// ],
// ),
// );
// }
if (snapshot.hasData) {
return Column(
children: <Widget>[
Expanded(
child: Scrollbar(
child: ListView.builder(
controller: _scrollController,
physics: const AlwaysScrollableScrollPhysics(),
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
Map<String, dynamic> player =
snapshot.data[index];
print(snapshot.data[index]);
return DataTable(columns: [
DataColumn(label: Text('Photo')),
DataColumn(label: Text('Player')),
DataColumn(label: Text('Round Results')),
DataColumn(label: Text('Played')),
DataColumn(label: Text('Total Points')),
DataColumn(label: Text('Avg')),
DataColumn(label: Text('3 Rd Avg')),
DataColumn(label: Text('5 Rd Avg')),
], rows: [
DataRow(cells: [
// TableRow(children: [
DataCell(Image.network(
"https://s.afl.com.au/staticfile/AFL%20Tenant/AFL/Players/ChampIDImages/XLarge2020/${player['feed_id']}.png?i10c=img.resize(scale_height:0.2)",
height: 54,
width: 54,
fit: BoxFit.fitWidth)),
DataCell(Column(children: [
Text(
"${player['first_name']} ${player['last_name']}"),
Text(
"${player['positions'][0]['position']}"),
Text(
"${player['player_stats'][0]['price']}")
])),
DataCell(Text(
"${player['player_stats'][0]['points']}")),
DataCell(Text(
"${player['player_stats'][0]['total_games']}")),
DataCell(Text(
"${player['player_stats'][0]['total_points']}")),
DataCell(Text(
"${player['player_stats'][0]['avg']}")),
DataCell(Text(
"${player['player_stats'][0]['avg3']}")),
DataCell(Text(
"${player['player_stats'][0]['avg5']}")),
])
]);
}),
),
),
],
);
}
if (!snapshot.hasData &&
snapshot.connectionState == ConnectionState.done) {
return Text('No Players');
}
if (snapshot.connectionState != ConnectionState.done) {
return Center(
child: CircularProgressIndicator(),
);
}
return Text('No Data');
},
),
)
]));
}
}

import 'dart:async';
import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: PlayerList(),
);
}
}
class PlayerList extends StatefulWidget {
#override
_PlayerListState createState() => _PlayerListState();
}
class _PlayerListState extends State<PlayerList> {
StreamController<List<Player>> _postsController;
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
List<Player> _list = <Player>[];
ScrollController _scrollController = ScrollController();
int count = 0;
var url = '';
bool fetching = false, endReached = false;
List data;
Future<List<dynamic>> fetchPlayer() async {
url =
'https://supercoach.heraldsun.com.au/2020/api/afl/classic/v1/players-cf?embed=notes%2Codds%2Cplayer_stats%2Cpositions';
final response = await http.get(url);
if (response.statusCode == 200) {
print('fetching player');
return json.decode(response.body);
} else {
throw Exception('Failed to load players');
}
}
Future<void> loadPlayers() async {
await fetchPlayer().then((res) async {
for (var model in res) {
_list.add(Player.fromMap(model));
}
_postsController.add(_list);
});
}
Future<void> _handleRefresh() async {
fetching = true;
await fetchPlayer().then((res) async {
if (res != null) {
for (var model in res) {
_list.add(Player.fromMap(model));
}
_postsController.add(_list);
if (res.length < 10) {
endReached = true;
_postsController.add(_list);
}
} else {
_postsController.add(null);
}
fetching = false;
});
}
#override
void initState() {
_postsController = StreamController();
loadPlayers();
_scrollController
..addListener(() {
var triggerFetchMoreSize =
0.9 * _scrollController.position.maxScrollExtent;
if (_scrollController.position.pixels > triggerFetchMoreSize &&
!fetching &&
!endReached) {
_handleRefresh();
}
});
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
key: scaffoldKey,
appBar: AppBar(
title: Text('Exploring Players'),
),
backgroundColor: Color.fromRGBO(246, 249, 255, 1),
body: StreamBuilder<List<Player>>(
stream: _postsController.stream,
builder: (context, snapshot) {
if (snapshot.hasError) {
return Text(snapshot.error);
}
if (snapshot.connectionState == ConnectionState.waiting ||
snapshot.hasData == false) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
CircularProgressIndicator(
valueColor:
AlwaysStoppedAnimation<Color>(Colors.purple)),
// Loader Animation Widget
Padding(padding: const EdgeInsets.only(top: 20.0)),
],
),
);
}
if (snapshot.data == null || snapshot.data.length == 0) {
return Column(
children: <Widget>[
Center(child: Text("Unable to find any players"))
],
);
}
if (snapshot.hasData) {
return SingleChildScrollView(
scrollDirection: Axis.vertical,
child: SingleChildScrollView(
physics: ClampingScrollPhysics(),
scrollDirection: Axis.horizontal,
child: DataTable(
columns: [
DataColumn(label: Text('Photo')),
DataColumn(label: Text('Player')),
DataColumn(label: Text('Round Results')),
DataColumn(label: Text('Played')),
DataColumn(label: Text('Total Points')),
DataColumn(label: Text('Avg')),
DataColumn(label: Text('3 Rd Avg')),
DataColumn(label: Text('5 Rd Avg')),
],
rows: snapshot.data
.map(
(player) => DataRow(cells: [
DataCell(Image.network(
"https://s.afl.com.au/staticfile/AFL%20Tenant/AFL/Players/ChampIDImages/XLarge2020/${player.feedId}.png?i10c=img.resize(scale_height:0.2)",
height: 54,
width: 54,
fit: BoxFit.fitWidth)),
DataCell(Column(
children: <Widget>[
Text('${player.firstName} ${player.lastName}'),
Text(player.position),
Text(player.price.toString()),
],
)),
DataCell(
Text(player.points.toString()),
),
DataCell(Text(player.totalGames.toString())),
DataCell(Text(player.totalPoints.toString())),
DataCell(Text(player.avg.toString())),
DataCell(Text(player.avg3.toString())),
DataCell(Text(player.avg5.toString())),
]),
)
.toList(),
),
),
);
}
if (!snapshot.hasData &&
snapshot.connectionState == ConnectionState.done) {
return Text('No Players');
}
if (snapshot.connectionState != ConnectionState.done) {
return Center(
child: CircularProgressIndicator(),
);
}
return Text('No Data');
},
));
}
}
class Player {
final String firstName;
final String lastName;
final String position;
final int price;
final int points;
final String feedId;
final int totalGames;
final int totalPoints;
final num avg;
final num avg3;
final num avg5;
Player({
#required this.firstName,
#required this.lastName,
#required this.position,
#required this.price,
#required this.points,
#required this.feedId,
#required this.totalGames,
#required this.totalPoints,
#required this.avg,
#required this.avg3,
#required this.avg5,
});
factory Player.fromMap(Map<String, dynamic> player) {
return Player(
avg: player['player_stats'][0]['avg'],
avg3: player['player_stats'][0]['avg3'],
avg5: player['player_stats'][0]['avg5'],
feedId: player['feed_id'],
firstName: player['first_name'],
lastName: player['last_name'],
points: player['player_stats'][0]['points'],
position: player['positions'][0]['position'],
price: player['player_stats'][0]['price'],
totalGames: player['player_stats'][0]['total_games'],
totalPoints: player['player_stats'][0]['total_points'],
);
}
}

Related

flutter carousel slider doesn't refresh items

i am new at flutter, so i tried to implement carousel slider with images, i receive an List with my model from server and i created widget but it shows only 1 item from 18... I mean it always show 1 item, but all list is passed
But if i make hot reload then i receive all items, i hope i could explain... my dart code
import 'dart:convert';
import 'package:carousel_slider/carousel_slider.dart';
import 'package:flutter/material.dart';
import 'package:vltest/Models/_easyloaderslist.dart';
import 'Models/_workers.dart';
import 'Widgets/navigation_drawer_widget.dart';
import 'database.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:http/http.dart' as http;
late List<EasyLoadersList> imgList = List.empty();
class Landing extends StatefulWidget {
#override
_LandingState createState() => _LandingState();
}
Future<List<EasyLoadersList>> _getLoaders(Workers workers) async {
final response = await http.get(
Uri.parse(
'http://url'),
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer ${workers.token}"
});
if (response.statusCode == 200) {
Iterable l = json.decode(response.body);
List<EasyLoadersList> loaders = List<EasyLoadersList>.from(
l.map((model) => EasyLoadersList.fromJson(model)));
return loaders;
} else {
throw Exception('Failed to load album');
}
}
List<T> map<T>(List list, Function handler) {
List<T> result = [];
for (var i = 0; i < list.length; i++) {
result.add(handler(i, list[i]));
}
return result;
}
showWorkerDialog(BuildContext context, Workers album) {
// set up the button
Widget okButton = TextButton(
child: Text("OK"),
onPressed: () {
Navigator.pop(context);
},
);
// set up the AlertDialog
AlertDialog alert = AlertDialog(
title: Text(album.name),
content: Text("Hi, ${album.name}"),
actions: [
okButton,
],
);
// show the dialog
showDialog(
context: context,
builder: (BuildContext context) {
return alert;
},
);
}
class _LandingState extends State<Landing> {
String _username = "";
late List<EasyLoadersList> loaders = List.empty();
int _current = 0;
#override
void initState() {
super.initState();
_loadUserInfo();
}
#override
Widget build(BuildContext context) {
return Scaffold(
drawer: NavigationDrawerWidget(),
appBar: AppBar(
title: Text('User info'),
),
body: RefreshIndicator(
onRefresh: () async {
_loadUserInfo();
},
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
CarouselSlider.builder(
itemCount: imgList.length,
itemBuilder: (context, index, realIndex) {
if (imgList.length != 0) {
return buildImage(imgList[index]);
} else {
return loadingData(context);
}
},
options: CarouselOptions(height: 500),
),
]),
),
),
);
}
Widget buildImage(EasyLoadersList loadersList) => Column(
mainAxisSize: MainAxisSize.max,
children: [
AspectRatio(
aspectRatio: 1,
child: Image.network(
loadersList.url,
fit: BoxFit.fill,
),
),
const SizedBox(
height: 30,
),
Text("Address :" + loadersList.shopAddress),
Text("Serial:" + loadersList.serialNumber),
Text("Hours :" + loadersList.currentMotoHours),
Text("Current:" + loadersList.currentMotoHoursUntilTO),
Text("Next:" + loadersList.remainsMotoHoursUntilTO),
Text("Last Use:" + loadersList.lastMotoHoursEditDate),
],
);
Widget loadingData(BuildContext context) {
return Scaffold(
body: Padding(
padding: const EdgeInsets.all(12.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Text(
'Loading...',
style: Theme.of(context).textTheme.headline6,
),
CircularProgressIndicator(
semanticsLabel: 'Loading...',
),
],
),
),
);
}
Future<void> _loadUserInfo() async {
Workers workers = await DBProvider.db.getWorkerInfo();
final prefs = await SharedPreferences.getInstance();
showWorkerDialog(context, workers);
imgList = await _getLoaders(workers);
}
}
Cant see any setState to update the UI. try adding setState on end of refresh like.
onRefresh: () async {
await _loadUserInfo();
setState((){});
},
And on initState
_loadUserInfo().then((value) {setState((){})}):
Or
Future<void> _loadUserInfo() async {
.....
imgList = await _getLoaders(workers);
setState((){});
}

make a pagination with flutter and bloc

ServiceRepo
import 'package:service_youtube/data/service_model.dart';
import 'package:http/http.dart';
class ServicesRepo {
final _url = "http://osamastartup.osamamy-class.com/api/services";
Future<List<Datum>> getServices(int page) async {
final response = await get(Uri.parse("$_url?page=$page"));
final services = serviceFromJson(response.body);
return services.data;
}
}
the _url and everything is correct and return data without any problem
ServiceBloc:
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:service_youtube/blocs/service_bloc/service_event.dart';
import 'package:service_youtube/blocs/service_bloc/service_state.dart';
import '../../data/service_repo.dart';
class ServiceBloc extends Bloc<ServiceEvent, ServiceState> {
final ServicesRepo repo;
int page = 1;
bool isFetching = false;
ServiceBloc(this.repo) : super(ServiceLoadingState()) {
on<LoadServicesEvent>((event, emit) async {
emit(ServiceLoadingState());
try {
final services = await repo.getServices(page);
emit(ServiceLoadedState(services: services));
page++;
} catch(e) {
emit(ServiceErrorState(msg: e.toString()));
}
});
}
}
surly i have all states and events , and there are no problem with them,
ServiceView
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:service_youtube/blocs/internet_bloc/internet_bloc.dart';
import 'package:service_youtube/blocs/service_bloc/service_bloc.dart';
import 'package:service_youtube/blocs/service_bloc/service_event.dart';
import 'package:service_youtube/data/service_model.dart';
import '../blocs/internet_bloc/internet_state.dart';
import '../blocs/service_bloc/service_state.dart';
class ServiceView extends StatelessWidget {
ServiceView({Key? key}) : super(key: key);
final List<Datum> _services = [];
final ScrollController _scrollController = ScrollController();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("Services App"),),
body: Container(
padding: EdgeInsets.all(5),
margin: EdgeInsets.all(5),
child: Center(
child: BlocListener<ConnectedBloc, ConnectedState>(
listener: (context, state) {
if (state is ConnectedSucessState) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Internet Connected')));
} else if (state is ConnectedFailureState) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Internet Lost')));
}
},
child: BlocBuilder<ServiceBloc, ServiceState>(
builder: (context, state) {
if(state is ServiceLoadingState && _services.isEmpty) {
return const CircularProgressIndicator();
} else if (state is ServiceLoadedState) {
_services.addAll(state.services);
context.read<ServiceBloc>().isFetching = false;
return ListView.separated(
controller: _scrollController
..addListener(() {
if (_scrollController.offset ==
_scrollController.position.maxScrollExtent &&
!context.read<ServiceBloc>().isFetching) {
context.read<ServiceBloc>()
..isFetching = true
..add(LoadServicesEvent());
}
}),
itemCount: _services.length,
separatorBuilder: (context, index) => const SizedBox(height: 50),
itemBuilder: (context, index) {
return ListTile(
title: Text(_services[index].name,),
subtitle: Text(_services[index].info,),
leading: CircleAvatar(
radius: 50,
backgroundImage: NetworkImage(_services[index].image),
),
);
},
);
} else if (state is ServiceErrorState && _services.isEmpty) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
IconButton(
onPressed: () {
context.read<ServiceBloc>()
..isFetching = true
..add(LoadServicesEvent());
},
icon: const Icon(Icons.refresh),
),
const SizedBox(height: 15),
Text(state.msg, textAlign: TextAlign.center),
],
);
} else {
return Container();
}
},
),
),
),
),
);
}
}
the data is appear without any problem , but after i scroll show me just a blank screen, without any error message? where is the problem?

Duplicate GlobalKey detected in tree widget scaffoldState

I was trying to update data (add, edit, delete) from my list using API, when I clicked something to update the list e.g deleting an item it showed a successfully updated. but in the Debug Console, there's an error that says
The following assertion was thrown while finalizing the widget tree:
Duplicate GlobalKey detected in the widget tree. The following GlobalKey
was specified multiple times in the widget tree. This will lead to
parts of the widget tree being truncated unexpectedly, because the
second time a key is seen, the previous instance is moved to the new
location. The key was:
[LabeledGlobalKey #47c37] This was determined by noticing that after the widget with the above global key was moved out
of its previous parent, that previous parent never updated during this
frame, meaning that it either did not update at all or updated before
the widget was moved, in either case implying that it still thinks
that it should have a child with that global key.
And when I tried going back to the Previous screen it just showed Blank Screen
Here's the code
Model
import 'dart:convert';
class Nasabah {
int id;
String nama_debitur;
String alamat;
String no_telp;
String no_ktp;
String no_selular;
Nasabah({
this.id = 0,
this.nama_debitur,
this.alamat,
this.no_telp,
this.no_ktp,
this.no_selular,
});
factory Nasabah.fromJson(Map<String, dynamic> json) => Nasabah(
id: json["id"],
nama_debitur: json["nama_debitur"],
alamat: json["alamat"],
no_telp: json["no_telp"],
no_ktp: json["no_ktp"],
no_selular: json["no_selular"],
);
factory Nasabah.fromMap(Map<String, dynamic> map) => Nasabah(
id: map["id"],
nama_debitur: map["nama_debitur"],
alamat: map["alamat"],
no_telp: map["no_telp"],
no_ktp: map["no_ktp"],
no_selular: map["no_selular"],
);
Map<String, dynamic> toJson() => {
"id": id,
"nama_debitur": nama_debitur,
"alamat": alamat,
"no_telp": no_telp,
"no_ktp": no_ktp,
"no_selular": no_selular,
};
#override
String toString() {
return 'Nasabah{id: $id, nama_debitur: $nama_debitur, alamat: $alamat, no_telp: $no_telp, no_ktp: $no_ktp, no_selular: $no_selular}';
}
}
class NasabahResult {
String status;
List<Nasabah> data = new List<Nasabah>();
NasabahResult({
this.status,
this.data,
});
factory NasabahResult.fromJson(Map<String, dynamic> data) => NasabahResult(
status: data["status"],
data: List<Nasabah>.from(
data["data"].map((item) => Nasabah.fromJson(item))),
);
}
NasabahResult nasabahResultFromJson(String jsonData) {
final data = json.decode(jsonData);
return NasabahResult.fromJson(data);
}
String nasabahToJson(Nasabah nasabah) {
final jsonData = nasabah.toJson();
return json.encode(jsonData);
}
Service
import 'package:flutter_auth/Models/nasabah.dart';
import 'dart:convert';
import 'package:http/http.dart' show Client;
class ApiService {
final String baseUrl = '192.168.100.242:8080';
Client client = Client();
Future<List<Nasabah>> getNasabah() async {
final response = await client.get('http://$baseUrl/api/mstdebitur');
print(response.body);
if (response.statusCode == 200) {
final nasabah = (json.decode(response.body) as List)
.map((e) => Nasabah.fromMap(e))
.toList();
return nasabah;
} else {
throw Exception('Failed to load post');
}
}
Future<bool> createNasabah(Nasabah data) async {
String url = new Uri.http("$baseUrl", "/api/mstdebitur/").toString();
final response = await client.post(url,
headers: {"Content-Type": "application/json"},
body: nasabahToJson(data));
if (response.statusCode == 201) {
return true;
} else {
return false;
}
}
Future<bool> updateNasabah(Nasabah data) async {
String url =
new Uri.http("$baseUrl", "/api/mstdebitur/${data.id}").toString();
final response = await client.put(url,
headers: {"Content-Type": "application/json"},
body: nasabahToJson(data));
if (response.statusCode == 200) {
return true;
} else {
return false;
}
}
Future<bool> deleteNasabah(int id) async {
String url = new Uri.http("$baseUrl", "/api/mstdebitur/$id").toString();
final response = await client.delete(url);
if (response.statusCode == 200) {
return true;
} else {
return false;
}
}
}
Home
import 'package:flutter/material.dart';
import 'package:flutter_auth/Models/nasabah.dart';
import 'package:flutter_auth/network/nasabah_service.dart';
import 'FormAddNasabah.dart';
import 'ListNasabah.dart';
GlobalKey<ScaffoldState> _scaffoldState = GlobalKey<ScaffoldState>();
// ignore: must_be_immutable
class DataNasabah extends StatefulWidget {
DataNasabah({Key key}) : super(key: key);
String title;
#override
_DataNasabahState createState() => _DataNasabahState();
}
class _DataNasabahState extends State<DataNasabah> {
ApiService apiService;
ListNasabah _listNasabah;
List<Nasabah> data;
#override
void initState() {
super.initState();
apiService = ApiService();
_listNasabah = new ListNasabah(apiService: apiService);
}
#override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldState,
appBar: AppBar(
title: Text(
'Data Nasabah',
style: TextStyle(color: Colors.white),
),
actions: <Widget>[
GestureDetector(
onTap: () async {
var result = await Navigator.push(
_scaffoldState.currentContext,
MaterialPageRoute(builder: (BuildContext context) {
return FormAddNasabah(nasabah: null);
}),
);
if (result != null) {
setState(() {});
}
},
child: Padding(
padding: const EdgeInsets.only(right: 16.0),
child: Icon(
Icons.add,
color: Colors.white,
),
),
)
],
),
body: _listNasabah.createViewList(),
);
}
}
List
import 'package:flutter/material.dart';
import 'package:flutter_auth/Models/nasabah.dart';
import 'package:flutter_auth/network/nasabah_service.dart';
import 'package:flutter_auth/screens/Menu/DataNasabah/FormAddNasabah.dart';
import 'package:flutter_auth/screens/Menu/DataNasabah/NasabahHome.dart';
import 'package:rflutter_alert/rflutter_alert.dart';
class ListNasabah {
ApiService apiService;
ListNasabah({this.apiService});
Widget createViewList() {
return SafeArea(
child: FutureBuilder(
future: apiService.getNasabah(),
builder: (BuildContext context, AsyncSnapshot<List<Nasabah>> snapshot) {
if (snapshot.hasError) {
return Center(
child: Text(
'Something wrong with message: ${snapshot.error.toString()}',
textAlign: TextAlign.center,
),
);
} else if (snapshot.connectionState == ConnectionState.done) {
List<Nasabah> nasabah = snapshot.data;
return nasabahListView(nasabah);
} else {
return Center(
child: CircularProgressIndicator(),
);
}
},
),
);
}
Widget nasabahListView(List<Nasabah> listnasabah) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 16.0),
child: ListView.builder(
shrinkWrap: true,
itemBuilder: (context, index) {
Nasabah nasabah = listnasabah[index];
return Padding(
padding: const EdgeInsets.only(top: 8.0),
child: Card(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
nasabah.nama_debitur,
style: Theme.of(context).textTheme.bodyText1,
),
Text(nasabah.alamat),
Text(nasabah.no_ktp),
Text(nasabah.no_telp),
Text(nasabah.no_selular),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
FlatButton(
onPressed: () {
apiService.deleteNasabah(nasabah.id).then((value) =>
Navigator.of(context).pushNamed('start'));
},
child: Text(
"Hapus",
style: TextStyle(color: Colors.red),
),
),
FlatButton(
onPressed: () async {
var result = await Navigator.push(context,
MaterialPageRoute(builder: (context) {
return FormAddNasabah(
nasabah: nasabah,
);
}));
},
child: Text(
'Edit',
style: TextStyle(color: Colors.blue),
),
),
],
)
],
),
),
),
);
},
itemCount: listnasabah.length,
),
);
}
}
Form
import 'package:flutter/material.dart';
import 'package:flutter_auth/Models/nasabah.dart';
import 'package:flutter_auth/network/nasabah_service.dart';
import 'package:flutter_auth/screens/Menu/DataNasabah/NasabahHome.dart';
import 'package:rflutter_alert/rflutter_alert.dart';
class FormAddNasabah extends StatefulWidget {
Nasabah nasabah;
FormAddNasabah({this.nasabah});
#override
_FormAddNasabahState createState() => _FormAddNasabahState();
}
class _FormAddNasabahState extends State<FormAddNasabah> {
ApiService apiService;
TextEditingController _contNama = TextEditingController();
TextEditingController _contAlamat = TextEditingController();
TextEditingController _contNoTelp = TextEditingController();
TextEditingController _contNoKtp = TextEditingController();
TextEditingController _contNoSelular = TextEditingController();
#override
void initState() {
super.initState();
apiService = ApiService();
if (widget.nasabah != null) {
_contNama.text = widget.nasabah.nama_debitur;
_contAlamat.text = widget.nasabah.alamat;
_contNoTelp.text = widget.nasabah.no_telp;
_contNoKtp.text = widget.nasabah.no_ktp;
_contNoSelular.text = widget.nasabah.no_selular;
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
iconTheme: IconThemeData(color: Colors.white),
title: Text(
widget.nasabah == null ? "Tambah Nasabah" : "Edit Nasabah",
style: TextStyle(color: Colors.white),
),
),
body: Stack(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
_buildTextField(_contNama, "Nama Nasabah"),
_buildTextField(_contAlamat, "Alamat"),
_buildTextField(_contNoTelp, "No Telp"),
_buildTextField(_contNoKtp, "No KTP"),
_buildTextField(_contNoSelular, "No Selular"),
Padding(
padding: const EdgeInsets.only(top: 8.0),
child: RaisedButton(
child: Text(widget.nasabah == null ? "Tambah" : "Edit"),
color: Colors.blue,
onPressed: () {
int id = 0;
if (widget.nasabah != null) {
id = widget.nasabah.id;
}
Nasabah nasabah = Nasabah(
id: id,
nama_debitur: _contNama.text,
alamat: _contAlamat.text,
no_telp: _contNoTelp.text,
no_ktp: _contNoKtp.text,
no_selular: _contNoSelular.text);
if (widget.nasabah == null) {
apiService.createNasabah(nasabah);
} else {
apiService.updateNasabah(nasabah);
}
Navigator.of(context)
.pushNamed('start')
.whenComplete(() => Navigator.pop(context));
},
),
)
],
),
)
],
),
);
}
Widget _buildTextField(TextEditingController _cont, String label) {
return TextField(
controller: _cont,
keyboardType: TextInputType.emailAddress,
decoration: InputDecoration(
labelText: label,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
),
),
);
}
}
Thank you for your attention!

Setting login cookies in the rest of headers requests Flutter

i'm trying to set the login cookies to the rest of the get requests.
so i use http pachakge and store the login cookies with sharedPreferences and use it in the get request by adding an update function
but i have a problem that when i go to the page i get 400 response just refreshing the page and i get my data and response 200
is there any other solution for setting cookies in the others get requests headers ?
or is there a solution for my bug ?
codes images : [https://ibb.co/kD3dDc9]
[https://ibb.co/25p5fZr]
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:shared_preferences/shared_preferences.dart';
import 'package:valomnia_reports/Screens/Superviseur%20Screens/SideBar.dart';
import 'user_model.dart';
class SellersPage extends StatefulWidget {
const SellersPage({Key? key}) : super(key: key);
#override
_SellersPage createState() => _SellersPage();
}
class _SellersPage extends State<SellersPage> {
String? finalEmail;
Future? _futureData;
String? rawCookie;
// ignore: must_call_super
void initState() {
getValidationData();
super.initState();
_futureData = getUserApi();
}
Future getValidationData() async {
final SharedPreferences sharedPreferences2 =
await SharedPreferences.getInstance();
var obtainedEmail2 = sharedPreferences2.getString("rawCookie");
setState(() {
rawCookie = obtainedEmail2;
print(rawCookie);
});
}
List<UserModel> userList = [];
Map<String, String> headers = {};
Future<List<UserModel>> getUserApi() async {
http.Response response = await http.get(
Uri.parse('https://valomnia.herokuapp.com/superviseur/getAllVendeurs'),
headers: headers);
response.headers['set-cookie'] = rawCookie!;
updateCookie(response);
var data = jsonDecode(response.body.toString());
String? cookies = response.headers['set-cookie'];
if (response.statusCode == 200) {
for (Map i in data) {
userList.add(UserModel.fromJson(i));
}
print("Cookie : $cookies");
print("200");
return userList;
} else {
print("400");
print(rawCookie);
print(cookies);
return userList;
}
}
void updateCookie(http.Response response) {
String? rawCookie2 = response.headers['set-cookie'];
if (rawCookie2 != null) {
int index = rawCookie2.indexOf(';');
headers['cookie'] =
(index == -1) ? rawCookie2 : rawCookie2.substring(0, index);
}
}
final GlobalKey<RefreshIndicatorState> _refreshIndicatorKey =
new GlobalKey<RefreshIndicatorState>();
Future<Null> _refresh() {
return getUserApi().then((userList) {
setState(() => userList = userList);
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
drawer: NavigationDrawerWidget(),
appBar: AppBar(
title: Text(
'Sellers list',
),
centerTitle: true,
backgroundColor: Colors.green,
),
body: Column(
children: [
Expanded(
child: FutureBuilder(
future: _futureData,
builder: (context, AsyncSnapshot snapshot) {
if (!snapshot.hasData) {
return Center(child: CircularProgressIndicator());
} else {
return RefreshIndicator(
key: _refreshIndicatorKey,
onRefresh: _refresh,
child: ListView.builder(
itemCount: userList.length,
itemBuilder: (context, index) {
return Card(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: [
ReusbaleRow(
title: 'Id',
value:
snapshot.data![index].id.toString()),
ReusbaleRow(
title: 'Name',
value: snapshot.data![index].name
.toString()),
ReusbaleRow(
title: 'Username',
value: snapshot.data![index].username
.toString()),
ReusbaleRow(
title: 'DateCreated',
value: snapshot.data![index].email
.toString()),
],
),
),
);
}),
);
}
},
),
)
],
),
);
}
}
// ignore: must_be_immutable
class ReusbaleRow extends StatelessWidget {
String title, value;
ReusbaleRow({Key? key, required this.title, required this.value})
: super(key: key);
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(title),
Text(value),
],
),
);
}
} ```

unnecessary container but I need this container? flutter/Dart

I am working on a app were I get data from the ESP32 and display it on a simple page. Here is my code for my sensorpage:
import 'dart:async';
import 'dart:convert' show utf8;
import 'package:flutter/material.dart';
import 'package:flutter_blue/flutter_blue.dart';
class sensorpage extends StatefulWidget {
const sensorpage({Key? key, required this.device}) : super(key: key);
final BluetoothDevice device;
#override
_sensorpageState createState() => _sensorpageState();
}
class _sensorpageState extends State<sensorpage> {
final String SERVICE_UUID = "edb91e04-3e19-11ec-9bbc-0242ac130002";
final String CHARACTERISTIC_UUID = "edb920c0-3e19-11ec-9bbc-0242ac130002";
late bool isReady;
//String val1 = "";
//int pot1 = 0;
FlutterBlue flutterBlue = FlutterBlue.instance;
//late StreamSubscription<ScanResult> scanSubScription;
//late BluetoothDevice targetDevice;
late Stream<List<int>> stream;
#override
void initState() {
super.initState();
isReady = false;
connectToDevice();
}
connectToDevice() async {
if (widget.device == null) {
_Pop();
return;
}
Timer(const Duration(seconds: 15), () {
if (!isReady) {
disconnectFromDevice();
_Pop();
}
});
await widget.device.connect();
discoverServices();
}
disconnectFromDevice() {
if (widget.device == null) {
_Pop();
return;
}
widget.device.disconnect();
}
discoverServices() async {
if (widget.device == null) {
_Pop();
return;
}
List<BluetoothService> services = await widget.device.discoverServices();
services.forEach((service) {
if (service.uuid.toString() == SERVICE_UUID) {
service.characteristics.forEach((characteristic) {
if (characteristic.uuid.toString() == CHARACTERISTIC_UUID) {
characteristic.setNotifyValue(!characteristic.isNotifying);
stream = characteristic.value;
setState(() {
isReady = true;
});
}
});
}
});
if (!isReady) {
_Pop();
}
}
Future<bool> _onWillPop() async {
bool shouldPop = false;
await showDialog(
context: context,
builder: (context) =>
AlertDialog(
title: const Text('Are you sure?'),
content: const Text('Do you want to disconnect device and go back?'),
actions: <Widget>[
ElevatedButton(
onPressed: () {
// shouldPop is already false
},
child: const Text('No')),
ElevatedButton(
onPressed: () async {
await disconnectFromDevice();
Navigator.of(context).pop();
shouldPop = true;
},
child: const Text('Yes')),
],
));
return shouldPop;
}
_Pop() {
Navigator.of(context).pop(true);
}
String _dataParser( List<int> dataFromDevice) {
return utf8.decode(dataFromDevice);
}
#override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: _onWillPop,
child: Scaffold(
appBar: AppBar(
title: const Text('Test'),
),
body: Container(
child: !isReady
? const Center(
child: Text(
"Waiting...",
style: TextStyle(fontSize: 24, color: Colors.red),
),
)
: Container(
child: StreamBuilder<List<int>>(
stream: stream,
builder: (BuildContext context,
AsyncSnapshot<List<int>> snapshot) {
if (snapshot.hasError){
return Text('Error: ${snapshot.error}');
}
if (snapshot.connectionState == ConnectionState.active) {
var currentValue = _dataParser (snapshot.data!);
//val1 = currentValue.split(',')[0];
//pot1 = int.parse(val1);
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text('Current value',
style: TextStyle(fontSize: 14)),
Text('${currentValue} jawool',
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 24))
])
);
} else {
return const Text('Check the stream');
}
},
)),
)
));
}
}´
My Problem is that my second container where I display my data is shown as unnecessary but I don´t know why.
I assume you mean this piece of code?
body: Container(
child: !isReady
? const Center(
child: Text(
"Waiting...",
style: TextStyle(fontSize: 24, color: Colors.red),
),
)
: Container(
child: StreamBuilder<List<int>>(
If isReady is true you return Container(child: Container(child: SteamBuilder));
You should change it to this and it should be fine:
body: Container(
child: !isReady
? const Center(
child: Text(
"Waiting...",
style: TextStyle(fontSize: 24, color: Colors.red),
),
)
: StreamBuilder<List<int>>(
The first Container is just wrapping the content based on the boolean and you don't need it. According to the flutter team:
Wrapping a widget in Container with no other parameters set has no effect and makes code needlessly more complex
So instead you can directly do:
body: !isReady ? buildSomething() : Container(....more code);