after call does not save data flutter - flutter

I make a call where I checked it happens correctly, but then when I try to retrieve a data received by the call me from null. I can not understand why but .. quancuno of you can give me a hand?
Future<UserDataByCode> sendCode() async {
var url = "$_baseUrl/api/users/ABC124";
try {
var response = await _dio.get(
url,
options: Options(headers: {"x-access-token": _loginData.token}),
);
if (response.statusCode == 200) {
var userData = UserDataByCode.fromJson(response.data);
return userDataByCode;
} else {
_printLog("Upload sendCode 2", response, level: Level.WARNING);
return null;
}
} on DioError catch (e) {
_printLog("Upload sendCode 3", e, level: Level.SHOUT);
return null;
}
}
This is the UserDataByCode model which should return the data to insert as name in the text after making the call, but it returns null:import 'dart:convert';
class UserDataByCode {
String firstName;
String surname;
int balance;
double ticketValue;
int remainingTickets;
UserDataByCode(
{this.firstName,
this.surname,
this.balance,
this.ticketValue,
this.remainingTickets,
});
UserDataByCode.fromJson(Map<String, dynamic> json) {
firstName = json['user_name_first'];
surname = json['user_name_surname'];
balance = json['tckt_balance'];
ticketValue = json['ticket_value'];
remainingTickets = json['remaining_tickets'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['firstName'] = this.firstName;
data['surname'] = this.surname;
data['balance'] = this.balance;
data['ticketValue'] = this.ticketValue;
data['remainingTickets'] = this.remainingTickets;
return data;
}
#override
String toString() {
return jsonEncode(toJson());
}
}
In my ContentManager I put this, since for the other calls whoever worked before me did well I hurt the same thing ..
Future<UserDataByCode> getUserDataByCode() async {
return _userDataByCode = await connection.sendCode();
}
UserDataByCode getUserDataByCodeSync() {
if (_userDataByCode == null) {
print("Still no _userDataByCode");
return null;
}
return _userDataByCode;
}
UPDATE:
Receive this
UPDATE 2:
return FutureBuilder<UserData>(
future: contentManager.getUserData(),
builder: (context, AsyncSnapshot<UserData> snapUserData) {
All widget code:
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
_buttonHeight = size.height * .05;
//double splitPoint = size.height / 7;
return FutureBuilder<UserData>(
future: contentManager.getUserData(),
builder: (context, AsyncSnapshot<UserData> snapUserData) {
if (snapUserData.hasError)
return Container(
child: Center(
child: Text("There was some error"),
),
);
if (snapUserData.connectionState != ConnectionState.done)
return Container(
child: Center(
child: CircularProgressIndicator(valueColor: new AlwaysStoppedAnimation<Color>(appColors.yellow)),
),
);
return Container(
color: appColors.primaryColor,
child: ListView(
primary: false,
children: [
// TITOLO
Align(
alignment: Alignment.center,
child: Container(
child: Text(
localization.showQR,
style: Theme.of(context).primaryTextTheme.headline5.copyWith(
color: appColors.green,
fontWeight: FontWeight.bold,
),
),
),
),
Align(
alignment: Alignment.center,
child: Container(
child: qrCodeHolder
),
),
Align(
alignment: Alignment.center,
child: Container(
child: AutoSizeText(
localization.home_subLabel,
textAlign: TextAlign.center,
maxLines: 1,
style: Theme.of(context).primaryTextTheme.headline5.copyWith(
color: appColors.green,
fontWeight: FontWeight.bold,
),
),
),
),
Padding(
padding: EdgeInsets.all(15.0),
//top: size.height * .02,
//right: size.width * .02,
child: Row(
children: [
Expanded(
child: TextField(
inputFormatters: [
new LengthLimitingTextInputFormatter(11),
],
decoration: InputDecoration(
filled: true,
fillColor: Colors.white,
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.white),
),
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.white),
),
),
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 18.0,
color: Colors.black,
),
),
),
IconButton(
icon: Image.asset("assets/images/send.png"),
onPressed: () async {
connection.sendCode().then((value) {
if (value != null) {
showDialog(context: context, builder: (_) => PaymentDialog());
} else {
showDialog(context: context, builder: (_) => PaymentDialog());
}
});
}
//onPressed: () => showDialog(context: context, builder: (_) => PaymentDialog()),
),
]
),
),
],
padding: EdgeInsets.all(20.0),
),
);
});
}
}

Related

Keyboard trigger the api call while closing and opening in flutter?

