POST request body is not updating after inserting new value - json

I have a login field that when doing a post request it returns the http code. If I enter a valid phone number it returns 200. All good here. But when I try to reproduce an error message, it stores the previous phone number forever and I can't find a way to reset that field like it is in the beginning. Is this something to do with cache? Or is it about the variables state?
My Post body stored in global_variables.dart:
final Map<String, dynamic> loginBody = {
"type": "device",
"app_id": '1',
"email": "example#example.pt",
"country_id": '1',
"phone_number": phone.text, --> I want to reset the value here
"password": "secret"
};
login.dart
#override
void initState() {
super.initState();
success = false;
focusNode.addListener(() {
if (!focusNode.hasFocus) {
log(phone.text);
}
});
refreshValues();
}
#override
void dispose() {
focusNode.dispose();
phone.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return !success
? Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: TextFormField(
maxLength: 9,
controller: phone,
focusNode: focusNode,
),
),
ElevatedButton(
onPressed: () async {
await login();
if (success) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
backgroundColor: Colors.green,
content: Text(
loginSuccessful.toString(),
),
),
);
// ignore: use_build_context_synchronously
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const BreakdownScreen(),
),
);
refreshValues();
} else {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
backgroundColor: Colors.red,
content: Text(
loginUnsuccessful.toString(),
),
),
);
refreshValues();
}
},
child: const Text('Login'),
)
],
)
: Container();
}
void refreshValues() {
setState(
() {
loginSuccessful = "";
loginUnsuccessful = "";
phone.text = "";
},
);
}
Future<void> login() async {
try {
if (phone.text.length == 9) {
var response = await http.post(
Uri.parse("http://LOCAL_API/api/login"),
body: loginBody,
);
if (response.statusCode == 200) {
Map<String, dynamic> loginSuccess = json.decode(response.body);
Map<String, dynamic> loginTokenOnSuccess = json.decode(response.body);
loginToken = loginTokenOnSuccess['data'];
setState(
() {
loginSuccessful = loginSuccess['message'];
success = true;
// phone.text = "";
},
);
} else {
Map<String, dynamic> loginNoSuccess = json.decode(response.body);
setState(() {
success = false;
loginUnsuccessful = loginNoSuccess['message'];
});
}
}
} on Exception catch (e) {
log('ERRO ----- ${e.toString()},');
log(
json.encode(loginBody),
);
}
}
Output with invalid phone 333333333:
{(...)"phone_number":"333333333"}
Output with valid phone 22222222 (for example):
It only doesn't update after inserting a first value and stays like that until I hot reload the app.
{(...)"phone_number":"333333333"}
tl;dr: my phone_number field doesn't change after a second attempt

