I want to get data of inventory but not getting. I am doing API integration without model because there are some issues in Model just to get data and want to display in to my view.
this is my service class of get data through API.
Future<dynamic> getInventory() async {
var data;
String? userId = await preferenceService.getuserId();
String? accessToken = await preferenceService.getAccessToken();
var response = await http.get(Uri.parse('${AppUrl.getInventory}/$userId'),
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
'Authorization': 'Barear $accessToken'
});
print("The data of the specific inventory ===========>>>>>>>> " +
response.body.toString());
if (response.statusCode == 200) {
data = jsonDecode(response.body);
print('This is futr dsta --->>> $data');
} else {
data=[];
}
return data;
}
This is my controller class where i am using above service function
Future getMyInvenoryFromService() async {
try {
isLoadingInventory(true);
await inventoryService.getInventory().then((val) {
if (val != []) {
inventoryData = val;
} else {
inventoryData = [];
}
});
} finally {
isLoadingInventory(false);
}
}
But when i am accessing the data with inventoryData (in controller) i am getting null, but in controller i am getting values when debugging. but i am not understanding why i am receiving null values in view.
This is my view,
class _UserInventoryScreenState extends State<UserInventoryScreen> {
InventoryController inventoryController = Get.put(InventoryController());
InventoryService inventoryService = InventoryService();
GiftController giftController = Get.put(GiftController());
GiftStorageService giftStorageService = GiftStorageService();
#override
void initState() {
super.initState();
/*Future delay() async {
await new Future.delayed(new Duration(milliseconds: 3000), () {
inventoryController.getMyInvenoryFromService();
});
}*/
Timer.run(() {
inventoryController.getMyInvenoryFromService();
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: AppColors.pinkAppBar,
appBar: AppBar(
elevation: 0,
backgroundColor: Colors.transparent,
leading: InkWell(
onTap: () {
Get.back();
},
child: Icon(Icons.arrow_back)),
title: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('Inventory'),
InkWell(
onTap: () {
Get.to(AddInventoryScreen());
},
child: Container(
padding: EdgeInsets.symmetric(horizontal: 10, vertical: 5),
decoration:
BoxDecoration(border: Border.all(color: Colors.white)),
child: Text(
"Add Inventory",
style: TextStyle(fontSize: 16),
),
),
)
],
),
),
body: Obx(() {
return inventoryController.isLoadingInventory.value == true
? Center(child: CircularProgressIndicator())
: ElevatedButton(
onPressed: () async {
await inventoryController.getMyInvenoryFromService();
},
child: Text("${inventoryController.inventoryData.length}"),
);
If your response.statusCode isn't 200 it might be because you are setting wrong your headers:
'Authorization': 'Barear $accessToken'
Change it to:
'Authorization': 'Bearer $accessToken'
Related
I am trying to parse a JSON after doing a HTTP GET request for my flutter app, however when it is parsed, the body shows as empty, this is the parsing code
urlHausParseBox() {
Future<_GoneSmishinState> fetchUrlResponse() async {
String url = myController.text;
final response = await http.post(
Uri.parse("https://urlhaus-api.abuse.ch/v1/url/"),
headers: <String, String>{
'Accept': 'application/json',
},
body: (<String, String>{
'url': url,
'query_status': query_status,
'url_status' : url_status,
//'status' : status,
//'urlStatus' : urlStatus,
}));
After this I have a check for the 200 status, and when recieved will return this to use after the fact, I printed the fields 'query_status' and 'url_status' but they came up empty so I printed what I was returning here
if (response.statusCode == 200) {
print (_GoneSmishinState.fromJson(jsonDecode(response.body)));
return _GoneSmishinState.fromJson(jsonDecode(response.body));
but all that is printed out is _GoneSmishinState#23f48(lifecycle state: created, no widget, not mounted)
which is not what is supposed to be returned by the HTTP GET request
The rest of my code is below
import 'dart:convert';
import 'package:validators/validators.dart';
import 'package:flutter/material.dart';
import 'package:sms/sms.dart';
import 'dart:io';
import 'dart:developer' as developer;
import 'package:http/http.dart' as http;
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
String url = "https://urlhaus-api.abuse.ch/v1/urls/recent/"; //address for URL file
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key:key);
#override
Widget build(BuildContext context) {
return const MaterialApp(
title: "Gone Smishin'",
home: GoneSmishin(),
);
}
}
class GoneSmishin extends StatefulWidget {
const GoneSmishin({Key? key}) : super(key: key);
State<GoneSmishin> createState() {
return _GoneSmishinState(url_status: '', query_status: '');
}
}
class _GoneSmishinState extends State<GoneSmishin> {
String message = "";
String word = "";
bool isOn = false;
final myController = TextEditingController();
#override
void dispose() {
myController.dispose();
super.dispose();
}
_GoneSmishinState({
required this.query_status,
required this.url_status,
});
final String query_status;
final String url_status;
factory _GoneSmishinState.fromJson(Map<String, dynamic> json) {
return _GoneSmishinState(
query_status: json["query_status"],
url_status: json["url_status"],
);
}
urlHausParseBox() {
Future<_GoneSmishinState> fetchUrlResponse() async {
String url = myController.text;
final response = await http.post(
Uri.parse("https://urlhaus-api.abuse.ch/v1/url/"),
headers: <String, String>{
'Accept': 'application/json',
},
body: (<String, String>{
'url': url,
'query_status': query_status,
'url_status' : url_status,
}));
if (response.statusCode == 200) {
print (_GoneSmishinState.fromJson(jsonDecode(response.body)));
return _GoneSmishinState.fromJson(jsonDecode(response.body));
} else {
throw Exception('Failed to load website');
}
}
fetchUrlResponse();
if (query_status == "ok" && url_status == "online") {
const Text ('Found in URLHause Database - Probably Smishing');
print("found");
} else if (query_status == "ok" && url_status == "offline") {
const Text ('Found in URLHaus, not online');
print("found offline");
} else {
const Text ('Found Nothing');
print("not found");
print (query_status);
print (url_status);
}
_pushInput() {
Navigator.of(context).push(
MaterialPageRoute<void>(
builder: (context) {
return Scaffold(
appBar: AppBar(
title: const Text ('Submit a Link')
),
body: (
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextField (
controller: myController,
decoration: InputDecoration(
border: OutlineInputBorder(),
hintText: 'Enter your Link Text',
contentPadding: EdgeInsets.symmetric(
vertical: 40, horizontal: 20),
),
),
ElevatedButton(
onPressed: () {
urlHausParseBox();
},
child: const Text('Submit')
)
]
)
));
}
)
);
}
#override
var buttonText = 'OFF';
String textHolder = "App is Off";
changeTextON() {
setState(() {
textHolder = "App is ON";
});
isOn == true;
}
changeTextOFF() {
setState(() {
textHolder = "App is OFF";
});
isOn == false;
}
Widget build(BuildContext context) {
final ButtonStyle outlineButtonStyle = OutlinedButton.styleFrom(
primary: Colors.black87,
minimumSize: Size(200, 130),
padding: EdgeInsets.symmetric(horizontal: 200),
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(300)),
),
).copyWith(
side: MaterialStateProperty.resolveWith<BorderSide>(
(Set<MaterialState> states) {
return BorderSide(
color: Theme.of(context).colorScheme.primary,
width: 1,
);
},
),
);
return Scaffold(
appBar: AppBar(
title: const Text("Gone Smishin'"),
actions: [
IconButton(
icon: const Icon(Icons.add_link),
onPressed: _pushInput,
tooltip: 'Submit a Link'
)
],
backgroundColor: Colors.red,
),
body: Column (
children: [
Container(
padding: EdgeInsets.fromLTRB(50, 50, 50, 50),
child: Text('$textHolder',
style: TextStyle(fontSize: 50)
),
),
Container(
//child: Text(result)
),
TextButton(
style: outlineButtonStyle,
onPressed: () {
changeTextON();
},
child: Text('ON')
),
TextButton(
style: outlineButtonStyle,
onPressed: () {
changeTextOFF();
},
child: Text("OFF"),
)
]
),
);
}
}
Change this:
_GoneSmishinState({
required this.query_status,
required this.url_status,
});
final String query_status;
final String url_status;
factory _GoneSmishinState.fromJson(Map<String, dynamic> json) {
return _GoneSmishinState(
query_status: json["query_status"],
url_status: json["url_status"],
);
}
to this:
_GoneSmishinState();
var queryStatus = '';
var urlStatus = '';
and this:
if (response.statusCode == 200) {
print (_GoneSmishinState.fromJson(jsonDecode(response.body)));
return _GoneSmishinState.fromJson(jsonDecode(response.body));
}
to:
if (response.statusCode == 200) {
setState(() {
final decoded = json.decode(response.body);
queryStatus = decoded['query_status'];
urlStatus = decoded['url_status'];
}
);
}
And, finally, patch up any unused/misnamed variables. As an aside, it's difficult to read functions declared inside other functions. Is fetchUrlResponse inside urlHausParseBox? Move it outside.
When I tried to change the state from outside the function the state is not changing.
void _showAlertDialog(BuildContext context) {
// flutter defined function
showDialog(
context: context,
builder: (BuildContext context) {
// return object of type Dialog
return AlertDialog(
title: const Text("Diabetes Prediction"),
content: StatefulBuilder(
return _predictedResult == "" ? Column(
mainAxisSize: MainAxisSize.min,
children: [
const CircularProgressIndicator(),
Text(loadingText),
],
) : Text(_predictedResult);
},
),
actions: <Widget>[
// usually buttons at the bottom of the dialog
TextButton(
child: const Text("OK"),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
Elevated button helps in calling the _showAlertDialog the loadingText is declared inside the class
ElevatedButton(
child: const Text("Predict"),
onPressed: () async {
// Pregnancies, Glucose, Blood Pressure, Insulin, Skin Thickness, Pedigree Function, Weight,
// Height, Age
_predictedResult = "";
loadingText = "";
var data = _formatData();
var result = Serializer().serialize(data);
_showAlertDialog(context);
setState(() {
loadingText = "Sending data to server...";
});
await Future.delayed(const Duration(seconds: 2), (){
});
setState(() {
loadingText = "Analyzing data...";
});
// await Future.delayed(const Duration(seconds: 2), (){
// print("data received");
// });
await _predict(result);
},
),
The output comes as Sending data to server...
String _predictedResult = '';
StreamController<String>? controller;
String loadingText = '';
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.grey[900],
body: Center(
child: ElevatedButton(
child: const Text("Predict"),
onPressed: () async {
controller = StreamController<String>();
// Pregnancies, Glucose, Blood Pressure, Insulin, Skin Thickness, Pedigree Function, Weight,
// Height, Age
_predictedResult = "";
loadingText = "";
_showAlertDialog(context);
controller!.add("Sending data to server...");
await Future.delayed(const Duration(seconds: 2), () {});
controller!.add("Analyzing data...");
await Future.delayed(const Duration(seconds: 2), () {
print("data received");
});
controller!.add("data received!");
},
),
),
);
}
void _showAlertDialog(BuildContext context) {
// flutter defined function
showDialog(
context: context,
builder: (BuildContext context) {
// return object of type Dialog
return AlertDialog(
title: const Text("Diabetes Prediction"),
content: StreamBuilder(
stream: controller!.stream,
builder: (context, AsyncSnapshot<String> snap) {
return _predictedResult == ""
? Column(
mainAxisSize: MainAxisSize.min,
children: [
const CircularProgressIndicator(),
Text(snap.data ?? "Loading..."),
],
)
: Text(_predictedResult);
},
),
actions: <Widget>[
// usually buttons at the bottom of the dialog
TextButton(
child: const Text("OK"),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
Use Stream
Flutter Stream Basics for Beginners
i want to delete an object from list of inventory in which i just have description and url of the inventory and i want to delete object of inventory by description so how can i delete the object.
function in service class
Future<dynamic> requestToRemoveInventory(
String accessToken, List<TradeWithPictures> list) async {
try {
var response = await http.patch(Uri.parse(AppUrl.removeInventory),
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
'Authorization': 'Bearer $accessToken'
},
body: jsonEncode({"inventory": list}));
if (response.statusCode == 200 || response.statusCode == 201) {
var responseJson = jsonDecode(response.body);
return responseJson;
} else {
var responseJson = jsonDecode(response.body);
print(responseJson);
}
} on SocketException {
throw NoInternetException('No Internet Service');
}
}
Function Controller class
deleteInventory(List<TradeWithPictures> list, BuildContext context) async {
String? accessToken = await preferenceService.getAccessToken();
inventoryService.requestToRemoveInventory(accessToken!, list).then((value) {
getMyInvenoryFromService();
}).catchError((error) {
showSnackBar(error.toString(), context);
});
}
please tell me what logic i have to write in view to delete the object. when i am deleting then all list is removed.
this is my view
PopupMenuItem(
onTap: () {
var list = inventoryController
.myInventoryList1
.where((i) =>
i.description !=
inventoryController
.myInventoryList1[
index]
.description)
.toList();
inventoryController
.deleteInventory(
list, context);
},
value: 1,
child: Padding(
padding:
const EdgeInsets.all(
8.0),
child: Text(
"Delete",
style: TextStyle(
color: AppColors
.pinkAppBar,
fontWeight:
FontWeight.w700),
),
),
),
Here is a simple example of how you can filter out your results from a list,
filteredResulst = AllRecords.where((i) => i.aParticularProperty === thingToCompare ).toList();
I am stacked!! and i know i will find help here . I create a flutter application which fetches data from news.org API . Everything was working fine until i started implementing BLOC in the app . I have successfully implemented the first part with BLOC with fetches all the data from the API . the next thing to do is to fetch another data using the categories provided by the API in another page using BLOC .
For instance , there are categories like business , technology , finance etc . So main thing is when the user taps on any of the category the data show be fetched from the API using BLOC .
the following are the codes for the bloc ...
THIS IS THE ERROR I GET
════════ Exception caught by widgets library ═══════════════════════════════════════════════════════
The following assertion was thrown building BlocListener<ArticleBloc, ArticleState>(dirty, state: _BlocListenerBaseState<ArticleBloc, ArticleState>#aae07):
A build function returned null.
The offending widget is: BlocListener<ArticleBloc, ArticleState>
Build functions must never return null.
To return an empty space that causes the building widget to fill available room, return "Container()". To return an empty space that takes as little room as possible, return "Container(width: 0.0, height: 0.0)".
The relevant error-causing widget was:
BlocListener<ArticleBloc, ArticleState> file:///C:/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_bloc-6.1.1/lib/src/bloc_builder.dart:149:12
When the exception was thrown, this was the stack:
#0 debugWidgetBuilderValue. (package:flutter/src/widgets/debug.dart:302:7)
#1 debugWidgetBuilderValue (package:flutter/src/widgets/debug.dart:323:4)
#2 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4632:7)
#3 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:4800:11)
#4 Element.rebuild (package:flutter/src/widgets/framework.dart:4343:5)
...
════════════════════════════════════════════════════════════════════════════════════════════════════
RepositoRy
abstract class CategoryRepository {
Future<List<Article>> getCategory(String category);
}
class CatService implements CategoryRepository {
#override
Future<List<Article>> getCategory(String category) async {
// List<Article> categoryNewsList = [];
String url =
"http://newsapi.org/v2/top-headlines?country=us&category=$category&apiKey=df74fc47f0dd401bb5e56c34893a7795";
return getData(url);
/*var response = await http.get(url);
//decode the response into a json object
var jsonData = jsonDecode(response.body);
//check if the status of the response is OK
if (jsonData["status"] == "ok") {
jsonData["articles"].forEach((item) {
//check if the imageUrl and description are not null
if (item["urlToImage"] != null && item["description"] != null) {
//create an object of type NewsArticles
Article newsArticleModel = new Article(
author: item["author"],
title: item["title"],
description: item["description"],
url: item["url"],
urlToImage: item["urlToImage"],
content: item["content"]);
//add data to news list
categoryNewsList.add(newsArticleModel);
}
});
}
return categoryNewsList;*/
}
}
Future<List<Article>> getData(String url) async {
List<Article> items = [];
var response = await http.get(url);
//decode the response into a json object
var jsonData = jsonDecode(response.body);
//check if the status of the response is OK
if (jsonData["status"] == "ok") {
jsonData["articles"].forEach((item) {
//check if the imageUrl and description are not null
if (item["urlToImage"] != null && item["description"] != null) {
//create an object of type NewsArticles
Article article = new Article(
author: item["author"],
title: item["title"],
description: item["description"],
url: item["url"],
urlToImage: item["urlToImage"],
content: item["content"]);
//add data to news list
items.add(article);
}
});
}
return items;
}
Bloc
class ArticleBloc extends Bloc<ArticleEvent, ArticleState> {
CategoryRepository categoryRepository;
ArticleBloc({this.categoryRepository}) : super(ArticleInitial());
#override
Stream<ArticleState> mapEventToState(
ArticleEvent event,
) async* {
if (event is GetArticle) {
try {
yield ArticleLoading();
final articleList =
await categoryRepository.getCategory(event.category);
yield ArticleLoaded(articleList);
} catch (e) {
print(e.message);
}
}
}
}
Event
class GetArticle extends ArticleEvent{
final String category;
GetArticle(this.category);
}
States
#immutable
abstract class ArticleState {
const ArticleState();
}
class ArticleInitial extends ArticleState {
const ArticleInitial();
}
class ArticleLoading extends ArticleState {
const ArticleLoading();
}
class ArticleLoaded extends ArticleState {
final List<Article> articleList;
ArticleLoaded(this.articleList);
}
class ArticleError extends ArticleState {
final String error;
ArticleError(this.error);
#override
bool operator ==(Object object) {
if (identical(this, object)) return true;
return object is ArticleError && object.error == error;
}
#override
int get hashCode => error.hashCode;
}
UI
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'News app',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: BlocProvider(
child: TestCat(),
create: (context) => ArticleBloc(categoryRepository : CatService()),
),
);
}
}
tEST category page
class TestCat extends StatefulWidget {
#override
_TestCatState createState() => _TestCatState();
}
class _TestCatState extends State<TestCat> {
bool isLoading = true;
List<String> categoryItems;
#override
void initState() {
super.initState();
categoryItems = getAllCategories();
// getCategory(categoryItems[0]);
// getCategoryNews();
}
getCategory(cat) async {
context.bloc<ArticleBloc>().add(GetArticle(cat));
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: header(context, isAppTitle: false, title: "App"),
body: _newsBody(context),
);
}
_newsBody(context) {
return ListView(
children: [
//category list
Container(
padding:
EdgeInsets.symmetric(horizontal: NewsAppConstants().margin16),
height: NewsAppConstants().columnHeight70,
child: ListView.builder(
itemCount: categoryItems.length,
itemBuilder: (context, index) {
return TitleCategory(
title: categoryItems[index],
onTap: ()=> callCat(context, categoryItems[index]),
);
},
shrinkWrap: true,
scrollDirection: Axis.horizontal,
),
),
Divider(),
Container(
child: BlocBuilder<ArticleBloc, ArticleState>(
builder: (context, ArticleState articleState) {
//check states and update UI
if (articleState is ArticleInitial) {
return buildInput(context);
} else if (articleState is ArticleLoading) {
return Loading();
} else if (articleState is ArticleLoaded) {
List<Article> articles = articleState.articleList;
updateUI(articles);
} else if (articleState is ArticleError) {
// shows an error widget when something goes wrong
final error = articleState.error;
final errorMsg = "${error.toString()}\nTap to retry";
ShowErrorMessage(
errorMessage: errorMsg,
onTap: getCategory,
);
}
return buildInput(context);
}),
),
],
);
}
getAllCategories() {
List<String> categoryList = [
"Business",
"Entertainment",
"General",
"Sports",
"Technology",
"Health",
"Science"
];
return categoryList;
}
Widget updateUI(List<Article> newsList) {
return SingleChildScrollView(
child: Column(
children: [
Container(
child: ListView.builder(
physics: ClampingScrollPhysics(),
shrinkWrap: true,
itemCount: newsList.length,
itemBuilder: (context, index) {
return NewsBlogTile(
urlToImage: newsList[index].urlToImage,
title: newsList[index].title,
description: newsList[index].description,
url: newsList[index].url,
);
}),
),
Divider(),
],
));
}
buildInput(context) {
ListView.builder(
itemCount: categoryItems.length,
itemBuilder: (context, index) {
return TitleCategory(
title: categoryItems[index],
onTap: () {
print("tapped");
// callCat(context, categoryItems[index]);
},
);
},
shrinkWrap: true,
scrollDirection: Axis.horizontal,
);
}
callCat(BuildContext context, String cat) {
print(cat);
context.bloc<ArticleBloc>().add(GetArticle(cat));
}
}
//this displays the data fetched from the API
class NewsBlogTile extends StatelessWidget {
final urlToImage, title, description, url;
NewsBlogTile(
{#required this.urlToImage,
#required this.title,
#required this.description,
#required this.url});
#override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {},
child: Expanded(
flex: 1,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
margin: EdgeInsets.all(NewsAppConstants().margin8),
child: Column(
children: <Widget>[
ClipRRect(
borderRadius:
BorderRadius.circular(NewsAppConstants().margin8),
child: Image.network(urlToImage)),
Text(
title,
style: TextStyle(
fontWeight: FontWeight.w600,
color: Colors.black,
fontSize: NewsAppConstants().margin16),
),
SizedBox(
height: NewsAppConstants().margin8,
),
Text(
description,
style: TextStyle(color: Colors.black54),
)
],
),
),
Divider(),
],
),
),
);
}
}
//news title category
class TitleCategory extends StatelessWidget {
final title;
final Function onTap;
TitleCategory({this.title, this.onTap});
#override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () => onTap,
child: Container(
margin: EdgeInsets.all(NewsAppConstants().margin8),
child: Stack(
children: <Widget>[
ClipRRect(
borderRadius: BorderRadius.circular(NewsAppConstants().margin8),
child: Container(
child: Text(
title,
style: TextStyle(
color: Colors.white,
fontSize: NewsAppConstants().font16,
fontWeight: FontWeight.w500),
),
alignment: Alignment.center,
width: NewsAppConstants().imageWidth120,
height: NewsAppConstants().imageHeight60,
decoration: BoxDecoration(
borderRadius:
BorderRadius.circular(NewsAppConstants().margin8),
color: Colors.black,
),
),
)
],
),
),
);
}
}
from what I see
you might try one of the below solutions :
try in bloc builder to return Container and inside it handle you states like this :
builder: (context, state) {
return Container(
child: Column(
children: [
if (state is Loading)
CircularProgressIndicator(),
if (state is Loaded)
CatsListView(data: state.data),
try to cover all your kind of states in if/else in your Bloc builder
so let's assume that you have 2 states (state1, state2) so your Bloc builder
would be something like this
builder: (context, state) {
if (state is state1) return Container();
else if (state is state2) return Container();
else return Container();
note that if you covered all states you don't have to do the last else
I am trying to write a program to check if the time selected by the user already exists in the firebase firestore or not. If it does then I navigate back to the page where they select time again.
But as of now, I am succeeded in sending the date and time to firebase and but not the latter part.
DateTime _eventDate;
bool processing;
String _time;
bool conditionsStatisfied ;
#override
void initState() {
super.initState();
_eventDate = DateTime.now();
processing = false ;
}
inside showDatePicker()
setState(() {
print('inside the setState of listTile');
_eventDate = picked ;
});
inside the button (SAVE):
onPressed: () async {
if (_eventDate != null) {
final QuerySnapshot result = await FirebaseFirestore
.instance
.collection('events')
.where('event_date', isEqualTo: this._eventDate)
.where('selected_time', isEqualTo: this._time)
.get();
final List <DocumentSnapshot> document = result.docs;
if (document.length > 0) {
setState(() {
print('inside the method matching conditions');
showAlertDialogue(context);
});
}else{
final data = {
// "title": _title.text,
'selected_time ': this._time,
"event_date": this._eventDate
};
if (widget.note != null) {
await eventDBS.updateData(widget.note.id, data);
} else {
await eventDBS.create(data);
}
Navigator.pop(context);
setState(() {
processing = false;
});
}
};
some guidance needed on how do I resolve this issue!
Also, because of the else statement now the program won't write the date into firestore.
After Alot of research, I came to realize that if you send the data from calendar in DateTime format then, because of the timestamp at the end of the Date it becomes impossible to match to dates. Hence I formatted the DateTime value into (DD/MM/YYYY).
Here is the rest of the code for reference:
class _AddEventPageState extends State<AddEventPage> {
String _eventDate;
bool processing;
String _time;
#override
void initState() {
super.initState();
// _eventDate = DateTime.now();
processing = false ;
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Please select a date'),),
body: Column(
children: [
hourMinute30Interval(),
Text('$_time'),
ListView(
scrollDirection: Axis.vertical,
shrinkWrap: true,
children: <Widget>[
ListTile(
title: Text(
'$_eventDate'),
onTap: () async {
DateTime picked = await showDatePicker(context: context,
initialDate: DateTime.now(),
firstDate: DateTime(DateTime.now().year - 1),
lastDate: DateTime(DateTime.now().year + 10),);
if (picked != null) {
setState(() {
print('inside the setState of listTile');
_eventDate = DateFormat('dd/MM/yyyy').format(picked) ;
});
}
},
),
SizedBox(height: 10.0),
ListTile(
title: Center(
child: Text('Select time for appointment!', style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20,
),
),
),
),
processing
? Center(child: CircularProgressIndicator())
: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: Material(
elevation: 5.0,
borderRadius: BorderRadius.circular(30.0),
color: Theme
.of(context)
.primaryColor,
child:MaterialButton(
child: Text('SAVE', style: TextStyle(
fontSize: 20,
color: Colors.white,
fontWeight: FontWeight.bold,
)),
onPressed: () async {
if (_eventDate != null) {
AddingEventsUsingRajeshMethod().getAvailableSlots(
_eventDate, _time).then((QuerySnapshot docs) async {
if (docs.docs.length == 1) {
showAlertDialogue(context);
}
else{
final data = {
// "title": _title.text,
'selected_time': this._time,
"event_date": _eventDate,
};
if (widget.note != null) {
await eventDBS.updateData(widget.note.id, data);
} else {
await eventDBS.create(data);
}
Navigator.pop(context);
setState(() {
processing = false;
});
}
});
}
}
),
),
),
],
),
],
),
);
}
showAlertDialogue method :
showAlertDialogue(BuildContext context) {
Widget okButton = FlatButton(onPressed: (){
Timer(Duration(milliseconds: 500), () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => datePicker()),
);
});
}, child: Text(' OK! '));
AlertDialog alert = AlertDialog(
title: Text('Slot unavailable'),
content: Text('This slot is already booked please select another slot'),
actions: [
okButton,
],
);
showDialog(context: context ,
builder: (BuildContext context){
return alert ;
}
);
}
The hourMinute30Interval() is nothing but a Widget that returns a timePickerSpinner which is a custom Widget. Tap here for that.
The Query that is run after passing the _eventDate and _time is in another class, and it goes as follows :
class AddingEventsUsingRajeshMethod {
getAvailableSlots(String _eventDate , String _time){
return FirebaseFirestore.instance
.collection('events')
.where('event_date', isEqualTo: _eventDate )
.where('selected_time', isEqualTo: _time)
.get();
}
}
You can name it something prettier ;)