Keyboard triggers the api calling while closing and opening
I have search bar I didn't pass anything inside the search bar but when I click the search bar The api call will run.
I don't know why that thing was happen I tried several ways but It won't work
Even Inside the keyboard I choose the one hand keyboard that time also api will run
Also tried the Focusnode also.
class PopupNaviagator extends StatefulWidget {
var body;
String leadsName = "";
Map<String, dynamic> listValues;
PopupNaviagator(this.listValues);
var data;
String pageData = "";
double totalPageCount = 0;
int pageIncrementer = 1;
#override
_PopupNavigatorState createState() => _PopupNavigatorState();
}
class _PopupNavigatorState extends State<PopupNaviagator> {
Utils util = new Utils();
bool isSearching = false;
#override
void initState() {
super.initState();
}
String searchingText = "";
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
titleSpacing: 0,
flexibleSpace: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: util.getColors(1001),
stops: [0.1, 5.0],
),
),
),
title: !isSearching
? Text("Select Search Type")
: TextField(
autofocus: true,
autocorrect: true,
onChanged: (value) {
searchingText = value;
},
cursorColor: Colors.white,
onSubmitted: (value) {
searchingText = value;
campaignAPI(
widget.listValues["colname"].toString(),
widget.pageIncrementer.toString(),
searchingText, // search key
1, // flag
);
},
style: TextStyle(color: Colors.white),
decoration: InputDecoration(
icon: Icon(Icons.search),
hintText: "Search ",
hintStyle: TextStyle(color: Colors.white)),
),
actions: <Widget>[
isSearching
? IconButton(
icon: Icon(Icons.cancel),
onPressed: () {
setState(() {
searchingText = "";
this.isSearching = false;
campaignAPI(
widget.listValues["colname"].toString(),
widget.pageIncrementer.toString(),
searchingText, // search key
1, // flag
);
/* filteredCountries = countries;*/
});
},
)
: IconButton(
icon: Icon(Icons.search),
onPressed: () {
setState(() {
this.isSearching = true;
});
},
)
],
),
body: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(5))),
child: Scaffold(
body: FutureBuilder(
future: campaignAPI(widget.listValues["colname"].toString(), "1",
searchingText, 0),
builder: (context, snapshot) {
if (snapshot.hasData) {
var body;
if (widget.data == null) {
body = snapshot.data;
} else {
body = widget.data;
}
final records = body["list_records"];
widget.pageData = body["PageValues"];
widget.totalPageCount =
(body["TotalRecordCount"] / 5).toDouble();
return Scaffold(
body: Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
if (records.length != 0) ...[
Expanded(
child: ListView.builder(
padding: EdgeInsets.only(
top: 0,
bottom: 0,
),
physics: ClampingScrollPhysics(),
shrinkWrap: true,
itemCount: records.length,
itemBuilder: (context, index) {
Map<String, dynamic> pickerValues =
records[index];
String titleName =
pickerValues["viewcol_value"]
.toString();
return Container(
margin: const EdgeInsets.all(5.00),
decoration: new BoxDecoration(
color: Colors.white,
border: Border.all(
color: Colors.grey, width: 1.0),
borderRadius: new BorderRadius.all(
Radius.circular(3.0)),
),
child: FlatButton(
padding: EdgeInsets.all(8.0),
onPressed: () {
setState(() {
List<String> strArr = [
titleName,
pickerValues["rec_id"].toString(),
widget.listValues["colname"]
];
Navigator.pop(context, strArr);
});
},
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(titleName.toString()),
Icon(
Icons.check_circle_outlined,
color: Colors.grey,
),
]),
),
);
}),
),
] else ...[
Container(
height: MediaQuery.of(context).size.height / 1.4,
child: Center(
child: Container(
padding: EdgeInsets.all(65),
child: Text(
"No Record Found",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20,
color: Colors.black),
),
decoration: BoxDecoration(
border: Border.all(
color: Colors.grey,
width: 2,
),
)),
),
),
],
if (records.length != 0) ...[
Container(
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
InkWell(
onTap: () {
if (widget.pageIncrementer > 1) {
widget.pageIncrementer--;
campaignAPI(
widget.listValues["colname"]
.toString(),
widget.pageIncrementer.toString(),
searchingText, // search key
1, // flag
);
setState(() {});
} else {
util.showToast("No records to show");
}
},
child: Icon(Icons.arrow_left_rounded,
size: 50, color: Colors.white),
),
Text(
widget.pageData,
style: TextStyle(
fontSize: 15,
color: Colors.white,
fontWeight: FontWeight.bold),
),
InkWell(
onTap: () {
if (widget.totalPageCount > 1 &&
widget.totalPageCount >=
widget.pageIncrementer) {
widget.pageIncrementer++;
campaignAPI(
widget.listValues["colname"]
.toString(),
widget.pageIncrementer.toString(),
searchingText, // search key
1, // flag
);
} else {
util.showToast("No reocrds to show");
}
},
child: Icon(Icons.arrow_right_rounded,
size: 50, color: Colors.white),
),
],
),
decoration: BoxDecoration(
gradient: LinearGradient(
colors: util.getColors(1001),
stops: [0.1, 5.0],
),
),
)
]
],
),
),
);
} else if (snapshot.hasError) {
return Text('${snapshot.error.toString()}');
}
return Center(
child: CircularProgressIndicator(),
);
},
),
),
));
}
campaignAPI(
String field_col, String page_no, String searchValue, int flag) async {
Utils util = new Utils();
SharedPreferences prefs = await SharedPreferences.getInstance();
final accessKey = prefs.getString('access_key');
final companyName = prefs.getString('company_name');
Object requestParam = {
"companyname": companyName,
"access_key": accessKey.toString(),
"field_col": field_col,
"page_no": page_no,
"searchValue": searchValue,
};
print(requestParam.toString());
APIS apis = new APIS();
Uri url = Uri.parse(apis.searchquickcreate);
util.prints(url);
util.prints(requestParam);
final response = await http.post(url, body: requestParam);
if (response.statusCode == 200) {
final body = json.decode(response.body);
print(body);
String status = body["status"];
if (status != "failed") {
if (flag == 1) {
setState(() {
widget.data = body;
});
}
return body;
} else {
util.logOut(context);
return body;
}
} else {
Navigator.pop(context);
util.showToast("Server Error !");
throw Exception("Server Error !");
}
}
}

flutter firestore - How to retrieve the new document id after adding to firestore