Solved it!
I had to construct the body directly on the POST function and remove it from the global_variables.dart file.
Future login() async {
try {
setState(() {});
if (phone.text.length == 9) {
var response = await http.post(
Uri.parse("http://LOCAL_API/api/login"),
body: {
"type": "device",
"app_id": '1',
"email": "example#mexample.com",
"country_id": '1',
"phone_number": phone.text,
"password": "secret"
},
);

Related

There should be exactly one item with [DropdownButton]'s value: Instance of 'Partner'

My dropdown working as expected . but when I selected a item my app crashing with error
There should be exactly one item with [DropdownButton]'s value: Instance of 'Partner'.
Either zero or 2 or more [DropdownMenuItem]s were detected with the same value
First I declare my variable in class
class _MultipleTestBookingState extends State<MultipleTestBooking> {
Partner? _selectedLab;
Datum? _selectedTest;
....................
declare with Partner?_selectedLab; because my dropdown menu takes in a list of Partners
Then using this variable to show the selected value in my dropdown
Container(
child: FutureBuilder<List<Partner>>(
future: AllPathLab(),
builder:
(BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.connectionState !=ConnectionState.done) {
return CircularProgressIndicator();
}
if (snapshot.hasError) {
return Text("Somthing went wrong");
}
if (snapshot.hasData) {
return DropdownButton<Partner>(
value: _selectedLab,
hint: Text("Select Lab"),
items: snapshot.data.map((Partner data) =>
DropdownMenuItem<Partner>(
child: Text("${data.partnerName}"),
value: data,
)
).toList().cast<DropdownMenuItem<Partner>>(),
onChanged: (value){
setState(() {
_selectedLab=value;
encLabId = value!.encPartnerId;
GetTestByLab();
});
}
);
}
return Text("Waiting for Internet Connection");
},
),
),
Full code with my JSON response
So from the data that you provided i have created the code below:
import 'package:date_time_picker/date_time_picker.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_app/Patner.dart';
import 'package:flutter_app/dataModel.dart';
import 'package:http/http.dart' as http;
void main() {
runApp(MaterialApp(
debugShowCheckedModeBanner: false,
home: MyApp(),
));
}
class MyApp extends StatefulWidget {
const MyApp({Key key}) : super(key: key);
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
Partner _selectedLab;
Datum _selectedTest;
Future getAllPathLabResults;
Future getTestByLabResult;
String encLabId = '';
void initState() {
super.initState();
getAllPathLabResults = allPathLab();
getTestByLabResult = getTestByLab();
}
String _selectedDate = DateTime.now().toString();
Future<List<Partner>> allPathLab() async {
String jsonData = jsonstring;
final model = modelFromJson(jsonData);
print("This is the list length : ${model.partner.length}");
List<Partner> arrData = model.partner;
// this Future is for sample as you will be fetching the api data remove this one
Future.delayed(Duration(seconds: 3));
return arrData;
}
Future<List<Datum>> getTestByLab() async {
print("This is the Id :$encLabId");
_selectedTest = null;
var response = await http.post(
Uri.parse("http://medbo.digitalicon.in/api/medboapi/GetTestByLab"),
body: ({"EncId": encLabId}));
if (response.statusCode == 200) {
final dataModel = dataModelFromJson(response.body);
print(dataModel.data.length);
for (final item in dataModel.data) {
print("This is hte test name :${item.testName}");
}
List<Datum> arrData = dataModel.data;
return arrData;
}
return [];
}
#override
Widget build(BuildContext context) {
var screenWidth = MediaQuery.of(context).size.width;
var screenHeight = MediaQuery.of(context).size.height;
var blockSizeHorizontal = (screenWidth / 100);
var blockSizeVertical = (screenHeight / 100);
return Scaffold(
body: SafeArea(
child: Container(
child: Column(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: ListTile(
title: Text("Booking Information",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: blockSizeHorizontal * 5,
fontFamily: 'Poppins',
color: Theme.of(context).primaryColor,
)),
subtitle: Text("Preferred Visit Date"),
),
),
Container(
margin: EdgeInsets.only(left: 20),
padding: EdgeInsets.only(left: 0, right: 150),
decoration: BoxDecoration(
color: Colors.lightBlue[50],
borderRadius: BorderRadius.all(Radius.circular(12)),
),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: DateTimePicker(
initialValue: DateTime.now().toString(),
//initialValue:'', // initialValue or controller.text can be null, empty or a DateTime string otherwise it will throw an error.
type: DateTimePickerType.date,
dateLabelText: 'Select Date',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: blockSizeHorizontal * 3.5,
fontFamily: 'Poppins',
color: Colors.green,
letterSpacing: 2.0,
),
firstDate: DateTime.now(),
lastDate: DateTime.now().add(Duration(days: 30)),
// This will add one year from current date
validator: (value) {
return null;
},
onChanged: (value) {
if (value.isNotEmpty) {
setState(() {
_selectedDate = value;
});
}
},
onSaved: (value) {
if (value.isNotEmpty) {
_selectedDate = value;
}
},
),
),
),
ListTile(
title: Text(
"Select Pathological Lab",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: blockSizeHorizontal * 4.0,
fontFamily: 'Poppins',
color: Theme.of(context).primaryColor,
),
),
),
Container(
child: FutureBuilder<List<Partner>>(
future: getAllPathLabResults,
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.connectionState != ConnectionState.done) {
return CircularProgressIndicator();
}
if (snapshot.hasError) {
return Text("Somthing went wrong");
}
if (snapshot.hasData) {
List<Partner> data =
snapshot.hasData ? snapshot.data : [];
return DropdownButton<Partner>(
value: _selectedLab,
hint: Text("Select Lab"),
//underline: SizedBox(),
//isExpanded: true,
items: data
.map((Partner data) => DropdownMenuItem<Partner>(
child: Text("${data.partnerName}"),
value: data,
))
.toList()
.cast<DropdownMenuItem<Partner>>(),
onChanged: (value) {
setState(() {
_selectedLab = value;
encLabId = value.encPartnerId;
getTestByLabResult = getTestByLab();
});
//GetTestByLab(value!.encPartnerId); // passing encid to my next API function
// GetTestByLab();
},
);
}
return Text("Waiting for Internet Connection");
},
),
),
//=========================================================== Dependent drop down===================================
ListTile(
title: Text(
"Test Name",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: blockSizeHorizontal * 4.0,
fontFamily: 'Poppins',
color: Theme.of(context).primaryColor,
),
),
),
Container(
child: FutureBuilder<List<Datum>>(
future: getTestByLabResult,
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.connectionState != ConnectionState.done) {
return CircularProgressIndicator();
}
if (snapshot.hasError) {
return Text("Select a Lab for your Test");
}
if (snapshot.hasData) {
List<Datum> data = snapshot.hasData ? snapshot.data : [];
return DropdownButton<Datum>(
value: _selectedTest,
hint: Text(""),
//underline: SizedBox(),
//isExpanded: true,
items: data
.map((Datum data) => DropdownMenuItem<Datum>(
child: Text("${data.testName}"),
value: data,
))
.toList()
.cast<DropdownMenuItem<Datum>>(),
onChanged: (value) {
print("This is the value : ${value.testName}");
setState(() {
_selectedTest = value;
});
//GetTestByLab(value!.encPartnerId); // passing encid to my next API function
});
}
return Text("Waiting for Internet Connection");
},
),
),
],
),
),
),
);
}
}
// used this as a sample
String jsonstring = '''{
"Status": "1",
"Message": "",
"Partner": [
{
"EncPartnerId": "IujyQXg8KZg8asLvK/FS7g==",
"PartnerName": "dasfdsf"
},
{
"EncPartnerId": "pEl2B9kuumKRxIxLJO76eQ==",
"PartnerName": "partner172"
},
{
"EncPartnerId": "eYwtNBXR6P/JDtsIwr+Bvw==",
"PartnerName": "nnkb"
},
{
"EncPartnerId": "kFgorcFF0G6RQD4W+LwWnQ==",
"PartnerName": "nnkjj"
},
{
"EncPartnerId": "U4exk+vfMGrn7cjNUa/PBw==",
"PartnerName": "mahadev"
},
{
"EncPartnerId": "tqkaSjTFgDf0612mp9mbsQ==",
"PartnerName": null
},
{
"EncPartnerId": "0aruO0FbYOu5IerRBxdT8w==",
"PartnerName": "Suraksha Diagnostics"
},
{
"EncPartnerId": "65gtodyhbtdInTsJWr1ZkA==",
"PartnerName": "Rasomoy pvt. Hospital"
},
{
"EncPartnerId": "LEuT1eIlpLEMAAkZme3wpQ==",
"PartnerName": "Tangra medical House"
},
{
"EncPartnerId": "q8O8YMzYKXSB4RtkX4k7Lw==",
"PartnerName": "Partner new"
}
]
}''';
Models for the apis:
// To parse this JSON data, do
//
// final model = modelFromJson(jsonString);
import 'dart:convert';
Model modelFromJson(String str) => Model.fromJson(json.decode(str));
String modelToJson(Model data) => json.encode(data.toJson());
class Model {
Model({
this.status,
this.message,
this.partner,
});
String status;
String message;
List<Partner> partner;
factory Model.fromJson(Map<String, dynamic> json) => Model(
status: json["Status"],
message: json["Message"],
partner:
List<Partner>.from(json["Partner"].map((x) => Partner.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"Status": status,
"Message": message,
"Partner": List<dynamic>.from(partner.map((x) => x.toJson())),
};
}
class Partner {
Partner({
this.encPartnerId,
this.partnerName,
});
String encPartnerId;
String partnerName;
factory Partner.fromJson(Map<String, dynamic> json) => Partner(
encPartnerId: json["EncPartnerId"],
partnerName: json["PartnerName"] == null ? null : json["PartnerName"],
);
Map<String, dynamic> toJson() => {
"EncPartnerId": encPartnerId,
"PartnerName": partnerName == null ? null : partnerName,
};
}
second api parsing model
// To parse this JSON data, do
//
// final dataModel = dataModelFromJson(jsonString);
import 'dart:convert';
DataModel dataModelFromJson(String str) => DataModel.fromJson(json.decode(str));
String dataModelToJson(DataModel data) => json.encode(data.toJson());
class DataModel {
DataModel({
this.status,
this.message,
this.data,
});
String status;
String message;
List<Datum> data;
factory DataModel.fromJson(Map<String, dynamic> json) => DataModel(
status: json["Status"],
message: json["Message"],
data: json["Data"] == null
? []
: List<Datum>.from(json["Data"].map((x) => Datum.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"Status": status,
"Message": message,
"Data":
data == null ? [] : List<dynamic>.from(data.map((x) => x.toJson())),
};
}
class Datum {
Datum({
this.testId,
this.encTestId,
this.testName,
this.noOfPartner,
this.testFee,
this.discountedFee,
this.bookingFee,
this.reportTime,
this.note,
this.createBy,
this.createDate,
this.modBy,
this.modDate,
this.activeStatus,
this.permission,
});
String testId;
dynamic encTestId;
String testName;
dynamic noOfPartner;
dynamic testFee;
dynamic discountedFee;
dynamic bookingFee;
dynamic reportTime;
dynamic note;
dynamic createBy;
dynamic createDate;
dynamic modBy;
dynamic modDate;
dynamic activeStatus;
dynamic permission;
factory Datum.fromJson(Map<String, dynamic> json) => Datum(
testId: json["TestId"],
encTestId: json["EncTestId"],
testName: json["TestName"],
noOfPartner: json["NoOfPartner"],
testFee: json["TestFee"],
discountedFee: json["DiscountedFee"],
bookingFee: json["BookingFee"],
reportTime: json["ReportTime"],
note: json["Note"],
createBy: json["CreateBy"],
createDate: json["CreateDate"],
modBy: json["ModBy"],
modDate: json["ModDate"],
activeStatus: json["ActiveStatus"],
permission: json["Permission"],
);
Map<String, dynamic> toJson() => {
"TestId": testId,
"EncTestId": encTestId,
"TestName": testName,
"NoOfPartner": noOfPartner,
"TestFee": testFee,
"DiscountedFee": discountedFee,
"BookingFee": bookingFee,
"ReportTime": reportTime,
"Note": note,
"CreateBy": createBy,
"CreateDate": createDate,
"ModBy": modBy,
"ModDate": modDate,
"ActiveStatus": activeStatus,
"Permission": permission,
};
}
So when you initially fetch the data based on the id and select the second dropdown. now when you change the lab you have the make the selected text to null.
and you are are also using the futurebuilder method in wrong manner as there is setstate getting called it is creating multiple rebuids and giving error.
please run the code and check if its working.

flutter json object to to list for dropdown menu

I got json object from API and i have to show this as a dropdown.
Json response
{
"deliveryCharges": {
"_id": "607b156404fb0a0184db98fe",
"businessId": "607b14ef04fb0a0184db98e3",
"createdAt": "2021-04-17T17:05:40.546Z",
"updatedAt": "2021-04-18T10:16:13.633Z",
"__v": 0,
"deliveryZones": {
"Bangladesh": { // country dropdown item 1
"Mirpur": {. // city dropdown item 1
"deliveryCost": "50",
"status": true
}
},
"American Samoa": { // country dropdown item 2
"lost city": { // city dropdown item 2
"deliveryCost": "50",
"status": true
}
}
}
}
}
Here Bangladesh and American Samoa in country drop down
Here Mirpur and lost city in city drop down
I thing i have to change json object to array. But did not found good example.
Advanced thanks
Since
"deliveryZones": {
"Bangladesh": { // country dropdown item 1
"Mirpur": {. // city dropdown item 1
"deliveryCost": "50",
"status": true
}
},
"American Samoa": { // country dropdown item 2
"lost city": { // city dropdown item 2
"deliveryCost": "50",
"status": true
}
}
}
this object will be stored in Map Data structure
you can convert map keys to list
map.keys.toList()
First, declare two variables of an array.
List<String> countryList = [];
List<String> zoneList = [];
After that parse JSON data which is provided from API response.
Map<String, dynamic> decoded = json.decode(response);
for (var colour in decoded.keys) {
List<String>.from(decoded[colour]['deliveryZones'].keys.map((model) {
countryList.add(model);
}));
List<String>.from(decoded[colour]['deliveryZones']['Bangladesh'].keys.map((model) {
zoneList.add(model);
}));
}
Now print and show the output
print("country $countryList");
print("zoneList $zoneList");
So I have Created a sample Example Based on the json that you provided.
json you provided :
{
"deliveryCharges": {
"_id": "607b156404fb0a0184db98fe",
"businessId": "607b14ef04fb0a0184db98e3",
"createdAt": "2021-04-17T17:05:40.546Z",
"updatedAt": "2021-04-18T10:16:13.633Z",
"__v": 0,
"deliveryZones": {
"Bangladesh": {
"Mirpur": {
"deliveryCost": "50",
"status": true
}
},
"American Samoa": {
"lost city": {
"deliveryCost": "50",
"status": true
}
}
}
}
}
Based on the json I have Made an Example :
import 'package:flutter/material.dart';
import 'dart:convert';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
var _isLoading = false;
String countryValue;
List<String> countriesList = [];
List<String> cityList = [];
String cityValue;
#override
void initState() {
super.initState();
getData();
}
getData() async {
setState(() {
_isLoading = true;
});
String data =
await DefaultAssetBundle.of(context).loadString("json/parse.json");
var item = json.decode(data);
item.forEach((key, value) {
print(value["deliveryZones"]);
value["deliveryZones"].forEach((key, value) {
print(key);
countriesList.add(key);
value.forEach((key, value) {
print(key);
cityList.add(key);
});
});
});
setState(() {
_isLoading = false;
});
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("Users List "),
),
body: Container(
width: 300,
child: _isLoading
? CircularProgressIndicator()
: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
DropdownButtonHideUnderline(
child: DropdownButton(
hint: Text(
'Choose Country'), // Not necessary for Option 1
value: countryValue,
onChanged: (newValue) {
setState(() {
countryValue = newValue;
});
print(countryValue);
},
items: countriesList.map((String company) {
return DropdownMenuItem(
child: new Text(company),
value: company,
);
}).toList(),
),
),
DropdownButtonHideUnderline(
child: DropdownButton(
hint: Text('Choose City'), // Not necessary for Option 1
value: cityValue,
onChanged: (newValue) {
setState(() {
cityValue = newValue;
});
print(cityValue);
},
items: cityList.map((String company) {
return DropdownMenuItem(
child: new Text(company),
value: company,
);
}).toList(),
),
),
],
),
),
),
);
}
}
Let me know if it works.

