Flutter: Show data from RestAPI - flutter

I am trying to show the data from database to Flutter.
I am able to get the data but don't know how can i show it in Flutter. Single data i can show but getting hard time presenting multiple data.
I am using DIO plugin for HTTP requests.
Here is the code.
Future getData() async{
try{
dtguid ='34';
var bodyss = { "uid" : dtgUid, "deviceid": deviceid};
Response<Map> responsess =
await Dio().post("http://192.168.100.4:8080/sampleapp/get-followingdata.php", data: bodyss,);
Map responseBody = response.data;
if(responseBodys['success'] == false){
_showSnackBar(context,responseBody['errors']['inputuid'],Colors.redAccent);
this.setState((){
_inProcess = false;
});
}else{
print(responseBody['success']);
totalcount = responseBody['count'];
this.setState((){
_inProcess = false;
});
}
}catch(e){
print("Exception Caught: $e");
}
}
Here is the Widget where i need to show this data.
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
'Test',// schoolLists[index]['name'],
style: TextStyle(
color: primary,
fontWeight: FontWeight.bold,
fontSize: 18),
),
SizedBox(
height: 6,
),
Row(
children: <Widget>[
Icon(
Icons.location_on,
color: secondary,
size: 20,
),
SizedBox(
width: 5,
),
Text(
'Earth',//schoolLists[index]['location'],
style: TextStyle(
color: primary, fontSize: 13, letterSpacing: .3)),
],
),
SizedBox(
height: 6,
),
Row(
children: <Widget>[
Icon(
Icons.school,
color: secondary,
size: 20,
),
SizedBox(
width: 5,
),
Text(
'Some Data',
//schoolLists[index]['type'],
style: TextStyle(
color: primary, fontSize: 13, letterSpacing: .3)),
],
),
],
),
)
For testing purpose i tried with some hardcoded data schoolLists that is working but i don't know how can i show the data from http request.
Sample Data.
{"errors":[],
"content":[{"uid":34,"age":35,"name":"Test User 1","country":"India"},
{"uid":34,"age":37,"name":"Test User 2","country":"India"},
{"uid":34,"age":36,"name":"Test User 3","country":"India"}],
"success":true}
I need to show name and country to the widget.
In place of this test value.
Text(
'Test',// schoolLists[index]['name'],
style: TextStyle(
color: primary,
fontWeight: FontWeight.bold,
fontSize: 18),
),
Later on i will try to work on Lazyload. Unfortunatly, i am not able to show the data so, didn't asked about the lazyload.
To be honest i am learning Flutter. I don't have much experience in it.

i dont see you decoding the body response data
on top of your code first import
import 'dart:convert' as convert;
than in your function getData() decode the server JSON response like this
//get the json data decode it and store it in decodedResponse
var decodedResponse = convert.jsonDecode(response.body);
than map thru your decodedResponse as you want

Related

How to get the user's display name without getting a null check error in Flutter project?

So, currently, I am creating a Flutter project which is an Android tricycle booking system. I am using a drawer widget inside the application. What I wanted to do is when a user logged in inside the application, their name will be shown in the drawer. However, when I tried following a tutorial video (since I am just a beginner), the screen always becomes red and shows the error:
"Null check operator used on a null value."
I think this is because of me trying to display the name of the user. Does anyone know how to fix this error? I am stuck already for so many days. Any help will be much appreciated!
This is the snippet of my codes for fetching the user's name:
UserAccountsDrawerHeader(
decoration: BoxDecoration(
color: Color(0xFFFED90F),
),
accountName: new Text(userModelCurrentInfo!.first_name! + " " + userModelCurrentInfo!.last_name!, // This is the line that makes it null
style: TextStyle( color: Colors.white,
fontSize: 15,
fontFamily: "Montserrat",
fontWeight: FontWeight.w600,),
),
accountEmail: new Text(user.email!,
style: TextStyle( color: Colors.white,
fontSize: 15,
fontFamily: "Montserrat",
fontWeight: FontWeight.w600,),
),
currentAccountPicture: new CircleAvatar(
radius: 50.0,
backgroundImage: AssetImage("assets/images/machu.jpg"),
),
),
This is the code for reading the current user details:
static void readCurrentOnlineUserInfo() async
{
final FirebaseAuth fAuth = FirebaseAuth.instance;
User? currentFirebaseUser;
currentFirebaseUser = fAuth.currentUser;
DatabaseReference userRef = FirebaseDatabase.instance
.ref()
.child("passengers")
.child(currentFirebaseUser!.uid);
userRef.once().then((snap)
{
if(snap.snapshot.value != null)
{
userModelCurrentInfo = UserModel.fromSnapshot(snap.snapshot);
print("name" + userModelCurrentInfo!.first_name.toString());
print("id" + userModelCurrentInfo!.id.toString());
}
});
}
Another thing that I notice:
Upon logging in, it will show the null error, then when I go to another tab and come back to the page that says null error, it suddenly disappears. Why tho?
Try this.
Added not null conditions
UserAccountsDrawerHeader(
decoration: BoxDecoration(
color: Color(0xFFFED90F),
),
accountName: userModelCurrentInfo!.first_name !=null && userModelCurrentInfo!.last_name !=null ?
new Text(userModelCurrentInfo!.first_name! + " " + userModelCurrentInfo!.last_name!,
style: TextStyle( color: Colors.white,
fontSize: 15,
fontFamily: "Montserrat",
fontWeight: FontWeight.w600,),
):new Text('')// added null condition here,
accountEmail: new Text(user.email!,
style: TextStyle( color: Colors.white,
fontSize: 15,
fontFamily: "Montserrat",
fontWeight: FontWeight.w600,),
),
currentAccountPicture: new CircleAvatar(
radius: 50.0,
backgroundImage: AssetImage("assets/images/machu.jpg"),
),
),

