When I am calling getUserById() function everything works fine and the growable string works fine but when I use the same variable inside a text widget then it shows RangeError.
The problem is occuring only when I try to use a growable list of string named as dataAsString inside the build.
Here is the Code with Error. Go to the scaffold where I have commented the line of error
import 'package:Healthwise/helpers/user.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import '../helpers/backEnd.dart';
import '../helpers/frontEnd.dart';
class ResultPage extends StatefulWidget {
const ResultPage({Key? key}) : super(key: key);
#override
State<ResultPage> createState() => _ResultPageState();
}
class _ResultPageState extends State<ResultPage> {
// String docId = '';
String objectToString = '';
String e = '';
//This variable is creating the problem...
// I have tried this by using a final instead of var, but nothing worked.
var dataAsString = <String>[];
#override
void initState() {
super.initState();
// getUsers();
getUserById();
}
getUserById() {
final String id = itemName;
userRef.doc(id).get().then((DocumentSnapshot doc) {
// final x = doc.data();
// docId= doc.id;
objectToString = doc.data().toString();
String temp = '';
// print(doc.data());
// print(doc.id);
int i = 1;
// int j = 0;
bool end = false;
//We are just parsing the object into string.
while (objectToString[i] != '}') {
if (objectToString[i - 1] == ' ' && objectToString[i - 2] == ':') {
while (objectToString[i] != ',' && end != true) {
// print(z[i]);
temp += objectToString[i];
if (objectToString[i + 1] != '}') {
i++;
} else {
end = true;
}
}
//Here I add all the strings to list...
// This line works fine.
dataAsString.add(temp);
temp = '';
// j++;
print("The code below this line prints everything perfectly");
print(dataAsString.length);
print(dataAsString[0]);
}
i++;
}
// print(dataAsString[0]);
// print(dataAsString[1]);
// print("+++++++++++");
// print(dataAsString[2]);
// for (var k in dataAsString) {
// print(k);
// }
// print(dataAsString);
// setState(() {});
});
}
// getUsers() {
// userRef.get().then((QuerySnapshot snapshot) {
// snapshot.docs.forEach((DocumentSnapshot doc) {
// print(doc.data());
// print(doc.id);
// print(doc.exists);
// });
// });
// }
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(backgroundColor: primary_color, title: Text("Apple")),
body: Container(
child: Column(children: [
ListTile(
//The problem arises here and the app do not crash if I run the same code with just a //string in place of dataAsString[0]
title: Text(dataAsString[0]),
),
ListTile(
title: Text(dataAsString[1]),
),
ListTile(
title: Text(dataAsString[2]),
),
]),
),
);
}
}
You cant have data on dataAsString because you are using future(.then) on fetching data. You can do value check like
Text( dataAsString.isNotEmpty? dataAsString[0]: "0 is empty"),
Text( dataAsString.length>2? dataAsString[1]: "1 index is empty"),
Text( dataAsString.length>3? dataAsString[2]: "3rd item is empty"),
It's cause your dataAsString ins't ready on first Flutter rendered frame. So, you need to wait for the getUserById finish to access the dataAsString values.
You can use a builder to check if the data is ready in a readable way.
Builder(
builder: (context) {
if (dataAsString.length >= 2) {
return Column(children: [
ListTile(
title: Text(dataAsString[0]),
),
ListTile(
title: Text(dataAsString[1]),
),
ListTile(
title: Text(dataAsString[2]),
),
]);
} else {
return const Center(
child: CircularProgressIndicator(),
);
}
},
),
Warning: it'll work cause you're calling setState when you finish the async task.
I am trying for the past two days to Get user data from binance Api with the Binance test net key using package https://pub.dev/packages/binance_spot/example
I tried every way possible I learned as I am a beginner I am not able to get the user data from the user account
I also changed the links that work for the testnet finance API version
here is the example code snippet
import 'dart:async';
import 'package:binance_spot/binance_spot.dart';
import 'package:flutter/material.dart' hide Interval;
class BinanceScreen extends StatefulWidget {
const BinanceScreen({Key? key}) : super(key: key);
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<BinanceScreen> {
BinanceSpot binanceSpot = BinanceSpot(
key: "3HKUUgtwu8WFWh4q31C5bh1veQqMEkEbF07hpMrq8xnwYsWDnj0ZWgYQkvC3gnE0",
secret: "KWwvWOi4nu8s0Qsi87iJ523cfp9Jcl8mFwt2hZHptMyahhGsxnmvdURIxVa9zA74",
);
double lastClosePrice = 0;
String tradablePairs = "";
String lastEventData = "";
WsAccountUpdate? balance;
late StreamSubscription<dynamic> klineStreamSub;
late StreamSubscription<dynamic> userdataStreamSub;
#override
void initState() {
startKlineStream();
startUserdataStream();
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Binance API tester"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text("Current BTC price : $lastEventData"),
// Text("Last userdataStream event : ${balance}"),
TextButton(
onPressed: getTradablePairs,
child: const Text("GET PAIRS"),
),
Expanded(
flex: 1,
child: SelectableText(
tradablePairs,
maxLines: 200,
minLines: 1,
),
),
],
),
),
);
}
void startKlineStream() {
var stream = binanceSpot.klineStream(
symbol: "BTCUSDT",
interval: Interval.INTERVAL_5m,
);
klineStreamSub = stream.listen(handleNewKline);
}
void handleNewKline(WsKlineEvent event) {
setState(() {
lastClosePrice = event.kline.close;
});
}
void startUserdataStream() async {
var response = await binanceSpot.createListenKey();
if (response.isRight) {
var stream = binanceSpot.userDataStream(listenKey: response.right);
userdataStreamSub = stream.listen(handleUserdataEvent);
} else {
lastEventData = response.left;
}
}
void handleUserdataEvent(dynamic event) {
if (event is WsAccountUpdate) {
lastEventData =
"Account update event : ${event.balances.length} balances updated";
} else if (event is WsBalanceUpdate) {
lastEventData = "Balance update event : ${event.asset} balance updated";
} else if (event is WsExecutionReport) {
lastEventData =
"Execution report event : status is ${event.orderStatus.toStr()}";
} else if (event is WsListOrderStatus) {
lastEventData =
"ListOrder update event : status is ${event.listOrderStatus}";
} else {
lastEventData = "Unknown event type : ${event.toString()}";
}
}
void getTradablePairs() async {
var response = await binanceSpot.exchangeInfo();
if (response.isLeft) {
tradablePairs = response.left;
} else {
var listSymbol = response.right.symbols.map((e) => e.symbol).toList();
tradablePairs = "";
for (var s in listSymbol) {
tradablePairs += "$s ";
}
}
}
#override
void dispose() {
klineStreamSub.cancel();
userdataStreamSub.cancel();
super.dispose();
}
}
and here is the class code snippet which I want to acess
class WsOcoOrder {
String symbol;
int orderId;
String clientOrderId;
WsOcoOrder.fromMap(Map m)
: symbol = m['s'],
orderId = m['i'],
clientOrderId = m['c'];
}
What is the Possible way to access this class and its data in the above-given code snippet
Please refer me to the solution or a Link from where I can learn and implement by myself
Here I have a StatefulWidget in which I want to get a random pet each time from a random url. Also, I have a condition for the random pet, if the condition is true, the pet will be shown, otherwise the random url and random pet should be selected again. I attached my code below, and the problem is the url only changes when the condition is false, but I want it to be randomly selected each time.
Putting the API.get_pets(init_random_url); in the future parameter of the FutureBuilder will solve the random selection but if the condition is false the URL and the pet would change two or three times, after searching about it and reading FutureBuilder documentation I put it in the initState and requestAgain and build, but I recognized the selectedURL in the build function does not work and the widget is stucked in the same URL until the condition gets false value.
import 'dart:developer';
import 'package:double_back_to_close/toast.dart';
import 'package:flutter/material.dart';
import 'package:pet_store/widgets/guess_game_random_card.dart';
import 'webservice/API.dart';
import 'main.dart';
import 'dart:math';
import 'utils/utils.dart';
Random random = new Random();
class Guess_Game extends StatefulWidget {
const Guess_Game({Key? key}) : super(key: key);
#override
State<Guess_Game> createState() => _Guess_GameState();
}
class _Guess_GameState extends State<Guess_Game> {
void initState() {
super.initState();
init_random_url = randomly_select_URL();
GuessGameFuture = API.get_pets(init_random_url);
}
void requestAgain() {
setState(() {
init_random_url = randomly_select_URL();
GuessGameFuture = API.get_pets(init_random_url);
});
}
#override
Widget build(BuildContext context) {
init_random_url = randomly_select_URL();
return Scaffold(
body: Center(
child:
FutureBuilder<List<dynamic>>(
future: GuessGameFuture,
builder: (context, snapshot) {
if (snapshot.hasData) {
List<dynamic>? pet_data = snapshot.data;
var number_of_parameters = snapshot.data!.length;
var random_pet = random.nextInt(number_of_parameters);
var category = pet_data![random_pet].category.toString();
var photoURL = pet_data![random_pet].photoUrls;
// Here is the condition that ensure pet category is in the list and has an image
if (checkCategoryInList(category, items) &&
photoURL.length != 0) {
return Random_Card(
pet_data: pet_data,
random_pet: random_pet,
dropdownvalue: dropdownvalue);
} else {
if (photoURL.length == 0) {
print(" NO PHOTO SUBMITTED FOR THIS PET");
} else {
print(category + "NOT IN CATEGORY");
}
WidgetsBinding.instance.addPostFrameCallback((_) {
requestAgain();
});
}
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
return const CircularProgressIndicator();
},
)
else
const Text(
"Please select your guess",
style: TextStyle(fontSize: 17, color: Colors.indigo),
),
),
),
}
}
Add this line to build
GuessGameFuture = API.get_pets(randomly_select_URL());
and Change requestAgain function to this:
void requestAgain() {
setState(() {
GuessGameFuture = API.get_pets(randomly_select_URL());
});
}
Also you can use FutureProvider and riverpod library.
Hope it helps
I have two api's from which I get data, I wanna check if any of the desired field match with each other data coming but it don't seem to work.
I have two api's from which I get data, I wanna check if any of the desired field match with each other data coming but it don't seem to work.
I have two api's from which I get data, I wanna check if any of the desired field match with each other data coming but it don't seem to work.
class Home extends StatefulWidget {
const Home({ Key? key }) : super(key: key);
#override
State<Home> createState() => _HomeState();
}
class _HomeState extends State<Home> {
List compaints = [];
List found = [];
List match = [];
var u_imei;
var d_imei;
Future fetch() async {
http.Response response_one;
http.Response response_two;
response_one = await http.get(Uri.parse("https://script.google.com/macros/s/AKfycbxi9kN6NWvoFjkQZE1OVJDPpWmQeYk0V5hNfRKqXS19wjz86SYq_FoQ51fjNQY22bN4/exec"));
response_two = await http.get(Uri.parse("https://script.google.com/macros/s/AKfycbx20kfm1g4Hno9DzO1uccmLgmuIQBkXQcA9tnhcup873TsEMEy9ejszCluhf4FzW-YJqQ/exec"));
if(response_one == 200 && response_two == 200){
if(mounted){
setState(() {
compaints = jsonDecode(response_one.body);
found = jsonDecode(response_two.body);
u_imei = compaints[2];
d_imei = found[1];
if(d_imei == u_imei) {
if(mounted){
print("working");
setState(() {
match.add(d_imei);
});
}
}
});
}
}
}
#override
Widget build(BuildContext context) {
// fetchu();
// fetchd();
// check();
fetch();
return Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text(compaints.length.toString()),
SizedBox(height: 20,),
Text(found.length.toString()),
],
),
);
}
}
There are several issues:
fetch is called in build, which causes rebuild loop. First step to move it to initState.
Response is compared to 200 (response_one == 200). There is property statusCode.
Parsing imei's is not correct. Responses:
[{time: 2022-07-03T16:07:15.491Z, name: Asif, imei: 1234, number: 9014580667}]
[{time: 2022-07-05T08:12:31.029Z, imei: 1234}]
So should be something like this:
u_imei = compaints[0]['imei'];
d_imei = found[0]['imei'];
Calling the fetch method inside the build will loop as the fetch method calls the setState(). Use initState() to call on the load or on refresh indicator while the user pulls to refresh or any other method.
class Home extends StatefulWidget {
const Home({ Key? key }) : super(key: key);
#override
State<Home> createState() => _HomeState();
}
class _HomeState extends State<Home> {
List compaints = [];
List found = [];
List match = [];
var u_imei;
var d_imei;
#override
void initState() {
super.initState();
fetch();
}
#override
void dispose() {
super.dispose();
}
Future fetch() async {
http.Response response_one;
http.Response response_two;
response_one = await http.get(Uri.parse("https://script.google.com/macros/s/AKfycbxi9kN6NWvoFjkQZE1OVJDPpWmQeYk0V5hNfRKqXS19wjz86SYq_FoQ51fjNQY22bN4/exec"));
response_two = await http.get(Uri.parse("https://script.google.com/macros/s/AKfycbxEDXZAmieRWk-8kOX-07ta8Q4TIa9Lf_NAiArEWhaU4jXO8d_DM9Jwuc0DRIwmUpPh/exec"));
if(response_one.statusCode == 200 && response_two.statusCode == 200){
if(mounted){
setState(() {
compaints = jsonDecode(response_one.body);
found = jsonDecode(response_two.body);
u_imei = compaints[2];
d_imei = found[1];
if(d_imei == u_imei) {
if(mounted){
print("working");
setState(() {
match.add(d_imei);
});
}
}
});
}
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text(compaints.length.toString()),
SizedBox(height: 20,),
Text(found.length.toString()),
],
),
);
}
}
I am trying to send data from Flutter to Node-RED (to Raspberry Pi) over HTTP (not HTTPS). The URL http://bierbrauserver.ddns.net is from NO-IP (DDNS). The transfer to a test server from a Youtube Tutorial works fine. But when I change the URL from "https://reqres.in/api/users" to "http://bierbrauserver.ddns.net:1880" I get no input in the debug window of Node-RED. I tried in the AndroidManifest.xml to add the entry
so that http is allowed, but that didn't solve the problem either.
Furthermore I checked the port forwarding in the WLAN router configuration of the network where the Raspberry Pi is located. Here a port forwarding of HTTP and 1880 (Node-RED) was configured. The connection of the IP addresses should be ok, because I can access a database from an external port, which is also located on the Raspberry Pi. Can it be that only httpS post requests are possible ?
Future<UserModel> createUser(String name, String jobTitle)async{
const String Url = "https://reqres.in/api/users";
// const String Url = "https://bierbrauserver.ddns.net:1880";
final response = await http.post(Uri.parse(Url),body:
{
"name": name,
"job": jobTitle
});
if (response.statusCode == 201) {
final String responseString = response.body;
return userModelFromJson(responseString);
}
else
{
print(response.statusCode);
return UserModel(name:'Fail',job: 'Fail', id: 'Fail', createdAt: DateTime.now());
}
}
Thank you for your help.
The problem is solved. The program code has already been modified because I forgot to answer the question immediately when the problem was fixed. The problem was hidden in the Node-RED program. The wrong Node was selected in Node-RED.
The URL was extended with "/test", which is reused in Node-RED in the "http in" node. Now everything works fine.
For your information: "Zutat_1", "Zutat_2", "Zutat_3" and "Zutat_4" are global variables in this program and therefore do not have to be passed to the "createRezept" function.
Additionally, it should be mentioned that some elements in the code that do not belong to the English language are executed in the German language.
Future<RezeptModel> createRezept()async{
const String Url = "http://bierbrauserver.ddns.net:1880/test";
final response = await http.post(Uri.parse(Url),body:
{
"zutat1": Zutat_1.toStringAsFixed(2),
"zutat2": Zutat_2.toStringAsFixed(2),
"zutat3": Zutat_3.toStringAsFixed(2),
"zutat4": Zutat_4.toStringAsFixed(2),
"createdAt" : DateTime.now().toIso8601String()
});
if (response.statusCode == 201) {
final String responseString = response.body;
return rezeptModelFromJson(responseString);
}
else
{
print(response.statusCode);
return RezeptModel(zutat1:"Fehler",zutat2: "Fehler", zutat3: "Fehler", zutat4: "Fehler",createdAt: DateTime.now());
}
}
Here is the code which is used for parsing.(This is in a separate file, which in my case is named "Rezept_model.dart" )
import 'dart:convert';
RezeptModel rezeptModelFromJson(String str) => RezeptModel.fromJson(json.decode(str));
String rezeptModelToJson(RezeptModel data) => json.encode(data.toJson());
class RezeptModel {
RezeptModel({
required this.zutat1,
required this.zutat2,
required this.zutat3,
required this.zutat4,
required this.createdAt,
});
String zutat1;
String zutat2;
String zutat3;
String zutat4;
DateTime createdAt;
factory RezeptModel.fromJson(Map<String, dynamic> json) => RezeptModel(
zutat1: json["zutat1"],
zutat2: json["zutat2"],
zutat3: json["zutat3"],
zutat4: json["zutat4"],
createdAt: DateTime.parse(json["createdAt"]),
);
Map<String, dynamic> toJson() => {
"zutat1": zutat1,
"zutat2": zutat2,
"zutat3": zutat3,
"zutat4": zutat4,
"createdAt": createdAt.toIso8601String(),
};
}
For completeness here is the whole code of the main program.
import 'dart:convert';
import 'dart:math';
import 'package:bier_brau_project/variables.dart';
import 'package:bier_brau_project/rezept_model.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Bier Brau App',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'HTTP Test Site'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
#override
State<MyHomePage> createState() => _MyHomePageState();
}
Future<RezeptModel> createRezept()async{
const String Url = "http://bierbrauserver.ddns.net:1880/test";
final response = await http.post(Uri.parse(Url),body:
{
"zutat1": Zutat_1.toStringAsFixed(2),
"zutat2": Zutat_2.toStringAsFixed(2),
"zutat3": Zutat_3.toStringAsFixed(2),
"zutat4": Zutat_4.toStringAsFixed(2),
"createdAt" : DateTime.now().toIso8601String()
});
if (response.statusCode == 201) {
final String responseString = response.body;
return rezeptModelFromJson(responseString);
}
else
{
print(response.statusCode);
return RezeptModel(zutat1:"Fehler",zutat2: "Fehler", zutat3: "Fehler", zutat4: "Fehler",createdAt: DateTime.now());
}
}
class _MyHomePageState extends State<MyHomePage> {
RezeptModel _rezept = RezeptModel(zutat1: "init", zutat2: "init", zutat3: "init",zutat4: "init", createdAt: DateTime.now());
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
MySlider(Min:22.0,Max:40.0,Devisions: 100,unit:'l',title: 'Wasser',ID:1),
MySlider(Min:4.0,Max:20.0,Devisions: 100,unit:'kg',title:'Malz',ID: 2,),
MySlider(Min:60.0,Max:300.0,Devisions: 100,unit:'g',title:'Hopfen',ID: 3,),
MySlider(Min:12.0,Max:60.0,Devisions: 100,unit:'g',title:'Hefe',ID:4),
const SizedBox(height:32.0,),
Text( "Wasser "+ _rezept.zutat1 +"\n"
+"Malz "+_rezept.zutat2 +"\n"
+"Mopfen "+ _rezept.zutat3 +"\n"
+"Hefe "+ _rezept.zutat4 +"\n"
+"ist Erfolgreich übertragen worden "
+ _rezept.createdAt.toIso8601String())
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: ()async{
final RezeptModel rezept= await createRezept();
setState(() {
_rezept=rezept;
});
},
child: const Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
/// This is the stateful widget that the main application instantiates.
class MySlider extends StatefulWidget {
MySlider({Key? key,required this.Min, required this.Max,required this.Devisions,required this.unit,required this.title,required this.ID}): super(key: key);
final double Min;
final double Max;
final String unit;
final String title;
final int Devisions;
final int ID;
bool ValueChanged= false;
#override
State<MySlider> createState() => _MySliderState();
}
/// This is the private State class that goes with MyStatefulWidget.
class _MySliderState extends State<MySlider> {
double _currentSliderValue =0;
#override
Widget build(BuildContext context) {
return Padding (
padding: const EdgeInsetsDirectional.fromSTEB(32.0, 32.0, 32.0, 16.0),
child: Column(children: <Widget> [
Text(
widget.title,
style: const TextStyle(
color: Colors.black54,
height: 1,
fontSize: 18
),
),
Slider(
value: widget.ValueChanged== false ? ((widget.Max-widget.Min)/2)+widget.Min : _currentSliderValue,
min: widget.Min,
max: widget.Max,
divisions: widget.Devisions,
label: _currentSliderValue.toStringAsFixed(2),
onChanged: (double value) {
setState(() {
_currentSliderValue = value;
first_call = false;
widget.ValueChanged =true;
switch(widget.ID) {
case 1: {Zutat_1 =double.parse(value.toStringAsFixed(2));}
break;
case 2: {Zutat_2 =double.parse(value.toStringAsFixed(2));}
break;
case 3: {Zutat_3 =double.parse(value.toStringAsFixed(2));}
break;
case 4: {Zutat_4 =double.parse(value.toStringAsFixed(2));}
break;
default: {}
break;
}
});
},
),
Text(
(widget.ValueChanged== false ?((widget.Max-widget.Min)/2)+widget.Min : _currentSliderValue.toStringAsFixed(2)).toString() + ' '+widget.unit,
),
])
);
}
}
Many thanks to all those who have dealt with this problem.
Here are still two images deposited around the connections to clarify.
Node-RED program to receive from http post
Android Studio emulator with the test application
Change your code to this:
final response = await http.post(Uri.parse(Url),body:
{
"name": name,
"job": jobTitle
});
if (response.statusCode == 201) {
final responseString = jsonDecode(_res.body)
return userModelFromJson(responseString);
}
else
{
print(response.statusCode);
return UserModel(name:'Fail',job: 'Fail', id: 'Fail', createdAt: DateTime.now());
}
}