I want to retrieve the new created document id and display the document data in a new page. How can i get the document id? When onPressed() the elevated button, I want to retrieve the document data based on its id.
How can I bring the document id from addDiagnose(_type, _symptomsResult) so that I can navigate it to another page.
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DiagnosisPage(documentId: documentId),
)
);
This is my current code.
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:multiselect_formfield/multiselect_formfield.dart';
import 'package:petbuddies/user/diagnosis/diagnose_history.dart';
import 'package:petbuddies/user/diagnosis/diagnosis.dart';
class CheckerPage extends StatefulWidget {
const CheckerPage({Key? key}) : super(key: key);
#override
_CheckerPageState createState() => _CheckerPageState();
}
class _CheckerPageState extends State<CheckerPage> {
//retrieve options
final _formKey = GlobalKey<FormState>();
void _petTypeDropDownItemSelected(String newValueSelected) {
setState(() {
petType = newValueSelected;
});
}
clearText(){
_symptoms?.clear();
}
#override
void initState(){
super.initState();
_symptoms = [];
_symptomsResult = [];
}
List? _symptoms;
late List<dynamic> _symptomsResult;
var petType;
var _type;
final Stream<QuerySnapshot> petTypeStream = FirebaseFirestore.instance.collection('pet type').orderBy('name').snapshots();
final Stream<QuerySnapshot> symptomsStream = FirebaseFirestore.instance.collection('symptoms').orderBy('name').snapshots();
DocumentReference diagnosis = FirebaseFirestore.instance.collection('diagnosis').doc();
//store the diagnosis result
User? user = FirebaseAuth.instance.currentUser;
Future<void> addDiagnose(_type, _symptomsResult) async {
String petChosen = this._type;
List symptomsChosen = this._symptomsResult.toList();
QuerySnapshot<Map<String, dynamic>> snapshot =
await FirebaseFirestore.instance.collection("disease")
.where('petType',isEqualTo: petChosen)
.where('symptoms',arrayContainsAny: symptomsChosen)
.get();
List<String> diseaseRef = snapshot.docs.map((e) => e.id).toList();
String createdby = user!.uid;
Timestamp date = Timestamp.now();
List possibleDisease = diseaseRef.toList();
final data = {
'created by': createdby,
'date': date,
'pet chosen': petChosen,
'symptoms chosen': symptomsChosen,
'possible disease': possibleDisease,
};
//set document data
return diagnosis
.set(data)
.then((value) => print('Diagnose Report Added'))
.catchError((error)=>print("Failed to add: $error")
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.blue[900],
title: const Text("Pet Symptoms Checker",
style: TextStyle(color: Colors.white),
),
),
body: Form(
key: _formKey,
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 30),
child: ListView(
children: [
Align(
alignment: Alignment.bottomRight,
child: TextButton(
child: const Text(
'History',
style: TextStyle(fontSize: 18),
),
onPressed: (){
Navigator.push(context, MaterialPageRoute(builder: (context) => const DiagnoseHistoryPage(),));
},
),
),
Container(
padding: const EdgeInsets.all(12.0),
decoration: BoxDecoration(
border: Border.all(width: 3, color: Colors.indigo,),
borderRadius: const BorderRadius.all(Radius.circular(30)),
),
child: Column(
children: [
StreamBuilder<QuerySnapshot>(
stream: petTypeStream,
builder: (context, snapshot) {
if (!snapshot.hasData) {
return const Center(
child: CircularProgressIndicator(),
);
}
return Container(
padding: const EdgeInsets.only(bottom: 16.0),
child: Row(
children: <Widget>[
Expanded(
flex: 2,
child: Container(
padding: const EdgeInsets.fromLTRB(12.0, 10.0, 10.0, 10.0),
child: const Text(
"Pet Type",
style: TextStyle(fontSize: 20),
),
),
),
Expanded(
flex: 3,
child: Row(
children: [
const SizedBox(width: 30,),
DropdownButton(
value: petType,
onChanged: (valueSelectedByUser) {
_petTypeDropDownItemSelected(valueSelectedByUser.toString());
},
hint: const Text('Choose Pet Type',),
underline: Container(),
items: snapshot.data!.docs.map((DocumentSnapshot document) {
return DropdownMenuItem<String>(
value: document.get('name'),
child: Text(document.get('name')),
);
}).toList(),
),
],
),
),
],
),
);
}),
StreamBuilder(
stream: symptomsStream,
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot){
if(snapshot.hasError){
print('Something went wrong');
}
if(snapshot.connectionState == ConnectionState.waiting){
return const Center(
child: CircularProgressIndicator(),
);
}
final List symptomsList = [];
snapshot.data!.docs.map((DocumentSnapshot document){
Map a = document.data() as Map<String, dynamic>;
symptomsList.add(a['name']);
a['id'] = document.id;
}).toList();
return MultiSelectFormField(
autovalidate: AutovalidateMode.disabled,
chipBackGroundColor: Colors.blue[900],
chipLabelStyle: const TextStyle(fontWeight: FontWeight.bold, color: Colors.white),
dialogTextStyle: const TextStyle(fontWeight: FontWeight.bold),
checkBoxActiveColor: Colors.blue[900],
checkBoxCheckColor: Colors.white,
dialogShapeBorder: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(12.0))),
title: const Text(
"Symptoms",
style: TextStyle(fontSize:20),
),
validator: (value) {
if (value == null || value.length == 0) {
return 'Please select one or more symptoms';
}
return null;
},
dataSource: [
for (String i in symptomsList) {'value' : i}
],
textField: 'value',
valueField: 'value',
okButtonLabel: 'OK',
cancelButtonLabel: 'CANCEL',
hintWidget: const Text('Please choose one or more symptoms'),
initialValue: _symptoms,
onSaved: (value) {
if (value == null) return;
setState(() {
_symptoms = value;
}
);
},
);
}
),
const SizedBox(height:50,),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
ElevatedButton(
onPressed: () async{
if(_formKey.currentState!.validate()){
setState(() {
_type = petType.toString();
_symptomsResult = _symptoms!.toList();
addDiagnose(_type,_symptomsResult);
final documentId = diagnosis.id;
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DiagnosisPage(documentId: documentId),
)
);
clearText();
}
);
}
},
child: const Text(
'Diagnose',
style: TextStyle(fontSize: 18),
),
style: ElevatedButton.styleFrom(primary: Colors.blue[900]),
),
],
),
],
),
)
],
),
),
),
);
}
}

How to increase quantity of same item click in Flutter (Bloc)