Flutter Nested array?

I have these JSON data
[
{
"student_id": 1,
"studentid": 1204,
"password": "demo",
"name": "Amber",
"level": "student",
"course_name": [
"Math",
"History"
]
}
]
Kindly show me the code to to achieve this :
Actually you have a JSON array (only one index), should be something like:
myArray[0].course_name.forEach(course => console.log(course));
data[index].courseName[0]
https://app.quicktype.io/ for right "model"
model.dart
// To parse this JSON data, do
//
// final welcome = welcomeFromJson(jsonString);
import 'dart:convert';
List<Welcome> welcomeFromJson(String str) => List<Welcome>.from(json.decode(str).map((x) => Welcome.fromJson(x)));
String welcomeToJson(List<Welcome> data) => json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
class Welcome {
int studentId;
int studentid;
String password;
String name;
String level;
List<String> courseName;
Welcome({
this.studentId,
this.studentid,
this.password,
this.name,
this.level,
this.courseName,
});
factory Welcome.fromJson(Map<String, dynamic> json) => Welcome(
studentId: json["student_id"] == null ? null : json["student_id"],
studentid: json["studentid"] == null ? null : json["studentid"],
password: json["password"] == null ? null : json["password"],
name: json["name"] == null ? null : json["name"],
level: json["level"] == null ? null : json["level"],
courseName: json["course_name"] == null ? null : List<String>.from(json["course_name"].map((x) => x)),
);
Map<String, dynamic> toJson() => {
"student_id": studentId == null ? null : studentId,
"studentid": studentid == null ? null : studentid,
"password": password == null ? null : password,
"name": name == null ? null : name,
"level": level == null ? null : level,
"course_name": courseName == null ? null : List<dynamic>.from(courseName.map((x) => x)),
};
}
main.dart
var jsonString = [
{
"student_id": 1,
"studentid": 1204,
"password": "demo",
"name": "Amber",
"level": "student",
"course_name": ["Math", "History"]
}
];
List<Welcome> hui = welcomeFromJson(json.encode(jsonString));
print(hui[0].courseName[0]);
Try this now
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
void main() {
runApp(new MaterialApp(
home: new HomePage(),
));
}
class HomePage extends StatefulWidget {
#override
HomePageState createState() => new HomePageState();
}
class HomePageState extends State<HomePage> {
List data;
bool isLoading = false;
Future<String> getData({isShowLoading: true}) async {
// refreshKey.currentState?.show(atTop: false);
//await Future.delayed(Duration(seconds: 2));
if (isShowLoading) {
setState(() {
isLoading = true;
});
}
var response = await http.get(
Uri.encodeFull("https://ikns.info/api/nested-array.php"),
headers: {"Accept": "application/json"});
if (response.statusCode == 200) {
if (isShowLoading) {
setState(() {
isLoading = false;
});
}
} else {
// If the server did not return a 200 OK response,
// then throw an exception.
throw Exception('Failed to load album');
}
if (mounted) {
setState(() {
data = jsonDecode(response.body);
});
}
return "Success!";
}
var refreshKey = GlobalKey<RefreshIndicatorState>();
#override
void initState() {
super.initState();
this.getData();
}
Future<Null> _onRefresh() async {
await getData(isShowLoading: false);
}
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("Parsing List of Strings"),
),
body: isLoading
? Center(
child: Text('Loading...'),
)
: RefreshIndicator(
key: refreshKey,
child: new ListView.builder(
itemCount: data == null ? 0 : data.length,
itemBuilder: (BuildContext context, int index) {
List<dynamic> items = data[index]["course_name"];
return GestureDetector(
onTap: () {
Navigator.push(
context,
new MaterialPageRoute(
builder: (context) => DetailsPage(
todo: Todo.fromJson(data[index]),
),
),
);
},
child: new Card(
child: Column(
children: <Widget>[
Container(
child: new Text(data[index]["name"]),
),
Column(
children: List.generate(items.length, (index) {
return Text(
"${items[index]}",
style: TextStyle(color: Colors.red),
);
}),
),
],
),
),
);
},
),
onRefresh: _onRefresh,
),
);
}
}
class Todo {
final String name;
Todo(this.name);
Todo.fromJson(Map<String, dynamic> json) : name = json['name'];
}
class DetailsPage extends StatelessWidget {
final Todo todo;
DetailsPage({Key key, #required this.todo}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: new AppBar(
title: new Text(todo.name),
),
body: Padding(
padding: EdgeInsets.all(16.0),
child: Text(todo.name),
),
);
}
}
UPDATE
OnClick Math, pass Math to the other screen (same for history)
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
void main() {
runApp(new MaterialApp(
home: new HomePage(),
));
}
class HomePage extends StatefulWidget {
#override
HomePageState createState() => new HomePageState();
}
class HomePageState extends State<HomePage> {
List data;
bool isLoading = false;
Future<String> getData({isShowLoading: true}) async {
// refreshKey.currentState?.show(atTop: false);
//await Future.delayed(Duration(seconds: 2));
if (isShowLoading) {
setState(() {
isLoading = true;
});
}
var response = await http.get(
Uri.encodeFull("https://ikns.info/api/nested-array.php"),
headers: {"Accept": "application/json"});
if (response.statusCode == 200) {
if (isShowLoading) {
setState(() {
isLoading = false;
});
}
} else {
// If the server did not return a 200 OK response,
// then throw an exception.
throw Exception('Failed to load album');
}
if (mounted) {
setState(() {
data = jsonDecode(response.body);
});
}
return "Success!";
}
var refreshKey = GlobalKey<RefreshIndicatorState>();
#override
void initState() {
super.initState();
this.getData();
}
Future<Null> _onRefresh() async {
await getData(isShowLoading: false);
}
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("Parsing List of Strings"),
),
body: isLoading
? Center(
child: Text('Loading...'),
)
: RefreshIndicator(
key: refreshKey,
child: new ListView.builder(
itemCount: data == null ? 0 : data.length,
itemBuilder: (BuildContext context, int index) {
List<dynamic> items = data[index]["course_name"];
return new Card(
child: Column(
children: <Widget>[
Container(
child: new Text(data[index]["name"]),
),
Column(
children: List.generate(items.length, (index) {
return GestureDetector(
onTap: () {
Navigator.push(
context,
new MaterialPageRoute(
builder: (context) => DetailsPage(
todo: Todo(items[index].toString()),
),
),
);
},
child: Text(
"${items[index]}",
style: TextStyle(color: Colors.red),
),
);
}),
),
],
),
);
},
),
onRefresh: _onRefresh,
),
);
}
}
class Todo {
final String name;
Todo(this.name);
Todo.fromJson(Map<String, dynamic> json) : name = json['name'];
}
class DetailsPage extends StatelessWidget {
final Todo todo;
DetailsPage({Key key, #required this.todo}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: new AppBar(
title: new Text(todo.name),
),
body: Padding(
padding: EdgeInsets.all(16.0),
child: Text(todo.name),
),
);
}
}

