Flutter error occurred when adding some JSON files from "Random User" - json

I tried to excute this code in my android mobile. it has not any error. when app start show "waiting" massage, after that body only displayed "true".
**body: FutureBuilder(
future: getUser(),
builder: (BuildContext context,AsyncSnapshot snapshot) {
if(snapshot.connectionState == ConnectionState.waiting){
return const Center(
**child: Text('waiting')**,
);
}else{
if(snapshot.hasError){
return Text(snapshot.hasError.toString());
}else{
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (BuildContext context,int index){
return ListTile(
leading: CircleAvatar(
backgroundImage: NetworkImage(snapshot.data[index].avatar),
),
title: Text(snapshot.data[index].name),
subtitle: Text(snapshot.data[index].email),
onTap: (){},**
i want to show user information getting from the 'https://randomuser.me/api/?results=20' this json file.

There is an error in the code. So that's why it is "true".
if you hover over " hasError " you will see the data type is boolean. so when you wrote
if(snapshot.hasError){
return Text(snapshot.hasError.toString());
by " tostring " you just presnted the error in string form. so.

Related

How to convert MQTT Message to JSON format in Flutter

I already connect and get data from MQTT broker using snapshot method. However, I want to convert the MQTT message to JSON format cause I want to do some condition code to certain data.
My problem is when I stream data from the MQTT broker, my data only came out for the last data for that index. That index consists three different data, but since the index hold 3 data at the same time, only the last data of the index that displayed. This is my current code. How can I do that?
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Flutter MQTT"),
),
body: FutureBuilder(
future: mqttSubscribe(topic: "/sensor_simulator/data"),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.hasError) {
return Center(
child: Text("Error: ${snapshot.error}"),
);
}
// if succeed to connect
if (snapshot.connectionState == ConnectionState.done) {
return StreamBuilder(
stream: snapshot.data,
builder: (BuildContext context, AsyncSnapshot snapshot) {
// if have error--> display
if (snapshot.hasError) {
return Center(
child: Text("Error: ${snapshot.error}"),
);
}
// if data detected--> display
if (snapshot.hasData) {
try {
final List<MqttReceivedMessage> receiveMessage =
snapshot.data;
final recMess =
receiveMessage[0].payload as MqttPublishMessage;
String payload = MqttPublishPayload.bytesToStringAsString(
recMess.payload.message);
return ListView(
children: [
Card(
child: ListTile(
title: Text(payload),
))
],
padding: EdgeInsets.all(10),
);
} catch (e) {
return Center(
child: Text("Error: ${e.toString()}"),
);
}
}
return Center(child: CircularProgressIndicator());
},
);
}
return Center(child: CircularProgressIndicator());
},
),
);
}
}
You can use this piece of code:
void _subscribeToTopic(String topicName) {
print('MQTTClientWrapper::Subscribing to the $topicName topic');
client.subscribe(topicName, MqttQos.atMostOnce);
client.updates!.listen((List<MqttReceivedMessage<MqttMessage>> c) {
final recMess = c[0].payload as MqttPublishMessage;
String message =
MqttPublishPayload.bytesToStringAsString(recMess.payload.message);
String decodeMessage = Utf8Decoder().convert(message.codeUnits);
print("MQTTClientWrapper::GOT A NEW MESSAGE $decodeMessage");
});
}

Flutter, How to Replace Html tags to Text?

When I am fetching data from the internet I get for example
<p> Shawarma </p>,
How can I display the data without appearing the <p> tag?
Note that there is a package called: html_character_entities and others but how can I use them in the builder?
FutureBuilder<Iterable<SubCategories>>(
builder: (context, snapshot) {
return ListView.builder(
itemBuilder: (context, index) =>
Text(
snapshot.data!.elementAt(index).description,
),
);
}),
No need for a package for this ...
FutureBuilder<Iterable<SubCategories>>(
builder: (context, snapshot) {
return ListView.builder(
itemBuilder: (context, index) =>
Text(
snapshot.data!.elementAt(index).description.replaceAll(RegExp(r'<[^>]*>|&[^;]+;'), ''),
),
);
}),
You can use this package : https://pub.dev/packages/flutter_html it will render hrml tags. OR
you can
use this function by creating self :
static String stripHtml(String text) {
return text.replaceAll(RegExp(r'<[^>]*>|&[^;]+;'), ' ');
}
In you code you can use like this by using that fucntion:
FutureBuilder<Iterable<SubCategories>>(
builder: (context, snapshot) {
return ListView.builder(
itemBuilder: (context, index) =>
Text(
stripHtml (snapshot.data!.elementAt(index).description,),
),
);
})
You can use html package like this:
String _removeHtmlTag(String str) {
String result = '';
final document = parse(str);
if (document.body != null) {
result = parse(document.body!.text).documentElement!.text;
}
return result;
}
and use this like this:
print("result = ${_removeHtmlTag('<p> Shawarma </p>')}"); //result = Shawarma

ItemList: RangeError (index): Invalid value: Valid value range is empty: 0

I know that many topics are created with this title, but there isnt an answer for this specific kind.
I get the following Error-Code:
Error: RangeError (index): Invalid value: Valid value range is empty: 0
When there isnt any data in the REST-API the output is: []
I dont know why i get this error-message please help me to solve it...
body: blockitem.listitems == null
? Center(child: CircularProgressIndicator())
: ItemList(),
ListView.builder(
itemCount: blockitem.listitems[tab.currentTab] == null
? 0
: selectedList.length,
itemBuilder: (BuildContext context, int index) {
return Card(
elevation: 2.0,
color: Colors.blue.shade50,
child: ListTile(
leading: getValidityIcon(
selectedList[index].isValid,
selectedList[index].targetAge),
title: Text(selectedList[index].name),
subtitle: Text(
"Expires at: ${selectedList[index].expDate}"),
trailing: Icon(
Icons.arrow_forward_ios,
color: Colors.green.shade400,
),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ItemDetail(itemDetailed: selectedList[index]),
),
);
},
),
);
itemCount: blockitem.listitems[tab.currentTab] == null
The output is not null. It is just empty. You can check it's size. So change your code like this;
blockitem.listitems.length == 0 ? .....