In HomePage.dart i am fetching an api data by using http package and flutter_bloc for the architecture. Now once i get the data and if i select any of the item in HomePage.dart then it will be added in MenuCart.dart. Now the problem i am facing is
If i click the same item more than one time then it shows duplicate card widget.
In MenuCart.dart i have added two buttons + & - and i increases the quantity to 3 then i decided to delete the item. Now i go back to previous screen and again i add that same item and if i go to MenuCart.dart then quantity displays 4.
What i am Expecting
It should not generate duplicate card instead quantity should increment.
After i delete an item and again add the same item then quantity must show 1.
In HomePage.dart i show very limited amount of code because of lengthy, but i have added the code of bloc and MenuCart.dart.
HomePage.dart
GestureDetector(
onTap: () {
BlocProvider.of<MenuCartBloc>(context)
.add(AddToCart(data[index])); // Here adding an item in MenuCart
},
child: Container(
child: Center(
child: Padding(
padding: const EdgeInsets.all(4.5)
child: Text('ADD'),
),
),
),
);
DishMenuTypesId.dart (Model)
class DishMenuTypesIdData {
String? id;
int? status;
int? quantity;
String? dishPrice;
String? photo;
DishMenuTypesIdData({
this.id,
this.status,
this.quantity = 1,
this.dishPrice,
this.photo,
});
DishMenuTypesIdData.fromJson(Map<String, dynamic> json) {
id = json['id']?.toString();
status = json['status']?.toInt();
quantity = 1;
dishPrice = json['dish_price']?.toString();
photo = json['photo']?.toString();
}
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
data['id'] = id;
data['status'] = status;
data["quantity"] = quantity;
data['dish_price'] = dishPrice;
data['photo'] = photo;
return data;
}
}
class DishMenuTypesId {
String? message;
List<DishMenuTypesIdData?>? data;
DishMenuTypesId({
this.message,
this.data,
});
DishMenuTypesId.fromJson(Map<String, dynamic> json) {
message = json['message']?.toString();
if (json['data'] != null) {
final v = json['data'];
final arr0 = <DishMenuTypesIdData>[];
v.forEach((v) {
arr0.add(DishMenuTypesIdData.fromJson(v));
});
this.data = arr0;
}
}
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
data['message'] = message;
if (this.data != null) {
final v = this.data;
final arr0 = [];
v!.forEach((v) {
arr0.add(v!.toJson());
});
data['data'] = arr0;
}
return data;
}
}
MenuCartBloc.dart
class MenuCartBloc extends Bloc<MenuCartEvent, MenuCartState> {
MenuCartBloc() : super(MenuLoaded([]));
List<DishMenuTypesIdData> cart = [];
#override
Stream<MenuCartState> mapEventToState(
MenuCartEvent event,
) async* {
yield MenuLoading();
try {
if (event is AddToCart) {
final itemExist = cart.where((e) => e.id == event.dish.id);
if (itemExist.isNotEmpty) {
print("Not Empty"); // Here i am expecting to show qty 2 if i click an item more than 1 time
} else {
print("Empty");
cart.add(event.dish);
}
} else if (event is DeleteToCart) {
cart.remove(event.dish);
} else if (event is ClearAllCart) {
cart = [];
}
yield MenuLoaded(cart);
} catch (e) {
yield MenuFailed(e.toString());
}
}
}
MenuCartEvent.dart
abstract class MenuCartEvent {}
class AddToCart extends MenuCartEvent {
late final DishMenuTypesIdData dish;
AddToCart(this.dish);
}
class DeleteToCart extends MenuCartEvent {
late final DishMenuTypesIdData dish;
DeleteToCart(this.dish);
}
class ClearAllCart extends MenuCartEvent {}
MenuCartState.dart
abstract class MenuCartState {}
class MenuLoading extends MenuCartState {}
class MenuLoaded extends MenuCartState {
final List<DishMenuTypesIdData> cart;
MenuLoaded(this.cart);
}
class MenuFailed extends MenuCartState {
final String message;
MenuFailed(this.message);
}
MenuCart.dart
Widget build(BuildContext context) {
var height = MediaQuery.of(context).size.height;
var width = MediaQuery.of(context).size.width;
var lang = translator.activeLanguageCode;
return Container(
child: Padding(
padding: const EdgeInsets.only(top: 20.0, left: 10.0, right: 10.0),
child: BlocBuilder<MenuCartBloc, MenuCartState>(
builder: (context, state) {
DishMenuTypesIdData _cart = DishMenuTypesIdData();
if (state is MenuLoading) {
return PlatformCircularProgressIndicator();
} else if (state is MenuLoaded) {
return SingleChildScrollView(
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'Your Reservation Details'.tr(),
style: TextStyle(
color: TuxedoColor.blackColor,
fontSize: lang == "en" ? 14.0 : 15.0,
fontFamily: lang == "en"
? 'OpenSansBold'
: 'ArabicSemiBold'),
),
GestureDetector(
onTap: () {
BlocProvider.of<MenuCartBloc>(context)
.add(ClearAllCart());
},
child: Row(
children: [
Icon(
Icons.close,
color: TuxedoColor.redColor,
size: 15.0,
),
Text(
'Clear All'.tr(),
style: TextStyle(
color: TuxedoColor.redColor,
fontSize: 12.0,
fontFamily: lang == "en"
? 'OpenSansRegular'
: 'ArabicLight'),
),
],
),
)
],
),
SizedBox(
height: 25.0,
),
Container(
height: height * 0.3,
child: ListView.builder(
shrinkWrap: true,
scrollDirection: Axis.vertical,
itemCount: state.cart.length,
itemBuilder: (BuildContext context, int index) {
_cart = state.cart[index];
return Dismissible(
key: UniqueKey(),
background: Container(
alignment: AlignmentDirectional.centerEnd,
color: TuxedoColor.redBrightColor,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Icon(
Icons.delete,
color: TuxedoColor.whiteColor,
),
),
),
onDismissed: (direction) {
BlocProvider.of<MenuCartBloc>(context)
.add(DeleteToCart(_cart));
setState(() {
state.cart.removeAt(index);
});
},
direction: DismissDirection.endToStart,
child: Card(
child: Row(
children: [
Stack(
children: [
ClipRRect(
borderRadius:
BorderRadius.circular(10.0),
child: CachedNetworkImage(
imageUrl:
_cart.photo!,
placeholder: (context, url) => Center(
child:
PlatformCircularProgressIndicator()),
errorWidget:
(context, url, error) =>
Icon(Icons.error),
width: width * 0.25,
height: height * 0.1,
fit: BoxFit.fill,
),
),
Positioned(
bottom: 0,
right: 0,
child: Container(
decoration: BoxDecoration(
color: TuxedoColor.redColor,
borderRadius: lang == "en"
? BorderRadius.only(
bottomRight:
Radius.circular(
10),
)
: BorderRadius.only(
bottomLeft:
Radius.circular(
10),
)),
height: 25.0,
width: 45.0,
child: Padding(
padding: const EdgeInsets.only(
left: 3.0, right: 3.0),
child: FittedBox(
fit: BoxFit.fitWidth,
child: Text(
'${_cart.dishPrice!} \SR',
style: TextStyle(
color: TuxedoColor
.whiteColor,
fontFamily: lang == "en"
? 'OpenSansSemiBold'
: 'ArabicSemiBold'),
),
),
),
),
)
],
),
Padding(
padding:
const EdgeInsets.only(left: 10.0),
child: Column(
children: [
Container(
width: width * 0.6,
child: Row(
mainAxisAlignment:
MainAxisAlignment
.spaceBetween,
children: [
Container(
height: 25.0,
child: Row(
children: [
MaterialButton(
color: TuxedoColor
.redColor,
shape: CircleBorder(),
onPressed: () {
setState(() {
var minus = state
.cart[index]
.quantity;
if (minus !=
null) {
minus--;
state
.cart[index]
.quantity = minus;
}
});
},
child: Text(
'-',
style: TextStyle(
color: Colors
.white,
fontSize: 20),
),
),
Text(_cart.quantity
.toString()),
MaterialButton(
color: TuxedoColor
.redColor,
shape: CircleBorder(),
onPressed: () {
setState(() {
var add = state
.cart[index]
.quantity;
if (add != null) {
add++;
state
.cart[index]
.quantity = add;
}
});
},
child: Text(
'+',
style: TextStyle(
color: Colors
.white,
fontSize: 20),
),
),
],
),
),
GestureDetector(
onTap: () {
BlocProvider.of<
MenuCartBloc>(
context)
.add(DeleteToCart(
state.cart[
index]));
},
child: Icon(
Icons.delete,
color:
TuxedoColor.redColor,
),
)
],
),
),
SizedBox(
height: 15.0,
)
],
),
),
],
),
),
);
}),
),
],
),
);
} else if (state is MenuFailed) {
return Center(child: Text(state.message));
}
return Container();
},
)),
);
}
Something like that should work:
final itemExist = cart.firstWhere((e) => e.id == event.dish.id, orElse: () => null);
if (itemExist != null) {
itemExist.quantity++;
print("Not Empty"); // Here i am expecting to show qty 2 if i click an item more than 1 time
} else {
print("Empty");
cart.add(event.dish);
}
Basically, we need to check whether the cart already has a dish with the same id or not. If the cart contains the dish with this id we increment dish quantity else we just add a dish to the cart.
Besides that, I see a potential problem with your code. Bloc to work properly requires either creating new instances of models or properly implementing of equals and hashCode. So even the code above may not work properly due to this problem. Be aware of it. You can fix it using this package.