How to make my own Loading Screen Indicator in flutter?

So far, I have made a loading animation that includes Container, Column, Text, and Image(gif). And this code is working fine in a new project but when I try to implement this code into my ongoing project, it is not working!
It does not throw any error but the loading screen is blank.
Like data from API loads without loading animation.
So, what I am doing wrong in this, or how to implement loader correctly?
Loader's code:
return Scaffold(
body: Container(
height: 130,
width: 135,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(17),
border: Border.all(color: Colors.blue)),
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const Text(
"Loading...",
style: TextStyle(
fontSize: 13,
letterSpacing: 2.1,
color: Colors.blue,
),
),
Padding(
padding: const EdgeInsets.all(3.0),
child: Image.network(
"https://cdn.dribbble.com/users/42716/screenshots/3913441/media/4ef7d67070fee7ab75948280f51d369f.gif",
height: 100,
),
),
],
),
),
);
Here I am implementing code:
Future<List<VeReportModel>>? _vReport() async {
debugPrint("Do not exploit this code $fDate &&&&&&&& Thank you");
try {
if (await NetworkUtils.isNetworkAvailable()) {
//UIUtils.showProcessIndicator(); //TODO This is old Indicator I want a new one here
Loader();
ApiResponse? apiResponse = await RestApiClient(session: session)
.vReport(fDate, tDate, spedLimit, stLimit, vId!);
UIUtils.hideProcessIndicator(); //TODO Old Indicator disposed
Common.printWrapped('Map: _vEvent(): apiResponse=$apiResponse');
if (apiResponse!.successful && apiResponse.code == apiSuccessCode) {
if (apiResponse.data != null) {
List mapMessages = apiResponse.result;
debugPrint("mapMessage $mapMessages");
return mapMessages
.map((v) => VeReportModel.fromJson(v))
.toList();
}
}
} else {
UIUtils.hideProcessIndicator();
UIUtils.displayInternetError(context);
}
} catch (e,stack) {
UIUtils.hideProcessIndicator();
UIUtils.catchErrorMsg(context);
debugPrint('Error While acknowledging v report : $e');
GeneralException.handleError(e, stack: stack, module: moduleVeReport);
debugPrint('VeReport: Error while getting v list: $e');
}
return [];
}

AssetsAudioPlayer only plays the audio at last index