infinite loading for json data in flutter

EDIT - "When I tried to run print(snapshot.error), It gave "type int is not a subtype of type string""
I am trying to get json data from https://raw.githubusercontent.com/RahulBagdiOfficial/rto_app_flutter/master/assets/json/applyonline.json
using https request package then parsing it into json data,
I am using it to build a list using ListView.builder
that if the data is null return CircularProgressIndicator
and if it contain data return list
The problem is This
its Stuck on loading
This is my code
class ApplyOnline extends StatefulWidget {
#override
_ApplyOnlineState createState() => _ApplyOnlineState();
}
class _ApplyOnlineState extends State<ApplyOnline> {
#override
Future<List<ApplyOnlineList>> _getapplyonlinelist() async {
var data = await http.get(
"https://raw.githubusercontent.com/RahulBagdiOfficial/rto_app_flutter/master/assets/json/applyonline.json");
var jsonData = json.decode(data.body);
List<ApplyOnlineList> applyonlinelist = [];
for (var i in jsonData) {
ApplyOnlineList applyonlineobject =
ApplyOnlineList(i['index'], i['string'], i['url']);
applyonlinelist.add(applyonlineobject);
}
print(applyonlinelist.length);
return applyonlinelist;
}
Widget customURLButton(String text, String URL, Icon icon) {
;
}
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color(0xff655ee6),
appBar: AppBar(
backgroundColor: Color(0xff655ee6),
title: Text("Apply Online"),
),
body: SingleChildScrollView(
child: SizedBox(
height: MediaQuery.of(context).size.height,
child: FutureBuilder(
future: _getapplyonlinelist(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.data == null) {
return Container(
child: Center(
child: CircularProgressIndicator(),
),
);
} if(snapshot.hasData) {
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (BuildContext context, int index) {
return ListTile(
title: Text(snapshot.data[index].string),
);
},
);
}
},
),
),
),
);
}
}
class ApplyOnlineList {
final int index;
final String url;
final String string;
ApplyOnlineList(this.url, this.index, this.string);
}
You should pass reference of the future since you're not accepting any params in future:
future: _getapplyonlinelist
Check all the connection state before getting into snapshot.
And for checking snapshot, You can do this way:
if(snapshot.hasData) {
// return something
} else if(snapshot.hasError) {
// play with error
}
return CircularProgressIndicator();
The problem is, you're checking for null, and returning the widget, doing this doesn't allow the FutureBuilder to rebuild because you're not checking its connection state, so the state of the data won't update. Try this instead.
...
FutureBuilder(
future: _getapplyonlinelist(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.connectionState == ConnectionState.waiting || !snapshot.hasData)
{
return Center(
child: CircularProgressIndicator(),
);
}
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (BuildContext context, int index) {
return ListTile(
title: Text(snapshot.data[index].string),
);
);
}
...
Checking the ConnectionState will let the future builder resolve the future properly.
future: _getapplyonlinelist(),
Don't do this. This way, every time your build function is called, your Future will start over. You need to start it once and then wait for it.
In your state, outside the build method, have a variable to hold the future. Assign _getapplyonlinelist() to this variable once, probably in the void initState () method. Then use that variable in your build method. That way, no matter how often the build method is called, it will not start the Future over and over and over.
In your state class:
Future<List<ApplyOnlineList>> waitingForOnlineList;
void initState () {
waitingForOnlineList = _getapplyonlinelist();
}
... and then in your build method:
future: waitingForOnlineList,

Flutter http get json data

I am having difficulty with data get. I am very new to Flutter and although I read the articles, I could not overcome this problem. I was able to get the data individually, but I couldn't put it in a loop. The codes are below.
Future<List<Post>> getPosts() async {
var jsonData = await http.get("https://example.com/api/posts.php");
final jsonResponse = json.decode(jsonData.body);
Match postList= Post.fromJsonMap(jsonResponse);
return (jsonResponse as List)
.map((postList) => Post.fromJsonMap(postList))
.toList();
//print("post" + postList.result[1].home);
}
When I run the print method, I can print the data. However, when I send it to futurebuilder, the data is not coming.
body: FutureBuilder(
future: getPosts(),
builder: (BuildContext context, AsyncSnapshot<List<Post>> snapshot) {
if (snapshot.hasData) {
print("test");
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(snapshot.data[index].result[index].home),
subtitle: Text(snapshot.data[index].result[index].title),
leading: CircleAvatar(
child: Text(
snapshot.data[index].result[index].id.toString()),
),
);
});
} else {
return Center(child: CircularProgressIndicator());
}
}),
Note: The codes I used as an example: https://github.com/emrealtunbilek/flutter_json_http/blob/master/lib/remote_api.dart
Try add additional if branch like this
} else if (snapshot.hasError) {
print(snapshot.error);
} else {
You can use JsonToDart for parse data and cast to your model