Local camera in first video call is not working in Flutter app with Agora (using agora_rtc_engine 4.0.7)

I integrated Agora in Flutter Application with the help of agora_rtc_engine 4.0.7, but upon making a video call for the very first time the local camera view is not working. When we disconnect the call and call back again then everything works fine, the local camera view started working.
Again when we kill the application from Phone memory and rerun it then also the same problem occurs for the first time.
VideoCallingScreen.dart file
class VideoCallingScreen extends StatefulWidget {
String doctorId;
String bookingId;
VideoCallingScreen(this.doctorId, this.bookingId);
#override
_VideoCallingScreenState createState() => _VideoCallingScreenState();
}
class _VideoCallingScreenState extends State<VideoCallingScreen> {
int? _remoteUid;
RtcEngine? _engine;
bool isJoined = false,
switchCamera = true,
switchRender = true,
muteAudio = false,
muteVideo = false;
bool remoteUserMicMute = false, remoteUserVideoMute = false;
bool resizeVideo = false;
ServerHandler _serverHandler = ServerHandler();
String? token;
String? channelName;
String? channelId;
late user.Details userDetails;
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
#override
void initState() {
super.initState();
getAgoraToken().then((value) {
if (value) {
initForAgora();
} else {
_showMyDialog();
}
});
// initForAgora();
}
Future<void> _showMyDialog() async {
return showDialog<void>(
context: context,
barrierDismissible: false, // user must tap button!
builder: (BuildContext context) {
return AlertDialog(
title: const Text('No Channel Found'),
content: SingleChildScrollView(
child: ListBody(
children: const <Widget>[
Text('No video channel has been created by the Doctor'),
],
),
),
actions: <Widget>[
TextButton(
child: const Text('Ok'),
onPressed: () async {
// int count = 0;
Navigator.pop(context);
Navigator.pop(_scaffoldKey.currentContext!);
},
),
],
);
},
);
}
Future<bool> getAgoraToken() async {
await Screen.keepOn(true);
var tokenBody = await _serverHandler.joinAgoraChannel(
widget.doctorId, widget.bookingId);
print('token Body from videoPage' + tokenBody.toString());
if (tokenBody['success'] == 1) {
setState(() {
token = tokenBody['channel']['access_token_patient'];
channelName = tokenBody['channel']['channel_name'];
print('**********Token Set********' + token!);
channelId = tokenBody['channel']['id'].toString();
});
return true;
} else {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text(
"Unable to get Video Call Token, Please check your internet Connection and try again."),
));
return false;
}
}
Future<void> initForAgora() async {
// retrieve permissions
await [Permission.microphone, Permission.camera].request();
userDetails = await _serverHandler.getUserProfile();
//create the engine
_engine = await RtcEngine.create(appId);
await _engine?.enableVideo();
_engine?.setEventHandler(
RtcEngineEventHandler(
joinChannelSuccess: (String channel, int uid, int elapsed) async {
print("local user $uid joined");
// await _engine!.enableVideo();
},
userJoined: (int uid, int elapsed) {
print("remote user $uid joined");
setState(() {
_remoteUid = uid;
});
},
tokenPrivilegeWillExpire: (token) async {
await getAgoraToken();
await _engine?.renewToken(token);
},
userOffline: (int uid, UserOfflineReason reason) {
print("remote user $uid left channel");
// _engine!.enableVideo();
setState(() {
_remoteUid = null;
});
_userLeftTheCall();
},
userMuteVideo: (int uid, bool isMute) {
print('Audio Mutted');
setState(() {
remoteUserVideoMute = isMute;
});
},
userMuteAudio: (int uid, bool isMute) {
print('Audio Mutted');
setState(() {
remoteUserMicMute = isMute;
});
},
),
);
await getAgoraToken();
await _engine?.joinChannel(token, channelName!, null, userDetails.id!);
}
// Create UI with local view and remote view
#override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: _onWillPop,
child: Scaffold(
key: _scaffoldKey,
body: SafeArea(
child: Stack(
children: [
Center(
child:
resizeVideo ? _renderLocalPreview() : _renderRemoteVideo(),
),
if (remoteUserVideoMute)
BackdropFilter(
filter: ImageFilter.blur(
sigmaX: 10,
sigmaY: 10,
),
child: Padding(
padding: const EdgeInsets.only(bottom: 32),
child: Center(
child: Text(
'Doctor video Paused',
style: TextStyle(
color: Colors.white,
fontSize: 16,
fontWeight: FontWeight.bold),
textAlign: TextAlign.center,
),
),
),
),
if (remoteUserMicMute)
Padding(
padding: const EdgeInsets.only(top: 32),
child: Center(
child: Text(
'Doctor Mic Muted',
style: TextStyle(
color: Colors.white,
fontSize: 16,
fontWeight: FontWeight.bold),
textAlign: TextAlign.center,
),
),
),
Positioned(
top: 8,
left: 8,
child: InkWell(
//Uncomment it to unable resize
// onTap: () {
// setState(() {
// resizeVideo = !resizeVideo;
// });
// },
child: Container(
width: 100,
height: 120,
child: Stack(
children: [
ImageFiltered(
imageFilter: muteVideo
? ImageFilter.blur(sigmaX: 3.0, sigmaY: 3.0)
: ImageFilter.blur(sigmaX: 0, sigmaY: 0),
child: resizeVideo
? _renderRemoteVideo()
: _renderLocalPreview(), // Widget that is blurred
),
if (muteVideo)
Positioned(
top: 4,
left: 4,
child: Icon(
Icons.videocam_off_outlined,
color: Colors.white,
size: 32,
),
),
if (muteAudio)
Positioned(
bottom: 4,
right: 4,
child: Icon(
Icons.mic_off_outlined,
color: Colors.white,
size: 32,
),
),
],
),
),
),
),
Positioned(
bottom: 32,
right: 8,
left: 8,
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
InkWell(
onTap: () async {
await Screen.keepOn(false);
await _engine?.leaveChannel();
await _serverHandler.leaveChannel(channelId!);
Navigator.pop(_scaffoldKey.currentContext!);
},
child: Container(
padding: EdgeInsets.all(16),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(50),
color: Colors.red),
child: Icon(
Icons.call_end,
color: Colors.white,
),
),
),
InkWell(
onTap: this._switchCamera,
child: Container(
padding: EdgeInsets.all(16),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(50),
color: Colors.white),
child: Icon(
Icons.flip_camera_android_rounded,
color: Colors.black87,
),
),
),
InkWell(
onTap: this._onToggleMuteVideo,
child: Container(
padding: EdgeInsets.all(16),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(50),
color: Colors.white),
child: Icon(
muteVideo
? Icons.videocam_off_outlined
: Icons.videocam_outlined,
color: Colors.black87,
),
),
),
InkWell(
onTap: this._onToggleMute,
child: Container(
padding: EdgeInsets.all(16),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(50),
color: Colors.white),
child: Icon(
muteAudio
? Icons.mic_off_outlined
: Icons.mic_none_outlined,
color: Colors.black87,
),
),
),
],
),
)
],
),
),
),
);
}
// current user video
Widget _renderLocalPreview() {
return RtcLocalView.SurfaceView();
}
// remote user video
Widget _renderRemoteVideo() {
// return RtcRemoteView.SurfaceView(uid: 70);
if (_remoteUid != null) {
return RtcRemoteView.SurfaceView(uid: _remoteUid!);
} else {
return Text(
'Please wait, doctor is joining shortly',
style: TextStyle(
color: Colors.white, fontSize: 16, fontWeight: FontWeight.bold),
textAlign: TextAlign.center,
);
}
}
_switchCamera() {
_engine?.switchCamera().then((value) {
setState(() {
switchCamera = !switchCamera;
});
}).catchError((err) {
log('switchCamera $err');
});
}
void _onToggleMute() {
setState(() {
muteAudio = !muteAudio;
});
_engine!.muteLocalAudioStream(muteAudio);
}
void _onToggleMuteVideo() {
setState(() {
muteVideo = !muteVideo;
});
_engine!.muteLocalVideoStream(muteVideo);
}
Future<bool> _onWillPop() async {
return (await showDialog(
context: _scaffoldKey.currentContext!,
builder: (context) => new AlertDialog(
title: new Text('Are you sure?'),
content: new Text('Do you want to exit exit Video Call?'),
actions: <Widget>[
TextButton(
onPressed: () => Navigator.pop(_scaffoldKey.currentContext!),
child: new Text('No'),
),
TextButton(
onPressed: () async {
await Screen.keepOn(false);
await _serverHandler.leaveChannel(channelId!);
await _engine?.leaveChannel();
Navigator.pop(_scaffoldKey.currentContext!);
Navigator.pop(_scaffoldKey.currentContext!);
},
child: new Text('Yes'),
),
],
),
)) ??
false;
}
_userLeftTheCall() async {
return (await showDialog(
context: _scaffoldKey.currentContext!,
builder: (context) => new AlertDialog(
title: new Text('Doctor Left'),
content: new Text('Doctor left this call please join Again'),
actions: <Widget>[
TextButton(
onPressed: () async {
// await _serverHandler.leaveChannel(channelId!);
await Screen.keepOn(false);
await _engine?.leaveChannel();
Navigator.pop(_scaffoldKey.currentContext!);
Navigator.pop(_scaffoldKey.currentContext!);
// Navigator.of(context).pop(true);
},
child: new Text('Okay'),
),
],
),
)) ?? false;
}
}
Please ignore things which are not relevent. Also the log is too long to share, the log keeps on running during the entire video call.
Mobile Screenshot
Thank You

