Ineffective Passing of Variable between Different Screens - flutter

I'm currently developing a Fingerspelling learning app. In the fingerspelling_screen.dart file, user will be able to choose which category that he/she would like to learn first. When the user chooses either one of the button, the app will query Firebase Firestore to get a list of signs object which contains the name of the sign, the category to which the sign belongs to and the video URL of each sign before navigating user to sign_video.dart which is a video player. From there, user can press next to switch to the next sign in the category. When the user presses on the check sign button, the user will be navigating to the check sign_checker.dart to check if they are performing a sign correctly.
I've been passing the 'category' variable from one screen to another using constructor and I do not think it is very effective. Is there any way I could solve this?
I wish to initilize vidlist variable (a variable that stores a list of Sign objects) in the initState because the video player controller needs to be initialized first. I've tried using StreamProvider, but for some reason, I couldn't initialize the vidlist variable in initState. The vidlist variable would always be null.
Thank you.
fingerspelling.dart
import 'package:slem_proto/screens/sign_video.dart';
import 'package:slem_proto/shared/constants.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:undraw/undraw.dart';
class FingerspellingScreen extends StatelessWidget {
static String routeName = 'fingerspelling_screen';
#override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: EdgeInsets.only(left: 20, right: 20, top: 50),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Fingerspelling',
style: kHeadingTextStyle,
),
SizedBox(height: 30),
FingerspellingTab(
title: 'Alphabets',
illustration: UnDrawIllustration.learning,
onTap: () {
print('Alphabet tab tapped');
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => SignVideoScreen(
category: 'alphabets',
),
),
);
},
),
SizedBox(
height: 15,
),
FingerspellingTab(
title: 'Numbers',
illustration: UnDrawIllustration.calculator,
onTap: () {
print('Number tab tapped');
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => SignVideoScreen(
category: 'numbers',
),
),
);
},
),
],
),
),
);
}
}
class FingerspellingTab extends StatelessWidget {
final String title;
final UnDrawIllustration illustration;
final Function onTap;
const FingerspellingTab(
{#required this.title,
#required this.illustration,
#required this.onTap});
#override
Widget build(BuildContext context) {
return InkWell(
child: Container(
width: double.infinity,
height: 250,
decoration: BoxDecoration(
color: Color.fromRGBO(58, 139, 238, 0.2),
borderRadius: BorderRadius.circular(20),
),
child: Padding(
padding: const EdgeInsets.only(left: 20, top: 20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
title,
style: kHeadingTextStyle.copyWith(
color: Color.fromRGBO(80, 80, 80, 0.8),
fontSize: 25,
),
),
SizedBox(
height: 15,
),
Container(
height: 150,
child: UnDraw(
color: Color(0xFF6C63FF),
illustration: illustration,
placeholder: Text(
"Illustration is loading..."), //optional, default is the CircularProgressIndicator().
),
),
],
),
),
),
onTap: onTap,
);
}
}
database.dart
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:slem_proto/models/sign.dart';
class DatabaseService {
// collection reference
final CollectionReference signCollection =
FirebaseFirestore.instance.collection('signs');
// Sign list from snapshot
List<Sign> _signListFromSnapshot(QuerySnapshot snapshot) {
return snapshot.docs.map((doc) {
return Sign(
category: doc.data()['category'] ?? '',
sign_name: doc.data()['sign_name'] ?? '',
sign_url: doc.data()['sign_url'] ?? '',
);
}).toList();
}
// get signs stream
Stream<List<Sign>> get signs {
return signCollection.snapshots().map(_signListFromSnapshot);
}
// get signs stream
Stream<List<Sign>> getSignFromCategory({String category}) {
return signCollection
.where('category', isEqualTo: category)
.snapshots()
.map(_signListFromSnapshot);
}
}
sign_checker.dart
import 'dart:convert';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:image_picker/image_picker.dart';
class SignChecker extends StatefulWidget {
final String category;
SignChecker({this.category});
#override
_SignCheckerState createState() => _SignCheckerState(category: this.category);
}
class _SignCheckerState extends State<SignChecker> {
final String category;
_SignCheckerState({this.category});
File _image;
bool predictionStarted = false;
bool predictionComplete = false;
var predictionResult = 'Please wait...';
Future getImage() async {
setState(() {
predictionStarted = false;
predictionComplete = false;
});
// Get image from camera
// var image = await ImagePicker.pickImage(source: ImageSource.camera);
// Get image from gallery
var image = await ImagePicker.pickImage(source: ImageSource.gallery);
setState(() {
_image = image;
predictionStarted = true;
});
// Base64 Encode the image
List<int> imageBytes = image.readAsBytesSync();
String base64Image = base64.encode(imageBytes);
// Print the base64 encoded string in console
print(base64Image);
// Send the encoded image with POST request
Map<String, String> headers = {"Accept": "application/json"};
Map body = {"image": base64Image};
// var response = await http.post('http://XX.XXX.XXX.X/automl.php',
// body: body, headers: headers);
var response = await http.post('http://XX.XXX.XXX.X/automl_alphabet.php',
body: body, headers: headers);
// Print the status code returned by server
print('Status code');
print(response.statusCode);
// Get prediction Result
setState(() {
predictionResult = response.body;
predictionComplete = true;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Sign Checker'),
),
body: SingleChildScrollView(
child: Column(
children: <Widget>[
SizedBox(
height: 20,
),
Text(
'Push the camera button',
textAlign: TextAlign.center,
),
RaisedButton(
onPressed: getImage,
child: Text('Camera'),
),
(_image != null)
? Image.file(
_image,
scale: 50,
)
: Text('No Image Picked'),
predictionBody()
],
),
),
);
}
Widget predictionBody() {
var predictionText = (predictionComplete) ? 'Result' : 'Prediction started';
if (predictionStarted) {
return Column(
children: <Widget>[
Divider(),
Text(predictionText),
Text(predictionResult)
],
);
} else {
return Container();
}
}
}
sign.dart
class Sign {
final String category;
final String sign_name;
final String sign_url;
Sign({this.category, this.sign_name, this.sign_url});
}