I'm using a listview to display images and text in my flutter app. I've stored the asset path and text in a Json file and I convert it to a list. Getting the image asset path and displaying the correct one seems to work with no issues but thats not the case in playing the audio files from their assets.
I'm using this package import 'package:assets_audio_player/assets_audio_player.dart';
declaration final AssetsAudioPlayer playAudio = AssetsAudioPlayer();
and this is main widget
#override
Widget build(BuildContext context) {
Widget _buildRow(int idx) {
for (var translations in widget.category.translations) {
_wordList = widget.category.translations[idx];
return Container(
height: 88.0,
child: Card(
child: ListTile(
onTap: () {
playAudio.open(
Audio(_wordList.audio),
);
// player.play(_wordList.audio);
log(_wordList.audio, name: 'my.other.category');
},
onLongPress: () {},
leading: SizedBox(
width: 50.0,
height: 88.0,
child: Image(
image: AssetImage(_wordList.emoji),
fit: BoxFit.contain,
),
),
title: Text(
_wordList.akan,
style: TextStyle(fontSize: 18),
),
subtitle: Text(
_wordList.english,
style: TextStyle(fontSize: 18, color: Colors.black),
),
trailing: const Icon(Icons.play_arrow, size: 28),
),
),
);
}
}
Since the image assets in the json file have no issues I don't get why the audio does
I've stored them like this,
{
"english": "mother",
"akan": "ɛna",
"emoji": "assets/icons/family_mother.png",
"audio": "assets/audio/family_mother.mp3"
},
Solved it by generating a new listtile widget through iteration and then putting it into a listview

A non-null String must be provided to a Text widget - flutter

I'm new to flutter and I'm learning it via a course on Udemy in this course we learn to create a simple BMI calculator which I did but the problem is that my app stats working perfectly and I can change the numbers and gender on it and sometimes it shows the result
<════════ Exception caught by widgets library ════════════
The following assertion was thrown building ResultsPage(dirty):
A non-null String must be provided to a Text widget.
'package:flutter/src/widgets/text.dart':
Failed assertion: line 381 pos 10: 'data != null'
The relevant error-causing widget was:
ResultsPage
file:///D:/FlutterProjects/bmi_calculator/lib/input_page.dart:223:47
When the exception was thrown, this was the stack:
#2 new Text (package:flutter/src/widgets/text.dart:381:10)
#3 ResultsPage.build (package:bmi_calculator/results_page.dart:50:19)
#4 StatelessElement.build (package:flutter/src/widgets/framework.dart:4749:28)
#5 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4675:15)
#6 Element.rebuild (package:flutter/src/widgets/framework.dart:4369:5)>
I don't know exactly what the problem is I tried to read similar problems here but unfortunately, I couldn't find which text widget I pass empty. this is the code for my results page
import 'package:bmi_calculator/bottom_button.dart';
import 'package:bmi_calculator/constants.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'reusable_card.dart';
class ResultsPage extends StatelessWidget {
ResultsPage(
{#required this.resultText,
#required this.bmiResult,
#required this.interpretation});
final String resultText;
final String bmiResult;
final String interpretation;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Your Results'),
),
body: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Expanded(
child: Container(
padding: EdgeInsets.all(15.0),
alignment: Alignment.bottomLeft,
child: Text(
'Your Results',
style: kTitleStyle,
),
),
),
Expanded(
flex: 5,
child: ReusableCard(
colour: kActiveCardColour,
cardChild: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Text(
bmiResult,
style: kResultTextStyle,
),
Text(
resultText,
style: kNumberTextStyle.copyWith(
fontSize: 100.0,
fontWeight: FontWeight.bold,
),
),
Text(
interpretation,
textAlign: TextAlign.center,
style: kBMIResultTextStyle,
)
],
),
),
),
BottomButton(
onTap: () => Navigator.pop(context), buttonTitle: 'ReCalculate')
],
),
);
}
}
EDIT:
Thanks, everyone for responding to my issue.
All of the solutions worked for me and stopped my app from crashing. and I used this method
Text(
bmiResult ?? '',
style: kResultTextStyle,
),
Text(
resultText ?? '',
style: kNumberTextStyle.copyWith(
fontSize: 100.0,
fontWeight: FontWeight.bold,
),
),
Text(
interpretation ?? '',
textAlign: TextAlign.center,
style: kBMIResultTextStyle,
)
to keep my code short and concise. But, I also realized something else in my code. I have three conditions in my app, which as you can guess are underweight, normal, and overweight. When I calculate the results, the application shows resultText and interpretation only if it's overweight. if the result is normal or underweight, it doesn't show them, and I assume it means this is what makes my app to crash because somehow it can't get the Text strings which I assigned for normal and underweight.
Either initialize the values to be not null or simply using ?? Operator to make this empty string when null is detected
children: <Widget>[
Text(
bmiResult ?? "",
style: kResultTextStyle,
),
Text(
resultText ?? "",
style: kNumberTextStyle.copyWith(
fontSize: 100.0,
fontWeight: FontWeight.bold,
),
),
Text(
interpretation ?? "",
textAlign: TextAlign.center,
style: kBMIResultTextStyle,
)
],
You just need to check if your variables : resultText, bmiResult, interpretation are not null because the Text widget cannot receive null value.
Text(
this.bmiResult != null ? this.bmiResult : "",
style: kResultTextStyle,
),
Text(
this.resultText != null ? this.resultText : "",
style: kNumberTextStyle.copyWith(
fontSize: 100.0,
fontWeight: FontWeight.bold,
),
),
Text(
this.interpretation != null ? this.interpretation : "",
textAlign: TextAlign.center,
style: kBMIResultTextStyle,
)
Or, you can just use the null-coalescing operator ?? to simplify :
this.interpretation ?? ""
You have at least 3 Text widgets where the data property is initialized from class members: resultText, bmiResult, interpretation. It looks like one of these member is null. To avoid the red screen you need to:
Call widget with initialized props:
ResultsPage(
resultText: 'Result Text',
bmiResult: 'BMI result',
interpretation: 'interpretation',
)
Set default values for ResultsPage's properties in constructor (e.g. empty string)
ResultsPage({this.resultText = '', this.bmiResult = '', this.interpretation = ''})
Use null aware feature in Text() widgets:
Text(resultText ?? 'n/a'),
This means that Text data will be equal to value of resultText if it is not null, or n/a if is null.
empty string will be used as data.