Flutter JSON Nested to Lisview Builder

sorry i have searched on youtube and google but i'm still not getting any clue to parse JSON nested to listview builder.
my json result
[
{
"ID_Type": "1",
"Type": "Food",
"Item": [
{
"SLU_Number": "3",
"SLU_Name": "Food"
}
]
},
{
"ID_Type": "2",
"Type": "Beverages",
"Item": [
{
"SLU_Number": "1",
"SLU_Name": "Non Alcohol"
},
{
"SLU_Number": "2",
"SLU_Name": "Alchohol"
}
]
}
]
i want ID_Type, Type,Item (SLU_Number and SLU Name) throw all value to Listview.builder
thank you.
my code on flutter, i follow some code on youtube and that throw the value to List but i don't how to throw the value to Listview.builder
class Products {
final ID_Type;
final Name_Type;
final Items;
Products({
this.ID_Type,
this.Name_Type,
this.Items,
});
factory Products.fromJson(Map<String, dynamic> json) {
return Products(
ID_Type: json["ID_Type"],
Name_Type: json["Type"],
Items: Item.fromJson(json["Item"]),
);
}
}
class Item {
final SLU_Number;
final SLU_Name;
Item({
this.SLU_Number,
this.SLU_Name,
});
factory Item.fromJson(Map<String, dynamic> json) {
return Item(
SLU_Number: json["SLU_Number"],
SLU_Name: json["SLU_Name"],
);
}
}
here below is my Future to throw all the "json" result to List
//------------------------------Start Syntax for List SLU
final listslu = new List<ListSLU>();
final GlobalKey<RefreshIndicatorState> _refreshlistslu =
GlobalKey<RefreshIndicatorState>();
Future<void> ListSLUs() async {
listslu.clear();
setState(() {
loading = true;
});
try {
final response = await http.get(BaseUrl.ListSLU);
if (response.contentLength == 2) {
} else {
final data = jsonDecode(response.body);
data.forEach((api) {
final b = new ListSLU(
api['ID_Type'].toString(),
api['SLU_Number'].toString(),
api['SLU_Name'].toString(),
);
listslu.add(b);
print(api['SLU_Name'].toString());
});
}
} catch (e) {
print("Error List SLU :");
print(e);
}
}
//------------------------------End Syntax for List Type
after parsing all json result and then all value from json i throw to body
Expanded(
flex: 2,
child: ListView.builder(
itemCount: listslu.length,
itemBuilder: (context,i){
final z = listslu[i];
return GestureDetector(
onTap: (){
},
child: Container(
child: Column(
children: <Widget>[
Row(
children: <Widget>[
Row(
children: <Widget>[
Text(z.SLU_Number +' - '+ z.SLU_Name),
],
),
],
)
],
),
),
);
}
)
),