Firstly, using constructors to pass variables may not be inefficient, since Flutter only pass on references. Say,
var a = List(...huge list...);
var b = a;
Then the second line is not costly.
Secondly, if you ask about state management, you may try Mobx, Bloc, Redux, etc. There are many ways to do so.

Related

Nasa API FLUTTER WITH pub.dev

| I used to crate an App on flutter wiht the Nasa API but i only get strings back, but i wanna have pictures in my App how do i get picturers from this strings ?
I already tried this but this but i dont finde the point where i coan change the program to give me the coice to macke a foto out of this String
import 'package:flutter/material.dart';
import 'package:nasa_apis/nasa_apis.dart';
import 'package:tuple/tuple.dart';
class ApodScreen extends StatefulWidget {
const ApodScreen({super.key, required this.title});
final String title;
#override
State<ApodScreen> createState() => _ApodScreenState();
}
class _ApodScreenState extends State<ApodScreen> {
static const String _widgetNasaApod = "APOD";
String _selected = _widgetNasaApod;
String _apodTestDescription =
"The request will appear here.";
List<ApodItem> _apodTestResults = <ApodItem>[];
#override
void initState() {
super.initState();
init();
}
void init() async {
await Nasa.init(
logReceiver: (String msg, String name) {
},
apodSupport: true,
apodCacheSupport: true,
apodDefaultCacheExpiration: const Duration(seconds: 20));
}
#override
Widget build(BuildContext context) {
List<Widget> widgets = <Widget>[];
if (_selected == _widgetNasaApod) {
widgets.add(
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextButton(
onPressed: () async {
_apodTestResults.clear();
DateTime date = DateTime.now();
Tuple2<int, ApodItem?> result =
await NasaApod.requestByDate(date);
_apodTestDescription =
"requestByDate()\ndate[${date.toString()}]\nhttp response code: ${result.item1.toString()}";
if (result.item2 != null) {
_apodTestResults.add(result.item2!);
}
setState(() {});
},
child: const Text("Today"),
),
TextButton(
onPressed: () async {
_apodTestResults.clear();
Tuple2<int, List<ApodItem>?> result =
await NasaApod.requestByRandom(5);
_apodTestDescription =
"requestByRandom()\ncount[5]\nhttp response code: ${result.item1.toString()}";
if (result.item2 != null) {
_apodTestResults = result.item2!;
}
setState(() {});
},
child: const Text("Random"),
),
TextButton(
onPressed: () async {
_apodTestResults.clear();
DateTime startDate = DateTime(2022, 10, 1);
DateTime endDate = DateTime(2022, 10, 31);
Tuple2<int, List<MediaType>?> result =
(await NasaApod.requestByRange(startDate, endDate)) as Tuple2<int, List<MediaType>?>;
_apodTestDescription =
"requestByOctober()\n$startDate - $endDate\nhttp response code: ${result.item1.toString()}";
if (result.item2 != null) {
_apodTestResults = result.item2!.cast<ApodItem>();
}
setState(() {});
},
child: const Text("October"),
),
],
),
);
widgets.add(Text(_apodTestDescription));
for (ApodItem apodItem in _apodTestResults) {
widgets.add(
Padding(
padding: const EdgeInsets.all(15),
child: Text(
apodItem.toString(),
),
),
);
}
}
return Scaffold(
appBar: AppBar(
leading: IconButton(
onPressed: (){
Navigator.of(context).pop();
}, icon: const BackButtonIcon(),
),
title: Text(widget.title),
),
body: SingleChildScrollView(
child: Column(
children: widgets,
),
),
);
}
}
Looking at the NASA API code, you can see the class ApodItem definition (Here).
So in this part of your code :
for (ApodItem apodItem in _apodTestResults) {
widgets.add(
Padding(
padding: const EdgeInsets.all(15),
//Here you create a text widget
child: Text(
apodItem.toString(),
),
),
);
}
replace the Text widget by an Image.network using the getImageUrl method of ApodItem. Like this :
for (ApodItem apodItem in _apodTestResults) {
widgets.add(
Padding(
padding: const EdgeInsets.all(15),
//Here you get the url from you APOD item and create an image widget
child: Image.network(
apodItem.getImageUrl(),
),
),
);
}
getImageUrl will provide you with a url of the image (or of the thumbnail of the video if relevant. And Image.network will build the widget from the said url.

Display Data Dynamically from Firebase Firestore to Flutter App

I am trying to create a Music Streaming App, I completed the UI with dummy data but now I want to show the data dynamically through firebase. Here's the App UI to better understand. The images should come from firebase document which looks something like this into a ListView which accepts certain parameters so that I won't have to assign the data to every single widget manually.
I have tried couple of codes but none of them worked... Here's the code.
class Home extends StatefulWidget {
#override
State<Home> createState() => _HomeState();
}
class _HomeState extends State<Home> {
late QuickPickProvider quickPickProvider;
Future<void> _handleRefresh() async {
return await Future.delayed(Duration(milliseconds: 2200));
}
#override
void initState() {
QuickPickProvider quickPickProvider = Provider.of(context, listen: false);
quickPickProvider.fetchQuickPicks();
super.initState();
}
#override
Widget build(BuildContext context) {
quickPickProvider = Provider.of(context);
return MaterialApp...
Here's the code I tried
Padding(
padding: const EdgeInsets.only(left: 15),
child: const Text('Quick Picks',
style: TextStyle(fontSize: 22),),),
const SizedBox(height: 20),
SizedBox(
height: 212,
width: MediaQuery.of(context).size.width,
child: ListView(
scrolldirection= axis.horizontal,
children: quickPickProvider.getQuickPicksDataList.map(
(quickPicksData) {
return Padding(
padding: const EdgeInsets.only(left: 15.0),
child: SizedBox(
width: 170,
child: Column( mainAxisAlignment:MainAxisAlignment.spaceBetween,
children: [
ClipRRect( borderRadius: const BorderRadius.all(Radius.circular(10),),
child: Image.network(quickPicksData.songImage,),
),
Column(
children: [
Text(quickPicksData.songName,
style: const TextStyle(
fontSize: 18,
fontWeight: FontWeight.w600),),
Text(
quickPicksData.artistName,
style: const TextStyle(
fontWeight:FontWeight.w500,
fontFamily:'Josefin_Sans')
),
]
),
]
),)
);}
).toList(),),),
...
This is the ticker provider file I am using. (I am using the provider package)
class QuickPickProvider with ChangeNotifier {
List<QuickPickModel> quickPickList = [];
late QuickPickModel quickPickModel;
fetchQuickPicks() async {
List<QuickPickModel> newList = [];
QuerySnapshot value =
await FirebaseFirestore.instance.collection("QuickPicks").get();
value.docs.forEach((element) {
quickPickModel = QuickPickModel(
songImage: element.get("songImage"),
artistName: element.get("artistName"),
songDuration: '00',
songLyrics: '00',
songName: element.get("songName"));
newList.add(quickPickModel);
});
quickPickList = newList;
notifyListeners();
}
List<QuickPickModel> get getQuickPicksDataList {
return quickPickList;
}
}
Here's the error
Error
Please help me with this code or else suggest any other method which is easy and efficient. I don't want to assign image manually to
Try wrap MaterialApp() with ChangeNotifierProvider():
ChangeNotifierProvider<QuickPickProvider>(
create: (_) => QuickPickProvider(),
child: MaterialApp(
debugShowCheckedModeBanner: false,
title: '',
),
)
You can first upload an image to Firebase Storage using:
File imageFile = YOURIMAGEHERE
TaskSnapshot snapshot = await FirebaseStorage.instance.ref('uniquePathForImage').putFile(imageFile);
Then get the url of the image you just uploaded with:
String url = await snapshot.ref.getDownloadURL();
Optionally, you can get an existing file with a url with:
String url = await FirebaseStorage.instance.getFromUrl('yourUrl').getDownloadURL();
This url works like any image url so you can use it with the Image.network widget:
Image.network(url)

Everything matches but I still get "Bad state: field does not exist within the DocumentSnapshotPlatform"

So i'm pretty lost trying to get my app to fetch not only the desired text from firestore but also the image i placed there. I know the error "Bad state: field does not exist within the DocumentSnapshotPlatform" implies that either I'm missing field or there's something wrong with at least one of those fields. There's only four things I'm trying to fetch from firestore "imgUrl, title, desc, organizer" i have checked for spelling and order and i can't figure it out. I have also checked firestore to see if the order and spelling was correct and i dont see what's the issue. Please help, Thank you so much in advanced.
////////////////////////////// News Class Starts\\\\\\\\\\\\\\
import 'package:myfuji/screens/CrudMethods.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'CrudMethods.dart';
import 'add_blog.dart';
class News extends StatefulWidget {
#override
_NewsState createState() => _NewsState();
}
class _NewsState extends State<News> {
CrudMethods crudMethods = CrudMethods();
late QuerySnapshot blogSnapshot;
#override
void initState() {
crudMethods.getData().then((result) {
blogSnapshot = result;
setState(() {});
});
super.initState();
}
Widget blogsList() {
return ListView.builder(
padding: const EdgeInsets.only(top: 24),
itemCount: blogSnapshot.docs.length,
itemBuilder: (context, index) {
return BlogTile(
organizer: blogSnapshot.docs[index].get('Organizer'),
desc: blogSnapshot.docs[index].get('desc'),
imgUrl: blogSnapshot.docs[index].get('imgUrl'),
title: blogSnapshot.docs[index].get('title'),
);
},
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Events"),
),
body: Container(
child: blogSnapshot != null
? blogsList()
: const Center(
child: CircularProgressIndicator(),
)),
floatingActionButton: FloatingActionButton(
child: const Icon(Icons.add),
onPressed: () {
Navigator.push(
context, MaterialPageRoute(builder: (context) => AddBlog()));
},
),
);
}
}
class BlogTile extends StatelessWidget {
final String imgUrl, title, desc, organizer;
const BlogTile(
{required this.organizer,
required this.desc,
required this.imgUrl,
required this.title});
#override
Widget build(BuildContext context) {
return Container(
margin: const EdgeInsets.only(bottom: 24, right: 16, left: 16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
child: ClipRRect(
borderRadius: const BorderRadius.all(Radius.circular(8)),
child: Image.network(
imgUrl,
width: MediaQuery.of(context).size.width,
fit: BoxFit.cover,
height: 200,
),
),
),
const SizedBox(height: 16),
Text(
title,
style: const TextStyle(fontSize: 17),
),
const SizedBox(height: 2),
Text(
'$desc - By $organizer',
style: const TextStyle(fontSize: 14),
)
],
),
);
}
}
///////////////////////////////////////////// class AddBlog begins here \\\\\\\\\\\
import 'dart:io';
import 'package:myfuji/screens/CrudMethods.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:random_string/random_string.dart';
class AddBlog extends StatefulWidget {
#override
_AddBlogState createState() => _AddBlogState();
}
class _AddBlogState extends State<AddBlog> {
//
late File selectedImage;
final picker = ImagePicker();
bool isLoading = false;
CrudMethods crudMethods = new CrudMethods();
Future getImage() async {
final pickedFile = await picker.getImage(source: ImageSource.gallery);
setState(() {
if (pickedFile != null) {
selectedImage = File(pickedFile.path);
} else {
print('No image selected.');
}
});
}
Future<void> uploadBlog() async {
if (selectedImage != null) {
// upload the image
setState(() {
isLoading = true;
});
Reference firebaseStorageRef = FirebaseStorage.instance
.ref()
.child("events/")
.child("${randomAlphaNumeric(9)}.jpg");
final UploadTask task = firebaseStorageRef.putFile(selectedImage);
var imageUrl;
await task.whenComplete(() async {
try {
imageUrl = await firebaseStorageRef.getDownloadURL();
} catch (onError) {
print("Error");
}
print(imageUrl);
});
// print(downloadUrl);
Map<String, dynamic> blogData = {
"imgUrl": imageUrl,
"Organizer": authorTextEditingController.text,
"title": titleTextEditingController.text,
"desc": descTextEditingController.text
};
crudMethods.addData(blogData).then((value) {
setState(() {
isLoading = false;
});
Navigator.pop(context);
});
// upload the blog info
}
}
//
TextEditingController titleTextEditingController =
new TextEditingController();
TextEditingController descTextEditingController = new TextEditingController();
TextEditingController authorTextEditingController =
new TextEditingController();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Create Blog"),
actions: [
GestureDetector(
onTap: () {
uploadBlog();
},
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 16),
child: Icon(Icons.file_upload)),
)
],
),
body: isLoading
? Container(
child: Center(
child: CircularProgressIndicator(),
))
: SingleChildScrollView(
child: Container(
margin: EdgeInsets.symmetric(horizontal: 16),
child: Column(
children: [
GestureDetector(
onTap: () {
getImage();
},
child: selectedImage != null
? Container(
height: 150,
margin: EdgeInsets.symmetric(vertical: 24),
width: MediaQuery.of(context).size.width,
child: ClipRRect(
borderRadius:
BorderRadius.all(Radius.circular(8)),
child: Image.file(
selectedImage,
fit: BoxFit.cover,
),
),
)
: Container(
height: 150,
decoration: BoxDecoration(
color: Colors.grey,
borderRadius:
BorderRadius.all(Radius.circular(8))),
margin: EdgeInsets.symmetric(vertical: 24),
width: MediaQuery.of(context).size.width,
child: Icon(
Icons.camera_alt,
color: Colors.white,
),
),
),
TextField(
controller: titleTextEditingController,
decoration: InputDecoration(hintText: "enter title"),
),
TextField(
controller: descTextEditingController,
decoration: InputDecoration(hintText: "enter desc"),
),
TextField(
controller: authorTextEditingController,
decoration:
InputDecoration(hintText: "enter author name"),
),
],
)),
),
);
}
}
///////////////////////////////////////////// class CrudMethods begins here \\\\\\\\\\\
import 'package:cloud_firestore/cloud_firestore.dart';
class CrudMethods {
Future<void> addData(blogData) async {
print(blogData);
FirebaseFirestore.instance
.collection("events/")
.add(blogData)
.then((value) => print(value))
.catchError((e) {
print(e);
});
}
getData() async {
return await FirebaseFirestore.instance.collection("events/").get();
}
}
/////////////////////////////////////////////firestore\\\\\\\\\\\\\
This maybe related to having “/“ after collection name here:
.collection("events/")
Instead try this:
.collection("events")
Also it may be best to change child to collection here:
Reference firebaseStorageRef = FirebaseStorage.instance
.ref()
.child("events/")
Try to see if you get data back by running this:
itemCount: blogSnapshot.docs.length,
itemBuilder: (context, index) {
QuerySnapshot snap = blogSnapshot.data; // Snapshot
List<DocumentSnapshot> items = snap.documents; // List of Documents
DocumentSnapshot item = items[index]; Specific Document
return BlogTile(
organizer: item.data['Organizer'],
desc: item.data['desc'],
imgUrl: item.data['imgUrl'],
title: item.data['title'],
);
},
I think you need to utilize a QueryDocumentSnapshot to access the data in the document.