text with \n and unicode literals saved in mysql do not work when displayed

I store a text string with \n and unicode literals like \u2022 in mysql, then retrieve it with http api call on flutter. When displaying it with Text widget, these escaped symbles do not show as expected. When I directly pass the string , it works. Could anyone help me out?
child: Column(
children: <Widget>[
Text(prompt.prompt_body, //This variable is from http call which does not work
textAlign: TextAlign.left,
style:TextStyle(
color: Colors.black,
fontSize: 13,
fontWeight: FontWeight.bold,
fontStyle: FontStyle.italic
)),
Divider(),
Text("You live in a room in college which you share with another student.However, there are many problems with this arrangement and you find it very difficult to work.\n\nWrite a letter to the accommodation officer at the college. In the letter,\n\n \u2022 describe the situation\n \u2022 explain your problems and why it is difficult to work\n \u2022 say what kind of accommodation you would prefer", //this part works
textAlign: TextAlign.left,
style:TextStyle(
color: Colors.black,
fontSize: 13,
fontWeight: FontWeight.bold,
fontStyle: FontStyle.italic
))
],
),
emulator screenshot
In response to Gunter's query, I add the following code on api call:
class PromptModel {
int id;
String prompt_body;
String prompt_image;
PromptModel(this.id, this.prompt_body, this.prompt_image);
PromptModel.fromJson(Map<String, dynamic> parsedJson) {
id = parsedJson['id'];
prompt_body = parsedJson['prompt_body'];
prompt_image = parsedJson['prompt_image'];
}
}
....
class PromptListPageState extends State<PromptListPage> {
int counter = 0;
List<PromptModel> prompts = [];
void fetchImage() async {
counter++;
var response =
await get('http://10.0.2.2:8080/TestPrompt');
var promptModel = PromptModel.fromJson(json.decode(response.body));
setState(() {
prompts.add(promptModel);
});
}
The following is the response of the api call:
{"id":1,"prompt_body":"You live in a room in college which you share with another student.However, there are many problems with this arrangement and you find it very difficult to work.\\n\\nWrite a letter to the accommodation officer at the college. In the letter,\\n\\n \\u2022 describe the situation\\n \\u2022 explain your problems and why it is difficult to work\\n \\u2022 say what kind of accommodation you would prefer","prompt_image":"http://10.0.2.2:8080/test.jpg"}
I solved the problem by inputting the string from flutter using TextFormField. directly inserting the text on database side is tricky. The code is as below:
Widget build(context) {
return MaterialApp(
home: Scaffold(
body: Form(
key: formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
TextFormField(
controller: myController,
maxLines: 5,
validator: (val) =>
(val == null || val.isEmpty) ? "请输入商品名称" : null,
decoration: const InputDecoration(
//icon: Icon(Icons.person),
hintText: 'add the prompt here:',
labelText: 'Prompt content',
border: OutlineInputBorder(
borderSide: BorderSide(color: Colors.teal)),
),
onSaved: (val) => this.content = val,
),
new Container(
margin: const EdgeInsets.only(top: 10.0),
child: new RaisedButton(
onPressed: _save,
child: new Text('Save'),
),
)
]),
),
appBar: AppBar(
title: Text('Add Essay Prompt'),
),
),
);
}
}