how to get data in material datatable in flutter from rest api

I want to show data in material dataTable but instead of getting data in a row it makes the table head every time with the row
My design which I Want:
The design I am getting right now:
Here is the full code of my flutter application:
UI SCREEN
________________This is Ui part of my application_
import 'package:aiims/bloc/add_relatives_bloc.dart';
import 'package:aiims/models/relative.dart';
import 'package:aiims/service/api.dart';
import 'package:aiims/widgets/side_menu_widget.dart';
import 'package:flutter/material.dart';
import 'package:outline_material_icons/outline_material_icons.dart';
import 'package:provider/provider.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'dart:async';
class RelativeScreen extends StatefulWidget {
#override
_RelativeScreenState createState() => _RelativeScreenState();
}
class _RelativeScreenState extends State<RelativeScreen> {
GlobalKey<FormState> _formKey = GlobalKey<FormState>();
DataRow getDataRow(data) {
return DataRow(
cells: <DataCell>[
DataCell(Text(data["name"])),
DataCell(Text(data["age"])),
DataCell(Text(data["relation"])),
DataCell(
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Icon(Icons.edit_outlined),
Icon(Icons.delete_outline_sharp),
],
),
),
],
);
}
#override
void initState() {
// TODO: implement initState
super.initState();
// _getDataRow(list.length);
}
// _getRelatives() {
// getRelativesList().then((Relative) {
// setState(() {
//
// });
// print("Length: ${_relative.length}");
// });
// }
// DataRow _getDataRow(list) {
// return DataRow(
// cells: <DataCell>[
// DataCell(Text(list["name"])),
// DataCell(Text(list["age"])),
// DataCell(Text(list["relation"])),
// ],
// );
// }
#override
Widget build(BuildContext context) {
final bloc = Provider.of<AddNewRelativeBloc>(context, listen: false);
return Scaffold(
drawer: NavDrawer(),
appBar: AppBar(
title: Text('Relatives'),
actions: <Widget>[
GestureDetector(
onTap: () => _add_relavitves(),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: Icon(Icons.add_circle_outline_rounded),
),
),
],
),
body: SafeArea(
child: Padding(
padding: const EdgeInsets.all(5.0),
child: Container(
// alignment: Alignment.center,
padding: EdgeInsets.symmetric(vertical: 20),
child: SingleChildScrollView(
child: Container(
child: FutureBuilder(
future: getRelativesList(),
// initialData: new TreatmentDetail(),
builder: (context, snapshot) {
if (snapshot.hasError) {
return Center(
child: Text(snapshot.error.toString()),
);
} else if (snapshot.connectionState ==
ConnectionState.done) {
return ListView.builder(
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: list.length,
itemBuilder: (context, index) {
return DataTable(
headingRowColor: MaterialStateColor
.resolveWith(
(states) => Color(0xffff69b4)),
// MaterialStateColor.resolveWith((states) => Colors.pink),
columns: [
DataColumn(label: Text("Name")),
DataColumn(label: Text("Age")),
DataColumn(label: Text("Relation")),
DataColumn(label: Text("Action")),
],
// rows: List.generate(
// list.length, (index) =>
// _getDataRow(list[index]),
// ));
rows: [
DataRow(
cells: [
DataCell(Text(list[index]["name"])),
DataCell(Text(list[index]["age"])),
DataCell(Text(list[index]["relation"])),
DataCell(
Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Icon(Icons.edit_outlined),
Icon(Icons.delete_outline_sharp),
],
),
),
],
),
// DataRow(cells: [
// DataCell(Text('Ajay Singh')),
// DataCell(Text('25')),
// DataCell(Text('Son')),
// DataCell(
// Row(
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
// children: [
// Icon(Icons.edit_outlined),
// Icon(Icons.delete_outline_sharp),
// ],
// ),
// ),
// ]),
],
);
});
} else {
return Center(
child: CircularProgressIndicator(),
);
}
}),
),
),
),
),
),
);
}
void _add_relavitves() {
final bloc = Provider.of<AddNewRelativeBloc>(context, listen: false);
// set up the buttons
// Widget cancelButton = FlatButton(
// child: Text("Cancel"),
// onPressed: () {
// Navigator.pop(context);
// },
// );
Widget cancelButton = MaterialButton(
child: Container(
height: 40,
width: 110,
alignment: Alignment.center,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: Color(0xffff69b4),
),
child: Text(
"Discard",
style: TextStyle(
color: Colors.white,
fontSize: 20,
),
),
),
onPressed: () {
Navigator.pop(context);
},
);
Widget continueButton = FlatButton(
child: Text("Continue"),
onPressed: () {},
);
// set up the AlertDialog
AlertDialog alert = AlertDialog(
title: Center(
child: Text(
"Add New Relative",
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
),
content: SingleChildScrollView(
child: Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
SizedBox(height: 20),
StreamBuilder<Object>(
stream: bloc.name,
builder: (context, snapshot) {
return TextField(
keyboardType: TextInputType.text,
decoration: InputDecoration(
hintText: "Name",
labelText: "Name",
errorText: snapshot.error,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
),
),
// onChanged: (value) => bloc.changeName,
onChanged: bloc.changeName,
);
}),
SizedBox(height: 20),
StreamBuilder<Object>(
stream: bloc.age,
builder: (context, snapshot) {
return TextField(
keyboardType: TextInputType.number,
decoration: InputDecoration(
hintText: "Age",
labelText: "Age",
errorText: snapshot.error,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
),
),
// onChanged: (value) => bloc.changeName,
onChanged: bloc.changeAge,
);
}),
SizedBox(height: 20),
StreamBuilder<Object>(
stream: bloc.relation,
builder: (context, snapshot) {
return TextField(
keyboardType: TextInputType.text,
decoration: InputDecoration(
hintText: "Relation",
labelText: "Relation",
errorText: snapshot.error,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
),
),
// onChanged: (value) => bloc.changeName,
onChanged: bloc.changeRelation,
);
}),
SizedBox(height: 20),
StreamBuilder<Object>(
stream: bloc.phoneNumber,
builder: (context, snapshot) {
return TextField(
keyboardType: TextInputType.number,
decoration: InputDecoration(
hintText: "Phone Number",
labelText: "Phone Number",
errorText: snapshot.error,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
),
),
// onChanged: (value) => bloc.changeName,
onChanged: bloc.changePhoneNumber,
);
}),
],
),
),
),
actions: [
cancelButton,
_saveButton(),
],
);
// show the dialog
showDialog(
context: context,
builder: (BuildContext context) {
return alert;
},
);
}
Widget _saveButton() {
final bloc = Provider.of<AddNewRelativeBloc>(context, listen: false);
return StreamBuilder<Object>(
stream: bloc.isValid,
builder: (context, snapshot) {
return GestureDetector(
onTap: snapshot.hasError || !snapshot.hasData
? null
: () {
bloc.submit();
},
child: Container(
height: 40,
width: 130,
alignment: Alignment.center,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: snapshot.hasError || !snapshot.hasData
? Color(0xffff69b4)
: Colors.green,
),
child: Text(
"Save",
style: TextStyle(
color: Colors.white,
fontSize: 20,
),
),
),
);
});
}
}
//My Future for getting response from api
Future<List> getRelativesList() async {
final response =
await http.get("$baseUrl");
Map<String, dynamic> map = json.decode(response.body);
List<dynamic> data = map["data"];
print("first id on console" + data[0]["id"].toString());
return list = data;
}
//Here is my model
class Relative {
int _code;
String _message;
List<Data> _data;
Relative({int code, String message, List<Data> data}) {
this._code = code;
this._message = message;
this._data = data;
}
int get code => _code;
set code(int code) => _code = code;
String get message => _message;
set message(String message) => _message = message;
List<Data> get data => _data;
set data(List<Data> data) => _data = data;
Relative.fromJson(Map<String, dynamic> json) {
_code = json['code'];
_message = json['message'];
if (json['data'] != null) {
_data = new List<Data>();
json['data'].forEach((v) {
_data.add(new Data.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['code'] = this._code;
data['message'] = this._message;
if (this._data != null) {
data['data'] = this._data.map((v) => v.toJson()).toList();
}
return data;
}
}
class Data {
int _id;
int _patientId;
String _name;
String _age;
String _relation;
String _phoneNo;
Data(
{int id,
int patientId,
String name,
String age,
String relation,
String phoneNo}) {
this._id = id;
this._patientId = patientId;
this._name = name;
this._age = age;
this._relation = relation;
this._phoneNo = phoneNo;
}
enter code here
int get id => _id;
set id(int id) => _id = id;
int get patientId => _patientId;
set patientId(int patientId) => _patientId = patientId;
String get name => _name;
set name(String name) => _name = name;
String get age => _age;
set age(String age) => _age = age;
String get relation => _relation;
set relation(String relation) => _relation = relation;
String get phoneNo => _phoneNo;
set phoneNo(String phoneNo) => _phoneNo = phoneNo;
Data.fromJson(Map<String, dynamic> json) {
_id = json['id'];
_patientId = json['patient_id'];
_name = json['name'];
_age = json['age'];
_relation = json['relation'];
_phoneNo = json['phone_no'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this._id;
data['patient_id'] = this._patientId;
data['name'] = this._name;
data['age'] = this._age;
data['relation'] = this._relation;
data['phone_no'] = this._phone`enter code here`No;
return data;
}
}
You return DataTable as an item for ListView.builder, that is why you see header and row. If you want display only table then remove ListView widget and return DataTable with rows. Something like
FutureBuilder(
builder: (context, snapshot) {
return DataTable(
columns: <DataColumn>[
...
],
rows: list.map((item) {
return DataRow(
cells: <DataCell>[...]
);
}),
),
}
)