How can i remove html tags from a variable which i am calling from rest api and display it?

So basically I am calling get request on a rest API in flutter. I can display the data perfectly in listview but while doing so this particular data have lots of html tags in it. How can I possible remove the html tags after I have got the data in a variable?. The data has tag in between two strings and there are other html tags as well. Here is my code
import 'package:flutter/material.dart';
import 'package:flutter_on_field/API/api.dart';
import 'package:flutter_on_field/Add/AddAttendance.dart';
import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:http/http.dart' as http;
class Attendance extends StatefulWidget {
#override
_AttendanceState createState() => _AttendanceState();
}
class _AttendanceState extends State<Attendance> {
List users = [];
bool isLoading = false;
#override
void initState() {
// TODO: implement initState
super.initState();
this.fetchUser();
}
fetchUser() async {
setState(() {
isLoading = true;
});
var uri = Uri.parse('https://hirana.in/cdnhira/Serv_onfield_v1/attendance_list?session=');
var url = uri.replace(queryParameters: <String, String>{'session': session});
print(url);
var response = await http.get(url);
// print(response.body);
if(response.statusCode == 200){
var items = json.decode(response.body)['data'];
setState(() {
users = items;
isLoading = false;
});
}else{
users = [];
isLoading = false;
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: new AppBar(
title:Text("Attendance list",
textAlign: TextAlign.center,
),
backgroundColor: Colors.blue,
),
body:Stack(
children: [
Align(
alignment: Alignment.bottomCenter,
child: Container(
color: Colors.green,
width: 2000.0,
child: RaisedButton(onPressed: () {
Navigator.push(context,new MaterialPageRoute(
builder: (BuildContext context)=>AddAttendance())
);
},
color: Colors.green,
child: Text('Add Attendance',style: TextStyle(color: Colors.black),)),
),
),
SizedBox(height: 10),
Container(
height: 720,
child:getBody(),
),
]
),
);
}
Widget getBody(){
if(users.contains(null) || users.length < 0 || isLoading){
return Center(child: CircularProgressIndicator(valueColor: new AlwaysStoppedAnimation<Color>(Colors.white),));
}
return ListView.builder(
itemCount: users.length,
itemBuilder: (context,index){
return display(users[index]);
});
}
Widget display(item){
var date = item["attend_date"];
var inTime = item['intime'];
var outTime = item['outtime'];
print(date);
print("hi");
return Card(
elevation: 1.5,
child: ListTile(
title: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Column(
children: [
Text("Date(Name)",style: TextStyle(fontSize: 17, fontWeight:FontWeight.bold)),
Text(date),
],
),
Column(
children: [
Text("In Time", style: TextStyle(fontSize: 17, fontWeight:FontWeight.bold)),
Text(inTime),
],
),
Column(
children: [
Text("Out Time", style: TextStyle(fontSize: 17, fontWeight:FontWeight.bold)),
Text(outTime),
],
),
],
),
),
);
}
}
I am not able to add it to the code without the errors. Can you edit the code or write how to call my variable in the function.
You can use it like this:
import ‘package:html/parser.dart’;
// Some of the code.
String parseHtmlString(String htmlString) {
var document = parse(htmlString);
String parsedString = parse(document.body.text).documentElement.text;
return parsedString;
}
// Some of the code again.
if(response.statusCode == 200){
var items = json.decode(response.body)['data'];
items = parseHtmlString(items);
setState(() {
users = items;
isLoading = false;
});
}else{
users = [];
isLoading = false;
}
You can use the HTML package (https://pub.dev/packages/html), which already includes a parser:
import 'package:html/parser.dart' show parse;
import 'package:html/dom.dart';
main() {
var document = parse(
'<body>Hello world! <a href="www.html5rocks.com">HTML5 rocks!');
print(document.outerHtml);
}

i have problem with async function and updated information on screen

When the user comes on this page, the function async get_ticket() need to be called, it returns a ticket id and the revenue user wins (it is scratch game). The first problem with this code is if i want display the value of "gain" and "id_ticket" because at the screen it says "null". When i have finish to scratch the ticket there is a setstate made and the value are updated from null to their real value.
Why this 2 values are not updated ??? The widget seems to be displayed before the function so widget can't display real values (which is updated by the async function). How i can resolve that ? For my game the better solution would be to called the async function and if player can have a ticket we display the ticket and if not we display a message for that "You can't scratch again today" for example.
import 'package:flutter/material.dart';
import 'package:flutter_app/menu_member.dart';
import 'package:scratcher/scratcher.dart';
import 'package:flutter_app/globals.dart' as globals;
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'dart:async';
import 'package:flutter_app/liste_grattage.dart';
class Affiche_Ticket_Grattage extends StatefulWidget {
#override
_Affiche_Ticket_Grattage_State createState() {
return _Affiche_Ticket_Grattage_State();
}
}
// Create a corresponding State class.
// This class holds data related to the form.
class _Affiche_Ticket_Grattage_State extends State<Affiche_Ticket_Grattage> {
#override
void initState() {
Get_Ticket();
super.initState();
}
bool vis=false;
var gain;
var id_ticket;
Future Get_Ticket() async {
// SERVER LOGIN API URL
var url = 'https://www.easytrafic.fr/game_app/get_ticket.php';
// Store all data with Param Name.
var data = {'id_membre':globals.id_membre};
var ticket_encode=jsonEncode(data);
// Starting Web API Call.
var response = await http.post(url, body: ticket_encode,headers: {'content-type': 'application/json','accept': 'application/json','authorization': globals.token});
// Getting Server response into variable.
Map <String,dynamic> map = json.decode(response.body);
gain=map["gain"];
print(gain.toString());
id_ticket=map["id"];
print(id_ticket.toString());
}
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('GRATTAGE')),
drawer: new DrawerOnly(),
body:
Center(
child:
Column(
children: <Widget>[
Container(
width:400,
height:30,
margin: const EdgeInsets.only(top: 10.0),
child : new Text("Grattez votre ticket N °"+id_ticket.toString(),textAlign: TextAlign.center,style: TextStyle(fontSize: 30.0),),
),
Container(
padding: const EdgeInsets.all(30.0),
child:
Scratcher(
accuracy: ScratchAccuracy.medium,
brushSize: 35,
color: Colors.lightBlueAccent,
threshold: 80,
onThreshold: () {
setState(() {
vis = true;
});
print ("Ticket gratté !!!");
},
child:
Container(
width: 300,
height:300,
color: Colors.black,
alignment: Alignment.center,
child:
Text(gain.toString()+" €",style: TextStyle(fontWeight: FontWeight.bold, fontSize: 50, color: Colors.red),
)
)
)
),
Visibility(
visible: vis,
child: Container(
width:300,
height:45,
margin: const EdgeInsets.only(top: 20.0),
child:
RaisedButton(
color: Colors.green,
textColor: Colors.white,
padding: EdgeInsets.fromLTRB(9, 9, 9, 9),
child: Text('VALIDER VOTRE TICKET'),
onPressed: () {
Valide_Ticket();
},
),
),
),
]
)
)
),
);
}
Future Valide_Ticket() async{
// SERVER LOGIN API URL
var url2 = 'https://www.easytrafic.fr/game_app/valide_ticket.php';
// Store all data with Param Name.
var data2 = {'id_membre':globals.id_membre,'id_ticket':id_ticket,'gain':gain};
var ticket_info=jsonEncode(data2);
// Starting Web API Call.
var response = await http.post(url2, body: ticket_info,headers: {'content-type': 'application/json','accept': 'application/json','authorization': globals.token});
// Getting Server response into variable.
Map <String,dynamic> map2 = json.decode(response.body);
if(map2["status"] == 1)
{
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: new Text(map2["message"]),
actions: <Widget>[
FlatButton(
child: new Text("OK"),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Affiche_Liste_Grattage()),
);
},
),
],
);
},
);
}
}
}
You can use FutureBuilder for this issue. It wait for the future function to perform its task and then renders your page.
Another way would be to show an animation while the data is fetched. then use setState() to hide the animation and show the Widgets(based on the condition)