LateInitializationError: Field '_origin#101043362' has not been initialized. am getting this error
as below, am new to coding
Error displayed when running the app:
Below is the user page
import 'package:edgescope_app/MapUtils.dart';
import 'package:edgescope_app/pages/directions_.dart';
import 'package:edgescope_app/pages/reason_hold.dart';
import 'package:edgescope_app/pages/reason_return.dart';
import 'package:edgescope_app/pages/start_page.dart';
import 'package:flutter/material.dart';
import 'package:edgescope_app/model/user.dart';
import 'package:edgescope_app/pages/start_page.dart';
import 'package:geolocator/geolocator.dart';
class UserPage extends StatelessWidget {
final User user;
const UserPage({
Key? key,
required this.user,
}) : super(key: key);
#override
Widget build(BuildContext context) =>
Scaffold(
appBar: AppBar(
title: Text(user.username),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
CircleAvatar(
backgroundImage: NetworkImage(user.urlAvatar),
radius: 80,
),
const SizedBox(height: 40),
Text(
user.username,
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 28,
),
),
const SizedBox(height: 20),
Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Text('Order number: ',
style: TextStyle(fontSize: 20,
color: Colors.black,
fontWeight: FontWeight.w500)),
Text(user.order,
style: TextStyle(fontSize: 14,
color: Colors.black,
fontWeight: FontWeight.w400)),
]
),
const SizedBox(height: 10),
Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Text('Location: ',
style: TextStyle(fontSize: 20,
color: Colors.black,
fontWeight: FontWeight.w500)),
Text(user.location,
style: TextStyle(fontSize: 14,
color: Colors.black,
fontWeight: FontWeight.w400)),
]
),
const SizedBox(height: 10),
Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Text('Phone number: ',
style: TextStyle(fontSize: 20,
color: Colors.black,
fontWeight: FontWeight.w500)),
Text(user.email,
style: TextStyle(fontSize: 14,
color: Colors.black,
fontWeight: FontWeight.w400)),
]
),
const SizedBox(height: 65),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
RaisedButton.icon(
padding: EdgeInsets.symmetric(horizontal: 8, vertical: 4),
color: Colors.green,
icon: Icon(
Icons.play_circle_outline, color: Colors.white),
label: Text(
'Start',
style: TextStyle(color: Colors.white, fontSize: 12),
),
onPressed: () {
Navigator.of(context).push(new MaterialPageRoute(
builder: (
BuildContext context) => new StartPage(user: user,)));
},),
RaisedButton.icon(
padding: EdgeInsets.symmetric(horizontal: 8, vertical: 4),
color: Colors.blue,
icon: Icon(Icons.location_pin, color: Colors.white),
label: Text(
'Map',
style: TextStyle(color: Colors.white, fontSize: 12),
),
onPressed: () {
Navigator.of(context).push(new MaterialPageRoute(
builder: (
BuildContext context) => new DirectionPage()));
},
),
RaisedButton.icon(
padding: EdgeInsets.symmetric(horizontal: 8, vertical: 4),
color: Colors.amberAccent,
icon: Icon(
Icons.pause_circle_outline, color: Colors.white),
label: Text(
'Hold',
style: TextStyle(color: Colors.white, fontSize: 12),
),
onPressed: () {
Navigator.of(context).push(new MaterialPageRoute(
builder: (
BuildContext context) => new ReasonHold()));
},
),
RaisedButton.icon(
padding: EdgeInsets.symmetric(horizontal: 8, vertical: 4),
color: Colors.redAccent,
icon: Icon(Icons.cancel_outlined, color: Colors.white),
label: Text(
'Return',
style: TextStyle(color: Colors.white, fontSize: 12),
),
onPressed: () {
Navigator.of(context).push(new MaterialPageRoute(
builder: (
BuildContext context) => new ReasonReturn()));
},
),
]
)
],
),
),
);
}
Below is the start page
// ignore_for_file: unnecessary_null_comparison
import 'dart:convert';
import 'package:edgescope_app/blocs/application_bloc.dart';
import 'package:flutter/material.dart';
import 'package:edgescope_app/model/user.dart';
import 'package:geolocator/geolocator.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:provider/provider.dart';
import 'package:edgescope_app/model/directions_model.dart';
import 'package:edgescope_app/model/directions_respository.dart';
class StartPage extends StatefulWidget {
final User user;
const StartPage({Key? key, required this.user}) : super(key: key);
#override
_StartPageState createState() => _StartPageState();
}
class _StartPageState extends State<StartPage> {
static ApplicationBloc _applicationBloc = ApplicationBloc();
static CameraPosition _initialCameraPosition = CameraPosition(
target: LatLng (_applicationBloc.currentLocation.latitude,
_applicationBloc.currentLocation.longitude),
zoom: 14,
);
var locationMessage="";
var clientLocation = "";
var directionInfo ="";
get dio => null;
void getCurrentLocation() async{
var position = await Geolocator
.getCurrentPosition(desiredAccuracy: LocationAccuracy.high);
var lastPosition =await Geolocator.getLastKnownPosition();
print(lastPosition);
var lat = position.latitude;
var long = position.longitude;
print("$lat,$long");
setState(() {
locationMessage ="$lat,$long";
});
}
void getClientLocation() {
}
late GoogleMapController _googleMapController;
late Marker _origin;
late Marker _destination;
late Directions _info;
#override
void dispose() {
_googleMapController.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
final applicationBloc = Provider.of<ApplicationBloc>(context);
return Scaffold(
appBar: new AppBar(title: new Text("Start"),
actions: <Widget>[
IconButton(
icon: Icon(Icons.place),
onPressed: () {
getCurrentLocation();
getClientLocation();
},
),
if(_origin != locationMessage)
IconButton(
onPressed: () => _googleMapController.animateCamera(
CameraUpdate.newCameraPosition(
CameraPosition(
target: _origin.position,
zoom: 14.5,
tilt: 50.0,
),
),
),
icon: Icon(Icons.my_location),
),
if (_destination != null)
IconButton(
onPressed: () => _googleMapController.animateCamera(
CameraUpdate.newCameraPosition(
CameraPosition(
target: _destination.position,
zoom: 14.5,
tilt: 50.0,
),
),
),
icon: Icon(Icons.person_pin_circle_outlined),
)
],
),
body: (applicationBloc.currentLocation == null)?
Center(child: CircularProgressIndicator(),):
ListView(
children: [
Column(children: [
Stack(
children: [
Container(
height: 400.0,
child: GoogleMap(
mapType: MapType.normal,
myLocationEnabled: true ,
zoomControlsEnabled: true,
initialCameraPosition: _initialCameraPosition,
onMapCreated: (controller) => _googleMapController = controller,
markers: {
if (_origin != null) _origin,
if (_destination != null) _destination
},
polylines: {
if (_info != null)
Polyline(
polylineId: const PolylineId('overview_polyline'),
color: Colors.red,
width: 5,
points: _info.polylinePoints
.map((e) => LatLng(e.latitude, e.longitude))
.toList(),
),
},
onLongPress: _addMarker,
),
),
if(_info != null)
Positioned(
top: 20.0,
child: Container(
padding: const EdgeInsets.symmetric(
vertical: 6.0,
horizontal: 12.0,
),
decoration: BoxDecoration(
color: Colors.yellowAccent,
borderRadius: BorderRadius.circular(20.0),
boxShadow: const [
BoxShadow(
color: Colors.black26,
offset: Offset(0, 2),
blurRadius: 6.0,
)
],
),
child: Text(
'${_info.totalDistance}, ${_info.totalDuration}',
style: const TextStyle(
fontSize: 18.0,
fontWeight: FontWeight.w600,
),
),
),
),
]
),
],
),
Text('Find Nearest',style: TextStyle(fontSize: 20,fontWeight: FontWeight.bold),),
Padding(
padding: const EdgeInsets.all(8.0),
child: Wrap(
spacing: 8.0,
children: [
FilterChip(label: Text('Nearest Route'),
onSelected: (val) => applicationBloc.togglePlaceType('direction',val),
selected: applicationBloc.placetype =='direction',
),
FilterChip(label: Text('Nearest Route'),
onSelected: (val) => applicationBloc.togglePlaceType('direction',val),
selected: applicationBloc.placetype =='direction',
),
],
),
),
Padding(
padding: const EdgeInsets.all(20.0),
child: Wrap(
spacing: 220.0,
children: [
FilterChip(label: Text('Accept'),
onSelected: (val) => applicationBloc.togglePlaceType('direction',val),
selected: applicationBloc.placetype =='direction',
backgroundColor: Colors.green,
),
FilterChip(label: Text('Reject'),
onSelected: (val) => applicationBloc.togglePlaceType('direction',val),
selected: applicationBloc.placetype =='direction',
backgroundColor: Colors.red,
),
],
),
),
],
),
);
}
void _addMarker(LatLng pos) async {
if (_origin == null || (_origin != null && _destination != null)) {
// Origin is not set OR Origin/Destination are both set
// Set origin
setState(() {
_origin = Marker(
markerId: const MarkerId('origin'),
infoWindow: const InfoWindow(title: 'Origin'),
icon:
BitmapDescriptor.defaultMarkerWithHue(BitmapDescriptor.hueGreen),
position: pos,
);
// Reset destination
_destination = clientLocation as Marker;
// Reset info
_info = directionInfo as Directions;
});
} else {
// Origin is already set
// Set destination
setState(() {
_destination = Marker(
markerId: const MarkerId('destination'),
infoWindow: const InfoWindow(title: 'Destination'),
icon: BitmapDescriptor.defaultMarkerWithHue(BitmapDescriptor.hueBlue),
position: pos,
);
});
// Get directions
final directions = await DirectionsRepository(dio: dio)
.getDirections(origin: _origin.position, destination: pos);
setState(() => _info = directions!);
}
}
}
Please assist
I have tried to look where the error is coming from but unfortunately am not getting it completely
is there away to clear this error please assist.
Related
So I am scanning a Barcode or I'm Introducing it manually and When I press Button to execute I get Full list of Items (Cards), when I press on them (one of Cards) -> I go to another page and It shows me more information about that Item.
But I would like to get automatically first Item opened when I press button, is there a way to do that?
Bellow I will share some screens and code in order to better understand what I try to say:
I would like to get First Item Opened Automatically After Request in First Screen (1 to 3)
And here is code:
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:sql_app/dita_conveer.dart';
import 'package:sql_app/info_produs.dart';
import 'package:sql_conn/sql_conn.dart';
import 'info_produs.dart';
class ditaStatie extends StatefulWidget {
final String nrStatie;
const ditaStatie({Key? key, required this.nrStatie}) : super(key: key);
#override
State<ditaStatie> createState() => _ditaStatieState();
}
class _ditaStatieState extends State<ditaStatie> {
final _scanCutieController = TextEditingController();
bool vizibil = true;
String cutieScan = '';
#override
void dispose() {
_scanCutieController.dispose();
super.dispose();
}
Future<List?> read(String query) async {
final result = await SqlConn.readData(query);
List _list = jsonDecode(result) as List;
return _list;
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
SizedBox(
height: 30,
),
Padding(
padding: const EdgeInsets.all(10),
child: Visibility(
visible: vizibil,
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Expanded(
flex: 6,
child: TextFormField(
controller: _scanCutieController,
decoration: const InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(20)),
borderSide: BorderSide(
color: Colors.redAccent,
width: 3,
)),
hintText: 'Scaneaza BarCode',
),
),
),
const SizedBox(width: 10),
// Butonul de Executarea selectiei
Expanded(
flex: 2,
child: ElevatedButton(
child: const Text('Test'),
onPressed: () {
setState(() {
vizibil = !vizibil;
});
cutieScan = _scanCutieController.text;
}),
),
],
),
),
),
Visibility(
visible: !vizibil,
child: Row(
children: const [
Expanded(flex: 2, child: Text('Adresa')),
Expanded(flex: 5, child: Text('Denumirea Produs')),
Expanded(flex: 2, child: Text('Comandat')),
Expanded(flex: 2, child: Text('Scanat')),
],
),
),
Expanded(
child: FutureBuilder<List?>(
future: read(
"SELECT ProductAdress, ProductName, NeedCount, ScanCount, ProductAdress, ProductBarCode, ProductSeriesCount, ProductExpirationDate FROM ScanRest WHERE ProductStation = '${widget.nrStatie}' AND BoxID = '${cutieScan}' ORDER BY ProductName ASC;"),
builder: (context, snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.waiting:
return const Text('Loading....');
default:
if (snapshot.hasError) {
print("call error");
return Text('Error: ${snapshot.error}');
} else {
print("call success = ${snapshot.data}");
List data = snapshot.data ?? [];
return ListView.builder(
itemCount: data.length,
itemBuilder: (context, index) {
return Card(
elevation: 2,
child: GestureDetector(
onTap: () {
setState(() {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => InfoProdus(
denumProdus: (data[index]
as Map)['ProductName']
.toString(),
adresaProdus: (data[index]
as Map)['ProductAdress']
.toString(),
needCount: (data[index]
as Map)['NeedCount']
.toString(),
scanCount: (data[index]
as Map)['ScanCount']
.toString(),
dataExpirare: (data[index] as Map)[
'ProductExpirationDate']
.toString(),
productBarCode: (data[index]
as Map)['ProductBarCode']
.toString(),
productSeriesCount:
(data[index] as Map)[
'ProductSeriesCount']
.toString(),
),
),
);
});
},
child: Row(children: [
Expanded(
flex: 2,
child: Text(
(data[index] as Map)['ProductAdress']
.toString()),
),
Expanded(
flex: 5,
child: Text(
(data[index] as Map)['ProductName']
.toString()),
),
Expanded(
flex: 2,
child: Center(
child: Text(
(data[index] as Map)['NeedCount']
.toString()),
),
),
Expanded(
flex: 2,
child: Center(
child: Text(
(data[index] as Map)['ScanCount']
.toString()),
),
),
]),
),
);
});
}
}
}),
),
SizedBox(
width: double.infinity,
child: ElevatedButton(
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all<Color>(Colors.green)),
child:
Text(widget.nrStatie, style: const TextStyle(fontSize: 20)),
onPressed: () => Navigator.push(context,
MaterialPageRoute(builder: (context) => statieConveer())),
),
),
],
),
);
}
}
If needed I can provide Information that is missing!
I'm starter in flutter .I want to extract value from API response and reuse it in second class as parameter. Here is my function to call API.
Response from API :
{
"code": 0,
"message": " success",
"data": {
"data": [
{
"id": 14,
"boxIdentifiant": 1924589682265255,
"user_id": 53,
"boxName": "box12",
"proprietaire": 21625147147,
"adress_circulation": "Paris ",
"gps_lat": null,
"gps_long": null,
"status": "normal"
}
]
},
"error": [],
"status": 200
}
I would like to extract id value in variable and reuse in second class .
Future<UserBox> fetchBoxes() async {
SharedPreferences localStorage = await SharedPreferences.getInstance();
String token = localStorage.getString('access_token');
await checkInternet();
Map<String, String> headers = {
'Content-type': 'application/json',
'Accept': 'application/json',
'Authorization': 'Bearer $token'
};
var url = Uri.parse(ApiUtil.GET_ALL_BOXES);
var response = await http.get(url, headers: headers);
errorHandler(response.statusCode);
var body = jsonDecode(response.body);
var data = body['data']['data'];
List<BoxModel> boxes =
List.generate(data.length, (index) => BoxModel.fromJson(data[index]));
final userbox = UserBox()..boxes = boxes;
return userbox;
}
}
UPDATE : and this is the main code :
Widget _buildDeletePopupDialog(BuildContext context) {
return new AlertDialog(
title: const Text('Supprimer un box'),
content: new Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text("Voulez vous vraiment supprimer le box"),
],
),
actions: <Widget>[
new TextButton(
onPressed: () {
removeBox();
},
/* onPressed: () {
Navigator.of(context).pop();
},*/
child: const Text('Oui'),
),
new TextButton(
onPressed: () {
Navigator.of(context).pop();
},
child: const Text('Non'),
),
],
);
}
#override
Widget build(BuildContext context) {
return SafeArea(
minimum: const EdgeInsets.only(
top: 20.0, right: 5.0, left: 5.0, bottom: 10.0),
child: Center(
child: Scaffold(
backgroundColor: Color(0xFFF6F7F8),
body: Stack(
children: [
Container(
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Container(
padding: EdgeInsets.all(10),
child: ElevatedButton.icon(
style: ElevatedButton.styleFrom(
primary: KBlue,
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(30))),
onPressed: () {
showDialog(
context: context,
builder: (BuildContext context) =>
_addNewBox(context),
);
},
label: Text(
'Ajouter un nouveau box',
style: TextStyle(color: Colors.white),
),
icon: Icon(
CommunityMaterialIcons.plus,
color: Colors.white,
),
),
),
],
),
FutureBuilder<UserBox>(
future: fetchBoxes(),
builder: (context, snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.none:
return Text('no connection');
case ConnectionState.active:
case ConnectionState.waiting:
return Center(
child: CircularProgressIndicator(),
);
break;
case ConnectionState.done:
if (snapshot.hasError) {
return Text('No Boxes');
} else {
if (snapshot.hasData) {
var userbox = snapshot.data;
// print(userbox);
// inspect(userbox);
// var user = userbox.user;
return Column(
children: List.generate(
userbox.boxes.length,
(index) {
final box = userbox.boxes[index];
// print(box.id);
// box.boxIdentifiant;
return Card(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Padding(
padding: EdgeInsets.only(
left: 10,
right: 10,
),
child: ExpansionTile(
tilePadding:
EdgeInsets.only(
left: 10),
title: Text(
'${box.boxName}',
style: TextStyle(
fontSize: 18,
fontWeight:
FontWeight
.w500),
),
// backgroundColor: Colors.white,
children: [
Row(
mainAxisAlignment:
MainAxisAlignment
.spaceBetween,
children: [
Text(
'Identifient :',
style: TextStyle(
color: Color(
0xFF01153D),
fontSize: 16,
fontWeight:
FontWeight
.w400,
),
),
SizedBox(
width: 20,
),
Text(
'${box.boxIdentifiant}',
style: TextStyle(
color: Color(
0xFF848586),
fontSize: 16,
fontWeight:
FontWeight
.w400,
),
),
],
),
SizedBox(
height: 20,
),
Row(
mainAxisAlignment:
MainAxisAlignment
.spaceBetween,
crossAxisAlignment:
CrossAxisAlignment
.start,
children: [
Text(
'Nom :',
style: TextStyle(
color: Color(
0xFF01153D),
fontSize: 16,
fontWeight:
FontWeight
.w400,
),
),
Text(
'${box.boxName}',
style: TextStyle(
color: Color(
0xFF848586),
fontSize: 16,
fontWeight:
FontWeight
.w400,
),
),
],
),
SizedBox(
height: 20,
),
Row(
mainAxisAlignment:
MainAxisAlignment
.spaceBetween,
crossAxisAlignment:
CrossAxisAlignment
.start,
children: [
Text(
'Propriétaire :',
style: TextStyle(
color: Color(
0xFF01153D),
fontSize: 16,
fontWeight:
FontWeight
.w400,
),
),
Text(
'${box.proprietaire}',
style: TextStyle(
color: Color(
0xFF848586),
fontSize: 16,
fontWeight:
FontWeight
.w400,
),
),
],
),
SizedBox(
height: 20,
),
Row(
mainAxisAlignment:
MainAxisAlignment
.spaceBetween,
crossAxisAlignment:
CrossAxisAlignment
.start,
children: [
Text(
'Adresse :',
style: TextStyle(
color: Color(
0xFF01153D),
fontSize: 16,
fontWeight:
FontWeight
.w400,
),
),
Text(
'${box.adressCirculation}',
style: TextStyle(
color: Color(
0xFF848586),
fontSize: 16,
fontWeight:
FontWeight
.w400,
),
),
],
),
SizedBox(
height: 20,
),
Row(
mainAxisAlignment:
MainAxisAlignment
.spaceEvenly,
children: [
IconButton(
icon: Icon(
CommunityMaterialIcons
.circle_edit_outline,
size: 30.0,
color: Color(
0xFFDEB522),
),
onPressed: () {
showDialog(
context:
context,
builder: (BuildContext
context) =>
_buildNamePopupDialog(
context),
);
},
),
IconButton(
icon: Icon(
CommunityMaterialIcons
.account_edit_outline,
size: 30.0,
color: Color(
0xFFDEB522),
),
onPressed: () {
showDialog(
context:
context,
builder: (BuildContext
context) =>
_buildPopupDialog(
context),
);
},
),
IconButton(
icon: Icon(
CommunityMaterialIcons
.map_marker_circle,
size: 30.0,
color: Color(
0xFFDEB522),
),
onPressed: () {
showDialog(
context:
context,
builder: (BuildContext
context) =>
_buildAdressePopupDialog(
context),
);
},
),
IconButton(
icon: Icon(
CommunityMaterialIcons
.delete_empty,
size: 30.0,
color: Color(
0xFFDEB522),
),
onPressed: () {
showDialog(
context:
context,
builder: (BuildContext
context) =>
_buildDeletePopupDialog(
context),
);
},
)
],
),
SizedBox(
height: 10,
),
],
)),
],
));
}));
} else {
return Text('No Data');
}
}
break;
default:
return Container();
break;
}
}),
void removeBox() async {
// if (_formKey.currentState.validate()) {
String boxId = _boxNameController.text;
boxApi.removeBox(boxId).then((data) {
// print(data);
// inspect(data);
if (data != null)
Navigator.push(
context, MaterialPageRoute(builder: (context) => BoxSettings()));
}).catchError((error) {
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: Text(error.toString())));
});
UPDATE 2 : BOXMODEL class :
class BoxModel {
int id;
String boxName;
int boxIdentifiant;
int userId;
// String createdAt;
// String updatedAt;
int proprietaire;
String adressCirculation;
int gpsLat;
int gpsLong;
String status;
BoxModel(
{this.id,
this.boxName,
this.boxIdentifiant,
this.userId,
// this.createdAt,
// this.updatedAt,
this.proprietaire,
this.adressCirculation,
this.gpsLat,
this.gpsLong,
this.status});
BoxModel.fromJson(Map<String, dynamic> json) {
id = json['id'];
boxName = json['boxName'];
boxIdentifiant = json['boxIdentifiant'];
userId = json['user_id'];
// createdAt = json['created_at'];
// updatedAt = json['updated_at'];
proprietaire = json['proprietaire'];
adressCirculation = json['adress_circulation'];
gpsLat = json['gps_lat'];
gpsLong = json['gps_long'];
status = json['status'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['boxName'] = this.boxName;
data['boxIdentifiant'] = this.boxIdentifiant;
data['user_id'] = this.userId;
// data['created_at'] = this.createdAt;
// data['updated_at'] = this.updatedAt;
data['proprietaire'] = this.proprietaire;
data['adress_circulation'] = this.adressCirculation;
data['gps_lat'] = this.gpsLat;
data['gps_long'] = this.gpsLong;
data['status'] = this.status;
return data;
}
}
class UserBox {
List<BoxModel> boxes;
}
how i can extract id value and save it in variable ?
First, Change your _buildDeletePopupDialog method to accept another parameter.
void removeBox(int id) async {
Then, add another param to your _buildDeletePopupDialog method and use it while calling removeBox
Widget _buildDeletePopupDialog(BuildContext context, int id) {
... rest of your code
onPressed: () {
removeBox(id);
},
Finally, start passing the id while you are calling the _buildDeletePopupDialog method,
builder: (BuildContext context) => _buildDeletePopupDialog(context, box.id)
This should be solving your case.
I started the flutter app to learn API functions but I am getting this problem that is when I change the page and go back to the previous page the data that I was displaying becomes null on all the pages. and I don't know the reason behind this.
below is the image of how it goes -:
below is the code in which I am getting data from one page to the home page and I am displaying it.
and it disappears on page change -:
import 'package:education/LogIn_SignUp/Log_In.dart';
import 'package:education/Screens/Profile_Screen.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'About_Scree.dart';
import 'Change_Password.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'dart:async';
class homeView extends StatefulWidget{
var user_id;
var user_name;
var mobile_number;
var user_address;
var user_Email;
var coaching_id;
var coaching_name;
var coaching_address;
var primary_no;
var altnumber;
var coaching_email;
homeView({
this.user_id,this.user_name,this.mobile_number,this.user_address,this.coaching_id,this.coaching_name,
this.coaching_address,this.primary_no,this.altnumber,this.coaching_email,this.user_Email
});
#override
State<StatefulWidget> createState() => homeViewState();
}
class homeViewState extends State<homeView> {
TextEditingController editingController = TextEditingController();
var showItemList = List<String>();
int count = 10;
var userid, username, mobilenumber, useraddress, userEmail, coachingid, coachingname, coachingaddress;
var primaryno, alt_number, coachingemail;
void setdata(){
setState(() {
userid = widget.user_id;
username = widget.user_name;
mobilenumber = widget.mobile_number;
useraddress = widget.user_address;
userEmail = widget.user_Email;
coachingid = widget.coaching_id;
coachingname = widget.coaching_name;
coachingaddress = widget.coaching_address;
});
}
#override
void initState(){
// showItemList.addAll(initList);
// getData();
setdata();
super.initState();
}
#override
void dispose() {
editingController.dispose();
super.dispose();
}
/// -----------------------------------------------------------------------------------------------------------------------------
/// Main Build Function for the class.
/// -----------------------------------------------------------------------------------------------------------------------------
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
appBar: PreferredSize(
preferredSize: Size.fromHeight(90.0),
child: AppBar(
title: Padding(
padding: const EdgeInsets.only(top: 20),
child: Text(
'$coachingname',//'${widget.coaching_name}',
style: TextStyle(
fontSize: 25.0,
letterSpacing: 4.5,
fontFamily: 'Sarif',
fontWeight: FontWeight.w300,
color: Colors.white,
),
),
),
backgroundColor: Colors.deepPurpleAccent,
centerTitle: true,
actions: <Widget>[
Column(
children: [
InkWell(
child: new IconButton(
icon: Padding(
padding: const EdgeInsets.only(top: 20),
child: Icon(Icons.exit_to_app),
),
onPressed:(){
Navigator.pushReplacement(context, MaterialPageRoute(
builder: (context) => LoginPage(),
));
}
),
onTap: (){
Navigator.pushReplacement(context, MaterialPageRoute(
builder: (context) => LoginPage()
));
},
),
],
),
],
),
),
drawer: Drawer(
child: Container(
padding: EdgeInsets.all(10),
child: ListView(
children: <Widget>[
Container(
height: 180,
decoration: BoxDecoration(
gradient: LinearGradient(colors: [
Colors.purple.shade300,
Colors.deepPurpleAccent.shade200,
]),
),
child: Column(
children: [
Padding(
padding: const EdgeInsets.only(top: 45.0, bottom: 10),
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(55),
),
color: Colors.blue,
child: Padding(
padding: const EdgeInsets.all(10.0),
child: Icon(Icons.perm_identity_outlined, color: Colors.white,size: 30),
)
),
),
Text(
'$username',//'${widget.user_name}',
style: TextStyle(
color: Colors.white,
fontSize: 24,
letterSpacing: 2.5,
),
),
],
),
),
ListTile(
title: Text('Profile',
style: TextStyle(
fontSize: 17,
fontWeight: FontWeight.w400,
letterSpacing: 1.5,
),
),
leading: Icon(Icons.person_pin, color: Colors.blue,),
selectedTileColor: Colors.blue,
onTap: (){
Navigator.pushReplacement(context, MaterialPageRoute(
builder: (context) => ProfilePage(
user_id: userid, user_name:username, mobile_number:mobilenumber, user_address:useraddress,
user_Email: userEmail,
)
));
},
),
ListTile(
title: Text('Change Password',
style: TextStyle(
fontSize: 17,
fontWeight: FontWeight.w400,
letterSpacing: 1.5,
),
),
leading: Icon(Icons.security, color: Colors.blue,),
selectedTileColor: Colors.blue,
onTap: (){
Navigator.pushReplacement(context, MaterialPageRoute(
builder: (context) => ChangePassword()
));
},
),
ListTile(
title: Text('About',
style: TextStyle(
fontSize: 17,
fontWeight: FontWeight.w400,
letterSpacing: 1.5,
),
),
leading: Icon(Icons.info_outline, color: Colors.blue,),
selectedTileColor: Colors.blue,
onTap: (){
Navigator.pushReplacement(context, MaterialPageRoute(
builder: (context) => AboutScreen(
coaching_id:coachingid, coaching_name:coachingname, coaching_address:coachingaddress,
primary_no:primaryno, altnumber:alt_number, coaching_email:coachingemail
)//coaching details
));
},
),
ListTile(
title: Text(
'Rate',
style: TextStyle(
fontSize: 17,
fontWeight: FontWeight.w400,
letterSpacing: 1.5,
),
),
leading: Icon(Icons.star_border_outlined, color: Colors.blue,),
selectedTileColor: Colors.blue,
onTap: (){
},
),
Divider(
color: Colors.red,
thickness: 1,
),
SizedBox(height: 10,),
Text(
'Contact Us',
style: TextStyle(
fontSize: 20,
color: Colors.grey[800],
letterSpacing: 1.5,
fontWeight: FontWeight.w500,
),
),
SizedBox(height: 10,),
ListTile(
title: Text('Share',
style: TextStyle(
fontSize: 17,
fontWeight: FontWeight.w400,
letterSpacing: 1.5,
),
),
leading: Icon(Icons.share, color: Colors.blue,),
selectedTileColor: Colors.blue,
onTap: (){
},
),
ListTile(
title: Text('Privacy Policy',
style: TextStyle(
fontSize: 17,
fontWeight: FontWeight.w400,
letterSpacing: 1.5,
),
),
leading: Icon(Icons.privacy_tip, color: Colors.blue,),
selectedTileColor: Colors.blue,
onTap: (){
},
),
ListTile(
title: Text(
'LogOut',
style: TextStyle(
fontSize: 17,
fontWeight: FontWeight.w400,
letterSpacing: 1.5,
),
),
leading: Icon(Icons.logout, color: Colors.blue,),
selectedTileColor: Colors.blue,
onTap: (){
Navigator.pushReplacement(context, MaterialPageRoute(
builder: (context) => LoginPage()
));
},
),
],
),
),
),
body: Container(),
),
);
}
}
the data that I am passing to this page is as below -:
I/flutter ( 4512): {address: jaipur, jaipur, alt_number: 9865358577, coach_address: Gautam Budha nagar, noida, coach_id: 2, coach_name: SSG Coaching, coaching_email: SSG#gmail.com, mobile_number: 9999999999, primary_no: 9898557898, res: success, user_id: 3, user_mail: s#gmail.com, user_name: sagar, user_pass: sagar123}
please help as I am unable to trace the error or find any solution.
that's is really normal because your data isn't stored in persistent storage like SQL lite, shared preferences, etc. And you shouldn't save anything not crucial into persistent local storage, because it's too expensive for your app size. There is something more that is state management with state management you wouldn't require to store your data in persistent storage, instead of store your data in a temporary so-called "semi-persistent" state. if you want to learn more about managing your data without doing async activity like crazy, you can follow these steps below.
first is to pass the data using vanilla Navigator push, and class constructor (depends on your routes type "named or not ClassNamed type of routes")
like the one #dshukertjr mentioned
Navigator.push(context, MaterialPageRoute(
builder: (context) => ProfilePage(user_id: userid, user_name:username, mobile_number:mobilenumber, user_address:useraddress,user_Email: userEmail,)
));
or using named route instead
Navigator.pushNamed(context, PackageWeight.routeName, arguments: Your data here);
learn here about named routes :
https://flutter.dev/docs/cookbook/navigation/named-routes
Pros: This is just simple af,
cons: you can't passing your data to the entire apps with this only, because this isn't good enough for managing the state for a lot of widgets.
two is to save the current data locally using provider/state management learn here about state management.
hint: you can use the provider package, it's really simple just add some map class to parse the data
https://flutter.dev/docs/development/data-and-backend/state-mgmt/simple
Pros: This is really neat for managing a state for a lot of widgets.
Cons: sometimes it's overkill to use provider & consumer to do a simple task like saving button save etc
Personal advice: Learn this, you wouldn't regret it, because you can use this almost everywhere & every situation in a flutter to managing state and data (semi persistently).
It is because you are using Navigator.pushReplacement instead of Navigator.push. When you use pushReplacement, the current route gets overridden by the new route.
So use this:
Navigator.push(context, MaterialPageRoute(
builder: (context) => ProfilePage(
user_id: userid, user_name:username, mobile_number:mobilenumber, user_address:useraddress,
user_Email: userEmail,
)
));
And inside the ProfilePage, use
Navigator.pop(context);
To go back to the homeView
I'm getting data from the API, text length is different from every post, so I want to make a responsible Text widget, which is want to behave like this image
I tried this solution but here if I click show more text every Text widget size is increase(see this ) because I declare descTextShowFlag this bool variable as global, and are there any way to increase the text widget height dynamically because here I want to give the maxline property as default, this maxline property also want to increase dynamically, If there any good way to that please tell me
import 'package:auto_size_text/auto_size_text.dart';
import 'package:exa/Model/ModelNewsFeed.dart';
import 'package:flutter/material.dart';
class Examplewidget extends StatefulWidget {
NewsFeeds newsFeeds;
Examplewidget(this.newsFeeds);
#override
_ExamplewidgetState createState() => _ExamplewidgetState();
}
class _ExamplewidgetState extends State<Examplewidget> {
String data = "We’ll see how image picker works in flutter for android and iOS. Ans: Image picker is a plugin which is used to get images from gallery or camera in the app. ... This is called Privacy - Photo Library Usage Description in the visual editor(Xcode or Android Studio).";
bool descTextShowFlag = false;
#override
Widget build(BuildContext context) {
int listsize = widget.newsFeeds.data.data.length;
return Scaffold(
body: Padding(
padding: const EdgeInsets.all(14.0),
child: ListView.builder(
itemCount: listsize,
itemBuilder: (context, index) {
String textStatus =
"${widget.newsFeeds.data.data[index].postContent}";
return new Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text( "$textStatus",
style: TextStyle(fontSize: 16.0),
maxLines: descTextShowFlag ? 8 : 2,
textAlign: TextAlign.start),
InkWell(
onTap: () {
setState(() {
descTextShowFlag = !descTextShowFlag;
});
},
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
descTextShowFlag
? Text(
"Show Less",
style: TextStyle(
fontSize: 16.0,
color: Colors.blue),
)
: Text("Show More",
style: TextStyle(color: Colors.blue))
],
),
),
],
);
}),
),
);
}
}
You can use RichText which will help you build your widget inline
this is a working example
class _MyHomePageState extends State<MyHomePage> {
var myText =
"Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum ";
var showAll = true;
final length = 150;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Text.rich(TextSpan(
children: <InlineSpan>[
TextSpan(
text: myText.length > length && !showAll
? myText.substring(0,length) + "..."
: myText),
myText.length > length
? WidgetSpan(
child: GestureDetector(
onTap: () {
setState(() {
showAll = !showAll;
});
},
child: Text(
showAll ? 'read less' : 'read more!',
style: TextStyle(color: Colors.blue),
),
),
)
: TextSpan(),
],
)),
);
}
}
Finally I found This Solution, This is Working Fine
import 'package:exa/Model/ModelNewsFeed.dart';
import 'package:flutter/material.dart';
class NewsfeedPost extends StatefulWidget {
NewsFeeds newsFeeds; // This is my model class for the API Response
NewsfeedPost(this.newsFeeds);
#override
_NewsfeedPostState createState() => _NewsfeedPostState();
}
class _NewsfeedPostState extends State<NewsfeedPost> {
String imageLink = "https://picsum.photos/250?image=9";
bool descTextShowFlag = false; // defaultly every post has small texts ()
#override
Widget build(BuildContext context) {
int listsize = widget.newsFeeds.data.data.length;
return Scaffold(
body: Padding(
padding: EdgeInsets.only(right: 4,left: 4,top: 4,bottom: 4),
child: ListView.builder(
itemCount: listsize,
itemBuilder: (context, index) {
String textStatus = "${widget.newsFeeds.data.data[index].postContent}";
String fname='${widget.newsFeeds.data.data[index].postOwner.firstName}';
String lname='${widget.newsFeeds.data.data[index].postOwner.lastName}';
String postdate='${widget.newsFeeds.data.data[index].updatedAt}';
int textlength = textStatus.length;
return Card(
child: SingleChildScrollView(
child: new Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
height:60.0 ,
color: Colors.white10,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Row(
children: <Widget>[
Padding(
padding: EdgeInsets.only(left: 5.0,right: 5.0),
child: Container(
height: 50.0,
width: 50.0, //MediaQuery.of(context).size.width,
child: new CircleAvatar(
radius: 50.0,
backgroundColor: Colors.transparent,
backgroundImage: NetworkImage(imageLink),
),
),
),
Padding(
padding:EdgeInsets.only(top: 5.0,bottom: 5.0),
child: Column(
children: <Widget>[
Column(
children: <Widget>[
Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Text('$fname'+' $lname',style: TextStyle(fontSize: 20.0),textAlign: TextAlign.start,),
],
),
Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Text('$postdate'),
],
),
],
),
],
),
),
],
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Icon(Icons.more_horiz),
)
],
),
),
Divider(),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text("$textStatus",
style: TextStyle(fontSize: 16.0),
maxLines: descTextShowFlag
? MediaQuery.of(context).size.height.toInt()
: 5,
textAlign: TextAlign.start),
),
InkWell(
onTap: () {
setState(() {
descTextShowFlag = !descTextShowFlag;
});
},
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
// descTextShowFlag
textlength <= 200
? Text(
"",
style: TextStyle(
fontSize: 16.0, color: Colors.blue),
)
: descTextShowFlag
? Padding(
padding: const EdgeInsets.all(8.0),
child: Text("Show Less",
style: TextStyle(color: Colors.blue)),
)
: Padding(
padding: const EdgeInsets.all(8.0),
child: Text("Show More",
style: TextStyle(color: Colors.blue)),
)
],
),
),
],
),
),
);
}),
),
);
}
}
So I have this code that fetches routes from one place to another.
Please see the picture attached below.
I need to add details for each journey which will be hidden unless you click on 'Details' button, I want to show the data in a ExpansionTile/ExpansionPanel - basically a collapsing element.
The problem is that when I use the setState() {...} on the button, it will show the data indeed but it will also make the API call again.
The method getData() gets triggered in the build widget which is why (I suppose) this is happening but I don't know how to solve this.
Is there a better way of doing it?
Any help/improvements will be highly appreciated as I am new to Flutter =)
...
class _PlanJourney extends State<PlanJourney> {
String data;
final from;
final to;
final type;
final time;
static var date = new DateTime.now();
final String formattedDate = new DateFormat('yyyy-MM-dd').format(date);
double _animatedHeight = 100.0;
Map<String,dynamic> journeyData;
_PlanJourney(this.from, this.to, this.type, this.time);
Future<String> getData() async {
http.Response response = await http.get(url);
data = response.body;
journeyData = json.decode(data);
debugPrint(journeyData.toString());
}
#override
Widget build(BuildContext context){
return Scaffold(
appBar: AppBar(
title: Text('Plan a journey'.toUpperCase(),
style: TextStyle(
color: Colors.black,
fontSize: 20,
fontWeight: FontWeight.bold
)
),
iconTheme: IconThemeData(
color: Color(0xFF0984e3),
),
backgroundColor: Colors.white,
),
resizeToAvoidBottomPadding: false,
body: SingleChildScrollView(
child: ConstrainedBox(
constraints: BoxConstraints(),
child: FutureBuilder(
future: getData(),
builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
if(snapshot.connectionState == ConnectionState.done){
List<Widget> elements = new List<Widget>();
for(var i = 0; i < journeyData['routes'].length; i++){
List<Widget> iconList = new List<Widget>();
String duration;
String start = journeyData['routes'][i]['departure_time'];
String end;
String stress = '2 min';
for(var j = 0; j < journeyData['routes'][i]['route_parts'].length; j++){
if(journeyData['routes'][i]['route_parts'][j]['mode'] == 'foot'){
iconList.add(IconTheme(
data: IconThemeData(
color: Color(0xFFbfcdd5)
),
child: Icon(Icons.directions_walk),
)
);
} else if(journeyData['routes'][i]['route_parts'][j]['mode'] == 'tube'){
iconList.add(IconTheme(
data: IconThemeData(
color: Color(0xFFbfcdd5)
),
child: Icon(Icons.train),
)
);
} else if(journeyData['routes'][i]['route_parts'][j]['mode'] == 'bus'){
iconList.add(IconTheme(
data: IconThemeData(
color: Color(0xFFbfcdd5)
),
child: Icon(Icons.directions_bus),
)
);
}
duration = journeyData['routes'][i]['duration'];
end = journeyData['routes'][i]['arrival_time'];
}
elements.add(Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Container(
alignment: Alignment.topLeft,
margin: EdgeInsets.only(left: 15, right: 15),
padding: EdgeInsets.all(10),
child: new Wrap(
direction: Axis.horizontal,
crossAxisAlignment: WrapCrossAlignment.start,
spacing: 5,
runSpacing: 5,
children: iconList
),
),
Container(
alignment: Alignment.topLeft,
margin: EdgeInsets.only(left: 15, right: 15),
padding: EdgeInsets.all(10),
child: new Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget> [
Column(
children: <Widget>[
Text('Duration',
style: TextStyle(
fontFamily: "Gotham Pro",
fontWeight: FontWeight.w300,
fontSize: 14
)
),
Padding(
padding: EdgeInsets.only(top: 5),
),
Text(duration)
],
),
Column(
children: <Widget>[
Text('Start',
style: TextStyle(
fontFamily: "Gotham Pro",
fontWeight: FontWeight.w300,
fontSize: 14
)
),
Padding(
padding: EdgeInsets.only(top: 5),
),
Text(start),
],
),
Column(
children: <Widget>[
Text('End',
style: TextStyle(
fontFamily: "Gotham Pro",
fontWeight: FontWeight.w300,
fontSize: 14
)
),
Padding(
padding: EdgeInsets.only(top: 5),
),
Text(end),
],
),
Column(
children: <Widget>[
Text('Stress',
style: TextStyle(
fontFamily: "Gotham Pro",
fontWeight: FontWeight.w300,
fontSize: 14
)
),
Padding(
padding: EdgeInsets.only(top: 5),
),
Text(stress)
],
)
]
),
),
Container(
alignment: Alignment.topLeft,
margin: EdgeInsets.only(left: 15, right: 15),
child: Row(
children: <Widget>[
OutlineButton(
child: Text('Details',
style: TextStyle(
color: Color(0xFF0c85e4),
fontFamily: "Gotham Pro",
fontWeight: FontWeight.w700
)
),
borderSide: BorderSide(
color: Color(0xFF0c85e4), //Color of the border
style: BorderStyle.solid, //Style of the border
width: 2, //width of the border
),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
onPressed: ()=>setState((){
_animatedHeight!=0.0 _animatedHeight=0.0:_animatedHeight=100.0;
}
),
),
Padding(
padding: EdgeInsets.only(left: 15, top: 15),
),
RaisedButton(
child: Text('Save',
style: TextStyle(
color: Colors.white,
fontFamily: "Gotham Pro",
fontWeight: FontWeight.w700,
)
),
color: Color(0xFF08b894),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
onPressed: (){},
)
],
)
),
AnimatedContainer(duration: const Duration(milliseconds: 120),
child: new Text("Journey data will go here"),
height: _animatedHeight,
color: Colors.tealAccent,
width: 200.0,
),
Divider()
],
),
));
}
return new Column(children: elements);
}else if(snapshot.connectionState == ConnectionState.waiting){
return Text("loading ...");
}
},
),
)
)
);
}
}
Here is how I solved my problem, but firstly I'll try to explain what was the cause.
The problem
The problem was that I had my getData() method that is calling the API in my build method, therefore, every time you'd make a change it calls the build method which then executes the getData method respectively.
...
future: getData()
...
The fix
The getData() method must be executed in the initState() to prevent it from executing multiple times. First, I defined a variable dataFetched which will only be set when the getData() method finishes. Once the it is set, the future builder will continue executing and run the code within it.
...
var dataFetched;
#override
void initState(){
super.initState();
dataFetched = getData();
}
...
FutureBuilder(
future: dataFetched,
builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
if(snapshot.connectionState == ConnectionState.done){...}
}
}
)
...
I am not sure that this is the best way of doing it, but at least it fixed my problem.
Please read this thread for more detailed explanation.
How to deal with unwanted widget build?
Credits: Rémi Rousselet