type _InternalLinkedHashMap<String, dynamic> is not subtype of type List<dynamic>

I am trying to implement a simple news feed app using network call wherein the screen will show the latest stories in a Listview.
With the current code, I am getting a response back from the API (as I see the entire response body in the log) but can't seem to display the data in the UI. I am getting this error :
type _InternalLinkedHashMap<String, dynamic> is not subtype of type List
This is the JSON structure
{
"response": {
"status": "ok",
"userTier": "developer",
"total": 25095,
"startIndex": 1,
"pageSize": 10,
"currentPage": 1,
"pages": 2510,
"orderBy": "relevance",
"results": [
{
"id": "australia-news/2018/aug/13/turnbulls-energy-policy-hangs-in-the-balance-as-euthanasia-debate-given-precedence",
"type": "article",
"sectionId": "australia-news",
"sectionName": "Australia news",
"webPublicationDate": "2018-08-12T18:00:08Z",
"webTitle": "Energy policy hangs in balance, as Senate debates euthanasia",
"webUrl": "https://www.theguardian.com/australia-news/2018/aug/13/turnbulls-energy-policy-hangs-in-the-balance-as-euthanasia-debate-given-precedence",
"apiUrl": "https://content.guardianapis.com/australia-news/2018/aug/13/turnbulls-energy-policy-hangs-in-the-balance-as-euthanasia-debate-given-precedence",
"isHosted": false,
"pillarId": "pillar/news",
"pillarName": "News"
}, {
"id": "media/2018/jun/13/the-rev-colin-morris-obituary-letter",
"type": "article",
"sectionId": "media",
For my understanding, I just want to first display webTitle in the list, and later add other fields (after I understand the network concept clearly), but getting the error mentioned above. This is my complete code :
class MyApp extends StatelessWidget{
#override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Network Example',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new Scaffold(
appBar: AppBar(
title: new Text('Network Example'),
),
body: new Container(
child: new FutureBuilder<List<News>> (
future: fetchNews(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return new ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
return new Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
new Text(snapshot.data[index].newsTitle,
style: new TextStyle(
fontWeight: FontWeight.bold)
),
new Divider()
],
);
}
);
} else if (snapshot.hasError) {
return new Text("${snapshot.error}");
}
return CircularProgressIndicator();
},
),
),
),
);
}
Future<List<News>> fetchNews() async {
final response = await http.get('https://content.guardianapis.com/search?q=debates&api-key=');
print(response.body);
List responseJson = json.decode(response.body.toString());
List<News> newsTitle = createNewsList(responseJson);
return newsTitle;
}
List<News> createNewsList(List data) {
List<News> list = new List();
for (int i = 0; i< data.length; i++) {
String title = data[i]['webTitle'];
News news = new News(
newsTitle: title);
list.add(news);
}
return list;
}
}
class News {
final String newsTitle;
News({this.newsTitle});
factory News.fromJson(Map<String, dynamic> json) {
return new News(
newsTitle: json['webTitle'],
);
}
}
I looked at similar questions before and also went through json structures articles but can't seem to figure out how to resolve this issue.
The problem is, your JSON is not an array. It is an object. But you tried to use it as an array.
You may want to change your createNewsList call to the following:
List responseJson = json.decode(response.body.toString());
List<News> newsTitle = createNewsList(responseJson["response"]["results"]);
Mybe you can try modify this method, like this :
Future<List<News>> fetchNews() async {
final response = await http.get('https://content.guardianapis.com/search?q=debates&api-key=');
print(response.body);
List responseJson = json.decode(response.body.result);
List<News> newsTitle = createNewsList(responseJson);
return newsTitle;
}
You can use this
Map<String, String> stringParams = {};
Or
var stringParams = <String, String>{};