Flutter show api data using POST - flutter

Hi need help to show my API data into Text.
I already get the response but I don't know how to turn it into text which it will show at the screen.. now the data are shows at the terminal.
This is my codes:
class carList extends StatefulWidget {
const carList({Key? key}) : super(key: key);
#override
State<carList> createState() => _carListState();
}
class _carListState extends State<carList> {
var userController = TextEditingController();
var apiController = TextEditingController();
final pref = Pref();
#override
void initState() {
MySharedPreferences().getUserId().then((value) {
setState(() {
userController.text = value.toString();
});
});
MySharedPreferences().getUserToken().then((value) {
setState(() {
apiController.text = value.toString();
});
});
//TODO: IMPLEMENT INITSTATE
}
this is where I want to show my API data
#override
Widget build(BuildContext context) {
return Scaffold(
body: ListView(
children: <Widget>[
Container(
padding: const EdgeInsets.all(10),
child: TextField(
controller: userController,
decoration: const InputDecoration(
border: OutlineInputBorder(),
suffixIcon: Icon(Icons.email),
labelText: 'User ID',
),
),
),
Container(
padding: const EdgeInsets.all(10),
child: TextField(
controller: apiController,
decoration: const InputDecoration(
border: OutlineInputBorder(),
suffixIcon: Icon(Icons.email),
labelText: 'Token',
),
),
),
Container(
margin: EdgeInsets.all(25),
child: TextButton(
child: Text('Show Car List',
style: TextStyle(fontSize: 20.0,
color: Colors.blueAccent,
backgroundColor: Colors.white),
),
onPressed: () {
list();
},
),
)
]
)
);
}
this is my API response
void list() async {
{
var response = await http.post(
Uri.parse("http://servisjer.me-tech.com.my/api/Car/GetUserCar"),
body: ({
'user_id': userController.text,
'token': apiController.text,
'device': "Android",
}));
if (response.statusCode == 200) {
final body = jsonDecode(response.body);
print(apiController.text);
print(body.toString());
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: Text("Successfully Login")));
}
}
}
}
This page that I want to show my data.
this is my log response
{
"Status": "OK",
"Message": "Senarai maklumat kereta.",
"Details": [
{
"car_id": 184,
"user_id": 141,
"manufacturer_id": 21,
"name": "Akma",
"registration_no": "ws 3345",
"model_name": "Bezza",
"production_year": 2022,
"notes": null,
"date_purchased": "2022-08-10",
"image":
" http://servisjer.me-tech.com.my/admin/storage/app/media/userplugin/7PyVIp8iwb.png"
}
]
}

Best way to use API response data is to create model from https://app.quicktype.io/ (copy your response and paste on this link and select language dart) and use as per your requirement.
I create model with name "GetUserCarModel" from your API response and use like this way.
Future<void> list() async {
{
var response = await http.post(
Uri.parse("http://servisjer.me-tech.com.my/api/Car/GetUserCar"),
body: ({
'user_id': userController.text,
'token': apiController.text,
'device': "Android",
})
);
if (response.statusCode == 200) {
final body = jsonDecode(response.body);
GetUserCarModel getUserCarModel = GetUserCarModel.fromJson(body);
print("getUserCarModel ===> ${getUserCarModel.toString()}");
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text("Successfully Login")));
}
}
}

First of all you have to crate a model class of your response.
import 'dart:convert';
CarDetailResponse carDetailResponseFromJson(String str) => CarDetailResponse.fromJson(json.decode(str));
String carDetailResponseToJson(CarDetailResponse data) => json.encode(data.toJson());
class CarDetailResponse {
CarDetailResponse({
this.status,
this.message,
this.details,
});
String? status;
String? message;
List<Detail>? details;
factory CarDetailResponse.fromJson(Map<String, dynamic> json) => CarDetailResponse(
status: json["Status"],
message: json["Message"],
details: List<Detail>.from(json["Details"].map((x) => Detail.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"Status": status,
"Message": message,
"Details": List<dynamic>.from(details!.map((x) => x.toJson())),
};
}
class Detail {
Detail({
this.carId,
this.userId,
this.manufacturerId,
this.name,
this.registrationNo,
this.modelName,
this.productionYear,
this.notes,
this.datePurchased,
this.image,
});
int? carId;
int? userId;
int? manufacturerId;
String? name;
String? registrationNo;
String? modelName;
int? productionYear;
dynamic notes;
DateTime? datePurchased;
String? image;
factory Detail.fromJson(Map<String, dynamic> json) => Detail(
carId: json["car_id"],
userId: json["user_id"],
manufacturerId: json["manufacturer_id"],
name: json["name"],
registrationNo: json["registration_no"],
modelName: json["model_name"],
productionYear: json["production_year"],
notes: json["notes"],
datePurchased: DateTime.parse(json["date_purchased"]),
image: json["image"],
);
Map<String, dynamic> toJson() => {
"car_id": carId,
"user_id": userId,
"manufacturer_id": manufacturerId,
"name": name,
"registration_no": registrationNo,
"model_name": modelName,
"production_year": productionYear,
"notes": notes,
"date_purchased": "${datePurchased!.year.toString().padLeft(4, '0')}-${datePurchased!.month.toString().padLeft(2, '0')}-${datePurchased!.day.toString().padLeft(2, '0')}",
"image": image,
};
}
you can make this model class with the help of app.quicktype.io
then after getting response, assign the response.body to this model class object
void list() async {
{
var response = await http.post(
Uri.parse("http://servisjer.me-tech.com.my/api/Car/GetUserCar"),
body: ({
'user_id': userController.text,
'token': apiController.text,
'device': "Android",
}));
if (response.statusCode == 200) {
final body = jsonDecode(response.body);
setState(() {
carDetailResponse =
carDetailResponseFromJson(body);
});
print(apiController.text);
print(body.toString());
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: Text("Successfully Login")));
}
}
}
}
then at UI use this model class to show data. Like -
class CarDetailScreen extends StatefulWidget {
const CarDetailScreen({Key? key}) : super(key: key);
#override
State<CarDetailScreen> createState() => _CarDetailScreenState();
}
class _CarDetailScreenState extends State<CarDetailScreen> {
CarDetailResponse? carDetailResponse;
#override
Widget build(BuildContext context) {
return Scaffold(
body: ListView(children: <Widget>[
Container(
padding: const EdgeInsets.all(10),
child: TextField(
controller: userController,
decoration: const InputDecoration(
border: OutlineInputBorder(),
suffixIcon: Icon(Icons.email),
labelText: 'User ID',
),
),
),
Container(
padding: const EdgeInsets.all(10),
child: TextField(
controller: apiController,
decoration: const InputDecoration(
border: OutlineInputBorder(),
suffixIcon: Icon(Icons.email),
labelText: 'Token',
),
),
),
Container(
margin: EdgeInsets.all(25),
child: TextButton(
child: Text(
'Show Car List',
style: TextStyle(fontSize: 20.0, color: Colors.blueAccent, backgroundColor: Colors.white),
),
onPressed: () {
list();
},
),
),
carDetailResponse != null
? Expanded(
child: ListView.builder(
shrinkWrap: true,
physics: const ClampingScrollPhysics(),
itemCount: carDetailResponse!.details!.length,
itemBuilder: (context, index) {
var car = carDetailResponse!.details![index];
return Text(car.name ?? '');
},
),
)
: const SizedBox()
]));
}
}

assuming this is valid response :
{
"Status":"OK",
"Message":"Sena.",
"Details":[
{
"car_id":184,
"user_id":141,
"manufacturer_id":21,
"name":"Akma",
"registration_no":"ws 3345",
"model_name":"Bezza",
"production_year":2022,
"notes":null,
"date_purchased":"2022-08-10",
"image":"http://servisjer.me-tech.com.my/admin/storage/app/media/userplugin/7PyVIp8iwb.png"
}
]
}
then to get save the details is a list so you have to loop through the list i.e
if(body["Status"]=="OK")
{
List<Detail> allRecord;
final parsed = json.decode(body).cast<Map<String, dynamic>>();
allRecord = parsed .map<Detail>((json) => Detail.fromJson(json)).toList();
}
here is your model :
// To parse this JSON data, do
//
// final responseModel = responseModelFromJson(jsonString);
import 'dart:convert';
ResponseModel responseModelFromJson(String str) => ResponseModel.fromJson(json.decode(str));
String responseModelToJson(ResponseModel data) => json.encode(data.toJson());
class ResponseModel {
ResponseModel({
this.status,
this.message,
this.details,
});
String status;
String message;
List<Detail> details;
factory ResponseModel.fromJson(Map<String, dynamic> json) => ResponseModel(
status: json["Status"],
message: json["Message"],
details: List<Detail>.from(json["Details"].map((x) => Detail.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"Status": status,
"Message": message,
"Details": List<dynamic>.from(details.map((x) => x.toJson())),
};
}
class Detail {
Detail({
this.carId,
this.userId,
this.manufacturerId,
this.name,
this.registrationNo,
this.modelName,
this.productionYear,
this.notes,
this.datePurchased,
this.image,
});
int carId;
int userId;
int manufacturerId;
String name;
String registrationNo;
String modelName;
int productionYear;
dynamic notes;
DateTime datePurchased;
String image;
factory Detail.fromJson(Map<String, dynamic> json) => Detail(
carId: json["car_id"],
userId: json["user_id"],
manufacturerId: json["manufacturer_id"],
name: json["name"],
registrationNo: json["registration_no"],
modelName: json["model_name"],
productionYear: json["production_year"],
notes: json["notes"],
datePurchased: DateTime.parse(json["date_purchased"]),
image: json["image"],
);
Map<String, dynamic> toJson() => {
"car_id": carId,
"user_id": userId,
"manufacturer_id": manufacturerId,
"name": name,
"registration_no": registrationNo,
"model_name": modelName,
"production_year": productionYear,
"notes": notes,
"date_purchased": "${datePurchased.year.toString().padLeft(4, '0')}-${datePurchased.month.toString().padLeft(2, '0')}-${datePurchased.day.toString().padLeft(2, '0')}",
"image": image,
};
}
Worst Approach : use a for each to loop through if you are sure the Details array has only one object i.e
for (var data in details)
{
debugPrint(data.model_name);
debugPrint(data.registration_no);
//and many more
}

Related

futurebuilder information not showing on actual mobile phone

hey im building a application which shows some information about certain things and this one certain widget does not show any type of information and just returns a white screen, this was no problem at first since i only really tested in on my emulator (Which worked everytime) but now that i downloaded the APK it only shows a white screen. i have used
<uses-permission android:name="android.permission.INTERNET" />
in my aindroidmanifest file.
my code:
Main.dart
class AllChampionsListedRoute extends StatefulWidget {
String summonerId, summonerName;
AllChampionsListedRoute(this.summonerId, this.summonerName);
#override
State<StatefulWidget> createState() {
return _AllChampionsListedRouteState(this.summonerId, this.summonerName);
}
}
class _AllChampionsListedRouteState extends State<AllChampionsListedRoute> {
TextEditingController editingController = TextEditingController();
var items = <String>[];
List<String> allChampListUncapitalized = [];
String summonerId, summonerName;
_AllChampionsListedRouteState(this.summonerId, this.summonerName);
#override
void initState() {
super.initState();
for (var champ in allChampList) {
allChampListUncapitalized.add(champ.toLowerCase());
items.add(champ.toLowerCase());
}
}
void filterSearchResults(String query) {
List<String> dummySearchList = <String>[];
dummySearchList.addAll(allChampListUncapitalized);
if(query.isNotEmpty) {
List<String> dummyListData = <String>[];
dummySearchList.forEach((item) {
if(item.contains(query)) {
dummyListData.add(item);
}
});
setState(() {
items.clear();
items.addAll(dummyListData);
});
return;
} else {
setState(() {
items.clear();
items.addAll(allChampListUncapitalized);
});
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: customAppBar(),
body: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.centerLeft,
end: Alignment.centerRight,
colors: [
bgColorFront,
bgColorEnd,
],
),
),
child: Center(
child: Expanded(
child: FutureBuilder<Champions>(
future: getChampions(), // a previously-obtained Future<String> or null
builder: (BuildContext context, AsyncSnapshot<Champions> snapshotChamps) {
if (snapshotChamps.hasData) {
return Column(
children: [
TextField(
onChanged: (value) {
filterSearchResults(value);
},
inputFormatters: [
UpperCaseTextFormatter(),
],
controller: editingController,
style: TextStyle(
color: customColorGray,
fontSize: 20,
),
decoration: new InputDecoration(
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: customColorDarkBlue, width: 2.0),
),
labelText: 'Champion',
labelStyle: TextStyle(
color: customColorTextBlue,
fontFamily: 'Spiegel',
fontSize: 20,
),
hintText: 'Fill in your champion here',
hintStyle: TextStyle(
color: customColorTextBlue,
fontFamily: 'Spiegel',
fontSize: 20,
),
),
maxLines: null,
),
Expanded(
child: ListView.builder(
shrinkWrap: true,
itemCount: items.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(
'${capitalize(items[index])}',
style: TextStyle(
fontSize: 25,
),
),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SummonerMasteryRoute(
snapshotChamps.data!.data["${capitalize(items[index])}"]!.key, capitalize(items[index]),
summonerId, snapshotChamps.data!.data["${capitalize(items[index])}"]!.image.full, summonerName
)),
);
},
);
},
),
)
],
);
} else if (snapshotChamps.hasError) {
return Text('Error: ${snapshotChamps.error}');
} else {
return SizedBox(
width: 60,
height: 60,
child: CircularProgressIndicator(),
);
}
},
),
)
),
),
);
}
}
Remoteservice.dart:
Future<Champions> getChampions() async {
String link = 'http://ddragon.leagueoflegends.com/cdn/12.22.1/data/en_US/champion.json';
final response = await http
.get(Uri.parse(link));
if (response.statusCode == 200) {
return Champions.fromJson(jsonDecode(response.body));
} else {
return throw Exception('Failed to load album');
}
}
champion.dart (class):
import 'dart:convert';
Champions championsFromJson(String str) => Champions.fromJson(json.decode(str));
String championsToJson(Champions data) => json.encode(data.toJson());
class Champions {
Champions({
required this.type,
required this.format,
required this.version,
required this.data,
});
Type? type;
String format;
Version? version;
Map<String, ChampData> data;
factory Champions.fromJson(Map<String, dynamic> json) => Champions(
type: typeValues.map[json["type"]],
format: json["format"],
version: versionValues.map[json["version"]],
data: Map.from(json["data"]).map((k, v) => MapEntry<String, ChampData>(k, ChampData.fromJson(v))),
);
Map<String, dynamic> toJson() => {
"type": typeValues.reverse?[type],
"format": format,
"version": versionValues.reverse?[version],
"data": Map.from(data).map((k, v) => MapEntry<String, dynamic>(k, v.toJson())),
};
}
class ChampData {
ChampData({
required this.version,
required this.id,
required this.key,
required this.name,
required this.title,
required this.blurb,
required this.info,
required this.image,
required this.tags,
required this.partype,
required this.stats,
});
Version? version;
String id;
String key;
String name;
String title;
String blurb;
Info info;
ChampImage image;
List<Tag> tags;
String partype;
Map<String, double> stats;
factory ChampData.fromJson(Map<String, dynamic> json) => ChampData(
version: versionValues.map[json["version"]],
id: json["id"],
key: json["key"],
name: json["name"],
title: json["title"],
blurb: json["blurb"],
info: Info.fromJson(json["info"]),
image: ChampImage.fromJson(json["image"]),
tags: List<Tag>.from(json["tags"].map((x) => tagValues.map[x])),
partype: json["partype"],
stats: Map.from(json["stats"]).map((k, v) => MapEntry<String, double>(k, v.toDouble())),
);
Map<String, dynamic> toJson() => {
"version": versionValues.reverse?[version],
"id": id,
"key": key,
"name": name,
"title": title,
"blurb": blurb,
"info": info.toJson(),
"image": image.toJson(),
"tags": List<dynamic>.from(tags.map((x) => tagValues.reverse?[x])),
"partype": partype,
"stats": Map.from(stats).map((k, v) => MapEntry<String, dynamic>(k, v)),
};
}
class ChampImage {
ChampImage({
required this.full,
required this.sprite,
required this.group,
required this.x,
required this.y,
required this.w,
required this.h,
});
String full;
Sprite? sprite;
Type? group;
int x;
int y;
int w;
int h;
factory ChampImage.fromJson(Map<String, dynamic> json) => ChampImage(
full: json["full"],
sprite: spriteValues.map[json["sprite"]],
group: typeValues.map[json["group"]],
x: json["x"],
y: json["y"],
w: json["w"],
h: json["h"],
);
Map<String, dynamic> toJson() => {
"full": full,
"sprite": spriteValues.reverse?[sprite],
"group": typeValues.reverse?[group],
"x": x,
"y": y,
"w": w,
"h": h,
};
}
enum Type { CHAMPION }
final typeValues = EnumValues({
"champion": Type.CHAMPION
});
enum Sprite { CHAMPION0_PNG, CHAMPION1_PNG, CHAMPION2_PNG, CHAMPION3_PNG, CHAMPION4_PNG, CHAMPION5_PNG }
final spriteValues = EnumValues({
"champion0.png": Sprite.CHAMPION0_PNG,
"champion1.png": Sprite.CHAMPION1_PNG,
"champion2.png": Sprite.CHAMPION2_PNG,
"champion3.png": Sprite.CHAMPION3_PNG,
"champion4.png": Sprite.CHAMPION4_PNG,
"champion5.png": Sprite.CHAMPION5_PNG
});
class Info {
Info({
required this.attack,
required this.defense,
required this.magic,
required this.difficulty,
});
int attack;
int defense;
int magic;
int difficulty;
factory Info.fromJson(Map<String, dynamic> json) => Info(
attack: json["attack"],
defense: json["defense"],
magic: json["magic"],
difficulty: json["difficulty"],
);
Map<String, dynamic> toJson() => {
"attack": attack,
"defense": defense,
"magic": magic,
"difficulty": difficulty,
};
}
enum Tag { FIGHTER, TANK, MAGE, ASSASSIN, MARKSMAN, SUPPORT }
final tagValues = EnumValues({
"Assassin": Tag.ASSASSIN,
"Fighter": Tag.FIGHTER,
"Mage": Tag.MAGE,
"Marksman": Tag.MARKSMAN,
"Support": Tag.SUPPORT,
"Tank": Tag.TANK
});
enum Version { THE_12221 }
final versionValues = EnumValues({
"12.22.1": Version.THE_12221
});
class EnumValues<T> {
Map<String, T> map;
Map<T, String>? reverseMap;
EnumValues(this.map);
Map<T, String>? get reverse {
if (reverseMap == null) {
reverseMap = map.map((k, v) => new MapEntry(v, k));
}
return reverseMap;
}
}
This is how it was supposed to look (and how it looks on my emulator):

FormatException:unexpected Character flutter

i tried to decode my json and take the values to futurebuilder in flutter when decode my json appear formatexception:unexpectedcharacter,tried to storage in a String and in List, think my error think is how to toke data,how to storage my json decode,
Thanks
my code
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:oauth2_client/spotify_oauth2_client.dart';
import 'package:ui/Models/segundapantalla.dart';
import 'newmodel.dart';
class callttoappi {
Future getatatodapi() async {
String url =
'https://api.spotify.com/v1/playlists/37i9dQZF1DXcBWIGoYBM5M/tracks';
var client = SpotifyOAuth2Client(
redirectUri: 'com.example.ui://callback',
customUriScheme: 'com.example.ui');
var tknResp = await client.getTokenWithAuthCodeFlow(
clientId: 'client id',
scopes: [
'user-read-email',
'user-read-private',
]);
if (tknResp != null) {
var headers = {
'Authorization': 'Bearer ${tknResp.accessToken}',
};
var request = await http.Request(
'GET', Uri.parse('https://api.spotify.com/v1/browse/new-releases'));
request.headers.addAll(headers);
http.StreamedResponse response =
await request.send().timeout(const Duration(seconds: 20));
if (response.statusCode == 200) {
//String reponsedata = await response.stream.bytesToString();
//print(await response.stream.bytesToString());
Map<String, dynamic> userMap = jsonDecode(await response.stream.bytesToString());
var user = Item.fromJson(userMap);
print(userMap);
//Map<String,dynamic> json = jsonDecode(await response.stream.bytesToString());
//print(json);
return Item.fromJson(jsonDecode(json.toString()));
} else {
print(response.reasonPhrase);
}
}
}
}
my model class,quicktype website or another page this like github projects to obtain my json
class Newmodel {
Newmodel({
required this.albums,
});
final Albums? albums;
factory Newmodel.fromJson(Map<String, dynamic> json){
return Newmodel(
albums: json["albums"] == null ? null : Albums.fromJson(json["albums"]),
);
}
Map<String, dynamic> toJson() => {
"albums": albums?.toJson(),
};
#override
String toString(){
return '$albums';
}
}
class Albums {
Albums({
required this.href,
required this.items,
required this.limit,
required this.next,
required this.offset,
required this.previous,
required this.total,
});
final String? href;
final List<Item> items;
final int? limit;
final String? next;
final int? offset;
final dynamic previous;
final int? total;
factory Albums.fromJson(Map<String, dynamic> json){
return Albums(
href: json["href"],
items: json["items"] == null ? [] : List<Item>.from(json["items"]!.map((x) => Item.fromJson(x))),
limit: json["limit"],
next: json["next"],
offset: json["offset"],
previous: json["previous"],
total: json["total"],
);
}
Map<String, dynamic> toJson() => {
"href": href,
"items": List<Item>.from(items.map((x) => x.toJson())),
"limit": limit,
"next": next,
"offset": offset,
"previous": previous,
"total": total,
};
#override
String toString(){
return '$href, $items, $limit, $next, $offset, $previous, $total';
}
}
class Item {
Item({
required this.albumType,
required this.artists,
required this.availableMarkets,
required this.externalUrls,
required this.href,
required this.id,
required this.images,
required this.name,
required this.releaseDate,
required this.releaseDatePrecision,
required this.totalTracks,
required this.type,
required this.uri,
});
final String? albumType;
final List<Artist> artists;
final List<String> availableMarkets;
final ExternalUrls? externalUrls;
final String? href;
final String? id;
final List<Image> images;
final String? name;
final DateTime? releaseDate;
final String? releaseDatePrecision;
final int? totalTracks;
final String? type;
final String? uri;
factory Item.fromJson(Map<String, dynamic> json){
return Item(
albumType: json["album_type"],
artists: json["artists"] == null ? [] : List<Artist>.from(json["artists"]!.map((x) => Artist.fromJson(x))),
availableMarkets: json["available_markets"] == null ? [] : List<String>.from(json["available_markets"]!.map((x) => x)),
externalUrls: json["external_urls"] == null ? null : ExternalUrls.fromJson(json["external_urls"]),
href: json["href"],
id: json["id"],
images: json["images"] == null ? [] : List<Image>.from(json["images"]!.map((x) => Image.fromJson(x))),
name: json["name"],
releaseDate: json["release_date"] == null ? null : DateTime.parse(json["release_date"]),
releaseDatePrecision: json["release_date_precision"],
totalTracks: json["total_tracks"],
type: json["type"],
uri: json["uri"],
);
}
Map<String, dynamic> toJson() => {
"album_type": albumType,
"artists": List<Artist>.from(artists.map((x) => x.toJson())),
"available_markets": List<String>.from(availableMarkets.map((x) => x)),
"external_urls": externalUrls?.toJson(),
"href": href,
"id": id,
"images": List<Image>.from(images.map((x) => x.toJson())),
"name": name,
//"release_date": "${releaseDate.year.toString().padLeft(4'0')}-${releaseDate.month.toString().padLeft(2'0')}-${releaseDate.day.toString().padLeft(2'0')}",
"release_date_precision": releaseDatePrecision,
"total_tracks": totalTracks,
"type": type,
"uri": uri,
};
#override
String toString(){
return '$albumType, $artists, $availableMarkets, $externalUrls, $href, $id, $images, $name, $releaseDate, $releaseDatePrecision, $totalTracks, $type, $uri';
}
}
viewpage class
class lodeo extends StatefulWidget {
#override
State<lodeo> createState() => _WeatherPageState();
}
class _WeatherPageState extends State<lodeo> {
Future getData() async {
return await callttoappi().getatatodapi();
}
Future<dynamic>? _myData;
#override
void initState() {
setState(() {
_myData = getData();
});
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: FutureBuilder(
builder: (ctx, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
// If error occured
if (snapshot.hasError) {
return Center(
child: Text(
'${snapshot.error.toString()} occurred',
style: TextStyle(fontSize: 18),
),
);
// if data has no errors
} else if (snapshot.hasData) {
// Extracting data from snapshot object
final data = snapshot.data as Item;
return Container(
padding: EdgeInsets.symmetric(horizontal: 15, vertical: 10),
decoration: const BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment(0.8, 1),
colors: <Color>[
Color.fromARGB(255, 65, 89, 224),
Color.fromARGB(255, 83, 92, 215),
Color.fromARGB(255, 86, 88, 177),
Color(0xfff39060),
Color(0xffffb56b),
],
tileMode: TileMode.mirror,
),
),
width: double.infinity,
height: double.infinity,
child: SafeArea(
child: Column(
children: [
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
data.albumType.toString(),
style: TextStyle(
fontSize: 30,
color: Colors.white,
fontWeight: FontWeight.bold),
),
Text(
data.id.toString(),
style: TextStyle(
fontSize: 20,
color: Colors.white,
fontWeight: FontWeight.bold),
),
Text(
data.name.toString(),
style: TextStyle(
fontSize: 50,
color: Colors.white,
fontWeight: FontWeight.bold),
),
],
),
),
],
),
),
);
}
} else if (snapshot.connectionState == ConnectionState.waiting) {
return Center(
child: CircularProgressIndicator(),
);
} else {
return Center(
child: Text("${snapshot.connectionState} occured"),
);
}
return Center(
child: Text("Server timed out!"),
);
},
future: _myData!,
),
);
}
enter code here

NoSuchMethodError: The method '[]' was called on null in GET request in Flutter

I'm trying to display a list from api with GET request. But it keeps showing this error:
NoSuchMethodError: The method '[]' was called on null.
Receiver: null
Tried calling: []("depId")
The thing is I don't use depId at all for this request and it's not even in the object that I'm using to make this request so I don't know from where it gets null value because when I use it in my previous request it works totally fine.
Here is the API request
static Future<List<Athlete>> getAthletesByTeamKey(
int depId, int teamId) async {
try {
final response = await http.get(
Uri.parse(
'$uri/get-athletes-by-team-key?depId=$depId&teamId=$teamId&page=0&length=50'),
headers: {
'Authorization': 'Basic ...',
'Content-Type': 'application/json',
'Accept': 'application/json'
});
print('Response status: ${response.statusCode}');
print('Response body: ${response.body}');
if (response.statusCode == 200) {
if (response.body.isNotEmpty) {
print('response.body.isNotEmpty');
List jsonResponse = json.decode(utf8.decode(response.bodyBytes));
return jsonResponse
.map((athlete) => Athlete.fromJson(athlete))
.toList();
} else if (response.body.isEmpty) {
print('response.body.isEmpty');
throw Exception();
}
}
} catch (e) {
print('catch');
logger.e(e.toString());
}
return getAthletesByTeamKey(depId, teamId, context);
}
It prints the print('response.body.isNotEmpty');and then it goes into catch
My Athlete object
List<Athlete> athleteFromJson(String str) =>
List<Athlete>.from(json.decode(str).map((x) => Athlete.fromJson(x)));
String athleteToJson(List<Athlete> data) =>
json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
class Athlete {
late int id;
late String firstName;
late String lastName;
late String fatherName;
late int currentMonthPresences;
late bool isSelected = false;
late bool hasDebt;
Department? department;
Team? team;
Athlete(
{required this.id,
required this.firstName,
required this.lastName,
required this.fatherName,
required this.currentMonthPresences,
this.isSelected = false,
required this.hasDebt,
this.department,
this.team});
Athlete.newSelectedAthlete(this.id, this.department, this.team); //I use it for another screen
factory Athlete.fromJson(Map<String, dynamic> json) => Athlete(
id: json['id'],
firstName: json['firstName'],
lastName: json['lastName'],
fatherName: json['fatherName'],
currentMonthPresences: json['currentMonthPresences'],
hasDebt: json['hasDebt'],
department: Department.fromJson(json['department']),
team: Team.fromJson(json['team']),
);
Map<String, dynamic> toJson() => {
'id': id,
'firstName': firstName,
'lastName': lastName,
'fatherName': fatherName,
'currentMonthPresences': currentMonthPresences,
'isSelected': isSelected,
'hasDebt': hasDebt,
'department': department,
'team': team,
};
}
Department object
class Department {
int id;
String depName;
Department({required this.id, required this.depName});
factory Department.fromJson(Map<String, dynamic> json) => Department(
id: json['id'],
depName: json['depName'],
);
Map<String, dynamic> toJson() => {
"id": id,
"depName": depName,
};
}
Team object
class Team {
final TeamKey teamKey;
final String teamName;
final int hidden;
final User user;
final String depName;
Team(
{required this.teamKey,
required this.teamName,
required this.hidden,
required this.user,
required this.depName});
factory Team.fromJson(Map<String, dynamic> json) => Team(
teamKey: TeamKey.fromJson(json['teamKey']),
teamName: json['teamName'],
hidden: json['hidden'],
user: User.fromJson(json['user']),
depName: json['depName'],
);
Map<String, dynamic> toJson() => {
'teamKey': teamKey,
'teamName': teamName,
'hidden': hidden,
'user': user,
'depName': depName,
};
}
and the TeamKey object that has the variable depId but I don't use it at all
class TeamKey {
int depId;
int teamId;
TeamKey({required this.depId, required this.teamId});
factory TeamKey.fromJson(Map<String, dynamic> json) => TeamKey(
depId: json['depId'],
teamId: json['teamId'],
);
Map<String, dynamic> toJson() => {
"depId": depId,
"teamId": teamId,
};
}
The screen I'm trying to display my list
class AthleteScreen extends StatefulWidget {
const AthleteScreen(this._team, {Key? key}) : super(key: key);
final Team _team;
#override
State<AthleteScreen> createState() => _AthleteScreenState();
}
class _AthleteScreenState extends State<AthleteScreen> {
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
final myController = TextEditingController();
final controller = TextEditingController();
Future<List<Athlete>>? futureAthletebyTeamKey;
Future<List<Presence>>? futureGetPresences;
final List<Athlete> _athlete = [];
#override
void initState() {
futureAthletebyTeamKey = ApiService.getAthletesByTeamKey();
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
body: Stack(
children: [
SingleChildScrollView(
child: Column(children: [
const SizedBox(
height: 10,
),
FutureBuilder<List<Athlete>>(
future: futureAthletebyTeamKey,
builder: (context, AsyncSnapshot snapshot) {
if (snapshot.hasData) {
List<Athlete> _athlete = snapshot.data;
return ListView.builder(
shrinkWrap: true,
cacheExtent: 34,
primary: true,
physics: const ClampingScrollPhysics(),
padding: const EdgeInsets.only(
top: 10,
bottom: 56,
),
itemCount: _athlete.length,
itemBuilder: (BuildContext context, int i) {
return CheckboxListTile(
title: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Text(
'ID: ${_athlete[i].id}',
style: const TextStyle(
color: Colors.blue, fontSize: 14),
),
const SizedBox(
width: 5,
),
],
),
Row(
children: [
Flexible(
child: Text(
'${_athlete[i].lastName} ${_athlete[i].firstName}',
style: const TextStyle(
color: Colors.black,
fontFamily: 'Cera',
fontWeight: FontWeight.bold,
fontSize: 18),
),
),
],
),
const SizedBox(
height: 5,
),
});
} else if (snapshot.hasError) {
logger.e('${snapshot.error}');
}
return const Center(
heightFactor: 20,
child: CircularProgressIndicator.adaptive(),
);
},
),
]),
),
Align(
alignment: Alignment.bottomCenter,
child: Container(
width: double.infinity,
height: 60,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
disabledBackgroundColor: Colors.grey),
onPressed: () async {
Navigator.of(context).pushNamed(
SelectedAthletes.routeName,
arguments: selectedAthlete.toList());
}),
child: Column(
children: [
const Text(
'ΝΕΧΤ',
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.white,
fontSize: 18),
),
],
),
),
),
),
],
),
);
}
}
I'll be very thankful if someone took time to help me! Thanks in advance!
You actually use depId.
So let's follow along with your JSON.
When you decode the athlete you do:
factory Athlete.fromJson(Map<String, dynamic> json) => Athlete(
...
department: Department.fromJson(json['department']),
team: Team.fromJson(json['team']),
);
So the Athlete.fromJson() is calling Team.fromJson(). Let's look at it
factory Team.fromJson(Map<String, dynamic> json) => Team(
teamKey: TeamKey.fromJson(json['teamKey']),
...
);
Team.fromJson() iscalling TeamKey.fromJson(). Let's look at that.
factory TeamKey.fromJson(Map<String, dynamic> json) => TeamKey(
depId: json['depId'],
teamId: json['teamId'],
);
TeamKey.fromJson() wants the 'depId'.
Your JSON should look like:
team: {
teamKey: {
depId: ...
}
}
Double check your JSON to make sure your structure is good. Your code will actually decode along with Athlete his Team and TeamKey where you access 'depId'.
You should either remove the teamKey, or resolve it by following along the path of the original JSON you are trying to parse and see if your structure is in align with it.

Listview search and filter not working flutter

This is my model;
/*
// To parse this JSON data, do
//
// final hisselist = hisselistFromJson(jsonString);
import 'dart:convert';
Hisselist hisselistFromJson(String str) => Hisselist.fromJson(json.decode(str));
String hisselistToJson(Hisselist data) => json.encode(data.toJson());
class Hisselist {
Hisselist({
required this.success,
required this.result,
});
bool success;
List<ResultClass> result;
factory Hisselist.fromJson(Map<String, dynamic> json) => Hisselist(
success: json["success"], result: json["result"].map<ResultClass>((x) => ResultClass.fromJson(x)).toList(),
);
Map<String, dynamic> toJson() => {
"success": success,
"result": result.map((x) => x.toJson()),
};
}
class ResultClass {
ResultClass({
required this.rate,
required this.lastprice,
required this.lastpricestr,
required this.hacim,
required this.hacimstr,
required this.text,
required this.code,
});
double rate;
double lastprice;
String lastpricestr;
double hacim;
String hacimstr;
String text;
String code;
factory ResultClass.fromJson(Map<String, dynamic> json) => ResultClass(
rate: double.tryParse(json["rate"].toString()) ?? 0.0,
lastprice: double.tryParse(json["lastprice"].toString()) ?? 0.0,
lastpricestr: json["lastpricestr"],
hacim: double.tryParse(json["hacim"].toString()) ?? 0.0,
hacimstr: json["hacimstr"],
text: json["text"],
code: json["code"],
);
Map<String, dynamic> toJson() => {
"rate": rate,
"lastprice": lastprice,
"lastpricestr": lastpricestr,
"hacim": hacim,
"hacimstr": hacimstr,
"text": text,
"code": code,
};
}
*/
// To parse this JSON data, do
//
// final hisselist = hisselistFromJson(jsonString);
import 'dart:convert';
Hisselist hisselistFromJson(String str) => Hisselist.fromJson(json.decode(str));
String hisselistToJson(Hisselist data) => json.encode(data.toJson());
class Hisselist {
Hisselist({
required this.success,
required this.result,
});
bool success;
List<Result> result;
factory Hisselist.fromJson(Map<String, dynamic> json) => Hisselist(
success: json["success"],
result: List<Result>.from(json["result"].map((x) => Result.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"success": success,
"result": List<dynamic>.from(result.map((x) => x.toJson())),
};
}
class Result {
Result({
this.rate,
this.lastprice,
this.lastpricestr,
this.hacim,
this.hacimstr,
this.min,
this.minstr,
this.max,
this.maxstr,
this.time,
this.text,
this.code,
});
double? rate;
double? lastprice;
String? lastpricestr;
String? hacim;
String? hacimstr;
dynamic min;
String? minstr;
dynamic max;
String? maxstr;
Time? time;
String? text;
String? code;
factory Result.fromJson(Map<String, dynamic> json) => Result(
rate: json["rate"].toDouble(),
lastprice: json["lastprice"].toDouble(),
lastpricestr: json["lastpricestr"],
hacim: json["hacim"],
hacimstr: json["hacimstr"],
min: json["min"],
minstr: json["minstr"],
max: json["max"],
maxstr: json["maxstr"],
time: timeValues.map[json["time"]],
text: json["text"],
code: json["code"],
);
Map<String, dynamic> toJson() => {
"rate": rate,
"lastprice": lastprice,
"lastpricestr": lastpricestr,
"hacim": hacim,
"hacimstr": hacimstr,
"min": min,
"minstr": minstr,
"max": max,
"maxstr": maxstr,
"time": timeValues.reverse[time],
"text": text,
"code": code,
};
}
enum Time { THE_1809, THE_1808, THE_1805, THE_1810, THE_1759, THE_1755 }
final timeValues = EnumValues({
"17:55": Time.THE_1755,
"17:59": Time.THE_1759,
"18:05": Time.THE_1805,
"18:08": Time.THE_1808,
"18:09": Time.THE_1809,
"18:10": Time.THE_1810
});
class EnumValues<T> {
Map<String, T> map;
Map<T, String>? reverseMap;
EnumValues(this.map);
Map<T, String> get reverse {
if (reverseMap == null) {
reverseMap = map.map((k, v) => new MapEntry(v, k));
}
return reverseMap!;
}
}
This is where i call api:
class Hisseler extends StatefulWidget {
const Hisseler({Key? key}) : super(key: key);
#override
State<Hisseler> createState() => _HisselerState();
}
class _HisselerState extends State<Hisseler> {
final controller = TextEditingController();
final scaffoldKey = GlobalKey<ScaffoldState>();
final url = Uri.parse('https://api.collectapi.com/economy/hisseSenedi');
var counter;
Hisselist? hisseResult;
Future callHisse() async {
try{
Map<String, String> requestHeaders = {
'Content-Type': 'application/json',
'Authorization': 'apikey xxx:xxx'
};
final response = await http.get(url,headers:requestHeaders);
if(response.statusCode == 200){
var result = hisselistFromJson(response.body);
if(mounted);
setState(() {
counter = result.result.length;
result.result.sort((a, b) => (a.text ?? "").compareTo(b.text ?? ""));
hisseResult = result;
});
return result;
} else {
print(response.statusCode);
}
} catch(e) {
print(e.toString());
}
}
#override
void initState() {
// TODO: implement initState
super.initState();
callHisse();
}
#override
Widget build(BuildContext context) {
final style = controller.text.isEmpty
? const TextStyle(color: Colors.black54)
: const TextStyle(color: Colors.black);
return Scaffold(
appBar: AppBar(
centerTitle: false,
automaticallyImplyLeading: false,
title: Text(
'Hisseler'
),
),
body: Column(
children: [
Container(
margin: const EdgeInsets.fromLTRB(16, 16, 16, 16),
child: TextField(
controller: controller,
decoration: InputDecoration(
prefixIcon: const Icon(Icons.search),
suffixIcon: controller.text.isNotEmpty
? GestureDetector(
child: Icon(Icons.close, color: style.color),
onTap: () {
controller.clear();
FocusScope.of(context).requestFocus(FocusNode());
searchHisse('');
},
)
: null,
hintText: 'Hisse Ara',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(20),
borderSide: const BorderSide(color: Colors.black26),
),
),
onChanged: searchHisse,
),
),
Expanded(
child: Center(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: counter != null ?
ReorderableListView.builder(
itemCount: counter,
itemBuilder: (context, index){
return Card(
key: ValueKey(hisseResult?.result[index]),
child: ListTile(
contentPadding: EdgeInsets.all(10),
title: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text((hisseResult?.result[index].code ?? "")
.replaceAll("https:", ""),
style: TextStyle(
color: Colors.black,
fontSize: 16,
fontWeight: FontWeight.w500)),
Text(hisseResult?.result[index].text??"",style: TextStyle(color: Colors.grey[500], fontSize: 14))
],
),
trailing: Column(
children: <Widget>[
Text(hisseResult?.result[index].lastpricestr??"", style: TextStyle(color: Colors.black, fontSize: 16, fontWeight: FontWeight.w500)),
Container(
alignment: Alignment.center,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
color: (hisseResult?.result[index].rate ?? 0) > 0
? Colors.green
: Colors.red),
width: 75,
height: 25,
child: Text(hisseResult?.result[index].rate.toString() ?? "",
style: TextStyle(color: Colors.white)))
],
),
onTap: () => Navigator.push(
context, MaterialPageRoute(builder: (context) => StocksDetailScreen(
degisimoran: hisseResult?.result[index].rate!.toDouble(),
sondeger: hisseResult?.result[index].lastpricestr??"",
hacim: hisseResult?.result[index].hacimstr ?? "",
mindeger : hisseResult?.result[index].minstr?? "",
maxdeger : hisseResult?.result[index].maxstr?? "",
hisseismi : hisseResult?.result[index].text?? "",
hissekodu : hisseResult?.result[index].code?? "",
min : hisseResult?.result[index].min!.toDouble(),
max : hisseResult?.result[index].max!.toDouble(),
son : hisseResult?.result[index].lastprice!.toDouble(),
)),),
),
);
},
onReorder: (oldIndex, newIndex) {
setState(() {
if (newIndex > oldIndex) {
newIndex = newIndex - 1;
}
final element = hisseResult?.result.removeAt(oldIndex);
hisseResult?.result.insert(newIndex, element!);
});
},) : Center(child: CircularProgressIndicator(
)),
),
),
),
],
),
);
}
void searchHisse(String query) {
final suggestions = hisseResult?.result.where((code) {
final hisseTitle = hisseResult?.result;
final input = query.toLowerCase();
return hisseTitle!.contains(input);
}).toList();
setState(() => hisseResult = suggestions as Hisselist?);
}
}
But nothing happens on search result :
I think the problem is on searchHisse() but i am not sure. How can i make this work? Thanks for your help
Based on your code , you only call api once and you get the full list only once too.
i think you need to separated in to 2 list object.
eg case:
initstate you fetch api callHisse(); and get the data.
then you can show all the data from hisseResult.
after 1 onchanged on Textfield you call searchHisse(String query) , which is updated your hisseResult. now you only have data with first letters from onchanged
then you tapped on textfield and clear the controller. there is no data on the list left that match to query
this is what i suggest
Hisselist? hisseResult; // data you get from API
Hisselist? hisseShow; // list that you show
and on your search function you need to add this condition
void searchHisse(String query) {
if (query == '') {
setState((){hisseShow =hisseResult;});
return;
}
final suggestions = hisseResult?.result.where((code) {
final hisseTitle = hisseResult?.result;
final input = query.toLowerCase();
return hisseTitle!.contains(input);
}).toList();
// based on your model data
setState(() => hisseShow = Hisselist(result: suggestions, success:true );
}
}
and you show your list
return Card(
key: ValueKey(hisseShow?.result[index]),
child: ListTile(
.....

How to get username and mail to display in UserAccountsDrawerHeader in flutter

I am getting my response from the URL after login in but I can only print the data in my console but how to get the mail and name from the that response
I have tried with the future response but when I get a future response but its returning error
LoginPage.dart
import 'dart:io';
import 'package:cookie_jar/cookie_jar.dart';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:path_provider/path_provider.dart';
import 'globals.dart' as globals;
class LoginPage extends StatefulWidget {
static String tag = 'login-page';
#override
_LoginPageState createState() => new _LoginPageState();
}
class _LoginPageState extends State<LoginPage> {
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
LoginRequestData _loginData = LoginRequestData();
bool _validate = false;
bool _obscureText = true;
var username, password;
#override
Widget build(BuildContext context) {
return Scaffold(
// backgroundColor: Colors.white,
body: SingleChildScrollView(
child: Container(
color: Colors.lightGreen[500],
child: Column(
children: <Widget>[
Center(
child: Container(
width: MediaQuery
.of(context)
.size
.width,
height: MediaQuery
.of(context)
.size
.height / 2.5,
decoration: BoxDecoration(
gradient: LinearGradient(
// begin: Alignment.topCenter,
// end: Alignment.bottomCenter,
colors: [
Color(0xFFFFFFFF),
Color(0xFFFFFFFF),
]
),
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(90)
)
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Align(
alignment: Alignment.center,
child: Image.asset('images/ic_launcher1.png'),
),
],
),
),
),
Center(
child: SingleChildScrollView(
child: new Form(
key: _formKey,
autovalidate: _validate,
child: _getFormUI(),
),
)
)
],
),
),
),
);
}
Widget _getFormUI() {
return new Column(
children: <Widget>[
SizedBox(height: 24.0),
Center(
child: Text('Login',
style: TextStyle(fontSize: 25,
fontWeight: FontWeight.bold,
color: Colors.white),),
),
new SizedBox(height: 25.0),
new TextFormField(
keyboardType: TextInputType.emailAddress,
autofocus: false,
decoration: InputDecoration(
hintText: 'Username',
contentPadding: EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0),
border:
OutlineInputBorder(borderRadius: BorderRadius.circular(32.0)),
),
validator: _validateName,
onSaved: (value) {
_loginData.username = value;
},
),
new SizedBox(height: 8.0),
new TextFormField(
autofocus: false,
obscureText: _obscureText,
keyboardType: TextInputType.text,
decoration: InputDecoration(
hintText: 'Password',
contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),
border:
OutlineInputBorder(borderRadius: BorderRadius.circular(24.0)),
suffixIcon: GestureDetector(
child: Icon(
_obscureText ? Icons.visibility : Icons.visibility_off,
semanticLabel:
_obscureText ? 'show password' : 'hide password',
),
),
),
validator: _validatePassword,
onSaved: (String value) {
_loginData.password = value;
}
),
new SizedBox(height: 15.0),
new Padding(
padding: EdgeInsets.symmetric(vertical: 16.0),
child: RaisedButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(24),
),
onPressed: () {
_submit();
// Navigator.of(context).pushReplacementNamed('/home');
},
padding: EdgeInsets.all(12),
color: Colors.black54,
child: Text('Log In', style: TextStyle(color: Colors.white)),
),
),
new FlatButton(
child: Text(
'Forgot password?',
style: TextStyle(color: Colors.black54),
),
onPressed: () {},
),
new FlatButton(
onPressed: _sendToRegisterPage,
child: Text('Not a member? Sign up now',
style: TextStyle(color: Colors.black54)),
),
Text(''),
Text(''),
Text(''),
],
);
}
_sendToRegisterPage() {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => HomeScreen()),
);
}
String _validateName(String value) {
if (value.isEmpty) {
return "Username is Required";
} else {
username = value.toString();
}
}
String _validatePassword(String value) {
if (value.isEmpty) {
return "Password is Required";
} else {
password = value.toString();
}
}
_submit() {
if (_formKey.currentState.validate()) {
_formKey.currentState.save();
print("Username ${_loginData.username}");
print("Password ${_loginData.password}");
return SessionId();
} else {
setState(() {
bool _validate = false;
});
}
}
final Dio _dio = Dio();
PersistCookieJar persistentCookies;
final String url = "https://www.xxxx.in/rest/user/login.json";
Future<String> get _localPath async {
final directory = await getApplicationDocumentsDirectory();
print(directory.path);
return directory.path;
}
Future<Directory> get _localCoookieDirectory async {
final path = await _localPath;
final Directory dir = new Directory('$path/cookies');
await dir.create();
print(dir);
return dir;
}
Future<String> getCsrftoken() async{
try {
String csrfTokenValue;
final Directory dir = await _localCoookieDirectory;
final cookiePath = dir.path;
persistentCookies = new PersistCookieJar(dir: '$cookiePath');
persistentCookies.deleteAll(); //clearing any existing cookies for a fresh start
_dio.interceptors.add(
CookieManager(persistentCookies) //this sets up _dio to persist cookies throughout subsequent requests
);
_dio.options = new BaseOptions(
baseUrl: url,
contentType: ContentType.json,
responseType: ResponseType.plain,
// connectTimeout: 5000,
// receiveTimeout: 100000,
headers: {
HttpHeaders.userAgentHeader: "dio",
"Connection": "keep-alive",
},
); //BaseOptions will be persisted throughout subsequent requests made with _dio
_dio.interceptors.add(
InterceptorsWrapper(
onResponse:(Response response) {
List<Cookie> cookies = persistentCookies.loadForRequest(Uri.parse(url));
csrfTokenValue = cookies.firstWhere((c) => c.name == 'csrftoken', orElse: () => null)?.value;
if (csrfTokenValue != null) {
_dio.options.headers['X-CSRF-TOKEN'] = csrfTokenValue; //setting the csrftoken from the response in the headers
}
print(response);
return response;
}
)
);
await _dio.get("https://www.xxxx.in/rest/user/login.json");
print(csrfTokenValue);
return csrfTokenValue;
} catch (error, stacktrace) {
print(error);
// print("Exception occured: $error stackTrace: $stacktrace");
return null;
}
}
SessionId() async {
try {
final csrf = await getCsrftoken();
FormData formData = new FormData.from({
"username": "${_loginData.username}",
"password": "${_loginData.password}",
"csrfmiddlewaretoken" : '$csrf'
});
Options optionData = new Options(
contentType: ContentType.parse("application/json"),
);
Response response = await _dio.post("https://www.xxxx.in/rest/user/login.json", data: formData, options: optionData);
Payload payloadFromJson(String str) =>
Payload.fromJson(json.decode(str));
String payloadToJson(Payload data) => json.encode(data.toJson());
if (response.statusCode == 200){
return Navigator.of(context).pushReplacement(MaterialPageRoute(
builder: (context) => HomeScreen(),
));
}
else{
throw Exception();
}
} on DioError catch(e) {
if(e.response != null) {
print( e.response.statusCode.toString() + " " + e.response.statusMessage);
print(e.response.data);
print(e.response.headers);
print(e.response.request);
} else{
print(e.request);
print(e.message);
}
}
catch (error, stacktrace) {
print("Exception occured: $error stackTrace: $stacktrace");
return null;
}
}
}
Homepage.dart
import 'package:flutter/material.dart';
...
class HomeScreen extends StatefulWidget {
#override
_HomeScreenState createState() => new _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color(0xffF2F2F2),
appBar: AppBar(
title: Text('Home'),
automaticallyImplyLeading: true,
drawer: new Drawer(
child: Column(
children: <Widget>[
UserAccountsDrawerHeader(
accountName: Text("${globals.payload.user.name}"),
accountEmail: Text("${globals.payload.user.mail}"),
)
],
)
)
}
please anybody can help to display name and mail-in drawer
Here is my Json
{
"sessid": "iszSjigXjxCvchpSRrU3j5Xp83t_LCXoIbwzx-mM3ag",
"session_name": "SSESSb2a6bc76023596a5f4079539da5ffe57",
"token": "zQESYCrGbL-3NzN8Lm-1ll3AQ-iCFYjiqRvxSpesGBc",
"user": {
"uid": "991",
"name": "abc",
"mail": "abc#gmail.com",
"theme": "",
"signature": "",
"signature_format": "plain_text",
"created": "1560678471",
"access": "1565326417",
"login": 1565328198,
"status": "1",
"timezone": "Asia/Kolkata",
"language": "",
"picture": "0",
"data": {
"mimemail_textonly": 0
},
"uuid": "9e614051-1f21-470a-9194-c567fced36f7",
"roles": {
"2": "authenticated user",
"6": "Mock test user"
},
"rdf_mapping": {
"rdftype": [
"sioc:UserAccount"
],
"name": {
"predicates": [
"foaf:name"
]
},
"homepage": {
"predicates": [
"foaf:page"
],
"type": "rel"
}
}
}
}
Find Json file here
In comments, how to parse the JSON?
please paste your JSON string to https://app.quicktype.io/
It will provide correct format
code snippet to parse JSON.
// To parse this JSON data, do
//
// final payload = payloadFromJson(jsonString);
import 'dart:convert';
Payload payloadFromJson(String str) => Payload.fromJson(json.decode(str));
String payloadToJson(Payload data) => json.encode(data.toJson());
class Payload {
String sessid;
String sessionName;
String token;
User user;
Payload({
this.sessid,
this.sessionName,
this.token,
this.user,
});
factory Payload.fromJson(Map<String, dynamic> json) => new Payload(
sessid: json["sessid"],
sessionName: json["session_name"],
token: json["token"],
user: User.fromJson(json["user"]),
);
Map<String, dynamic> toJson() => {
"sessid": sessid,
"session_name": sessionName,
"token": token,
"user": user.toJson(),
};
}
class User {
String uid;
String name;
String mail;
String theme;
String signature;
String signatureFormat;
String created;
String access;
int login;
String status;
String timezone;
String language;
String picture;
Data data;
String uuid;
Map<String, String> roles;
RdfMapping rdfMapping;
User({
this.uid,
this.name,
this.mail,
this.theme,
this.signature,
this.signatureFormat,
this.created,
this.access,
this.login,
this.status,
this.timezone,
this.language,
this.picture,
this.data,
this.uuid,
this.roles,
this.rdfMapping,
});
factory User.fromJson(Map<String, dynamic> json) => new User(
uid: json["uid"],
name: json["name"],
mail: json["mail"],
theme: json["theme"],
signature: json["signature"],
signatureFormat: json["signature_format"],
created: json["created"],
access: json["access"],
login: json["login"],
status: json["status"],
timezone: json["timezone"],
language: json["language"],
picture: json["picture"],
data: Data.fromJson(json["data"]),
uuid: json["uuid"],
roles: new Map.from(json["roles"]).map((k, v) => new MapEntry<String, String>(k, v)),
rdfMapping: RdfMapping.fromJson(json["rdf_mapping"]),
);
Map<String, dynamic> toJson() => {
"uid": uid,
"name": name,
"mail": mail,
"theme": theme,
"signature": signature,
"signature_format": signatureFormat,
"created": created,
"access": access,
"login": login,
"status": status,
"timezone": timezone,
"language": language,
"picture": picture,
"data": data.toJson(),
"uuid": uuid,
"roles": new Map.from(roles).map((k, v) => new MapEntry<String, dynamic>(k, v)),
"rdf_mapping": rdfMapping.toJson(),
};
}
class Data {
int mimemailTextonly;
Data({
this.mimemailTextonly,
});
factory Data.fromJson(Map<String, dynamic> json) => new Data(
mimemailTextonly: json["mimemail_textonly"],
);
Map<String, dynamic> toJson() => {
"mimemail_textonly": mimemailTextonly,
};
}
class RdfMapping {
List<String> rdftype;
Name name;
Homepage homepage;
RdfMapping({
this.rdftype,
this.name,
this.homepage,
});
factory RdfMapping.fromJson(Map<String, dynamic> json) => new RdfMapping(
rdftype: new List<String>.from(json["rdftype"].map((x) => x)),
name: Name.fromJson(json["name"]),
homepage: Homepage.fromJson(json["homepage"]),
);
Map<String, dynamic> toJson() => {
"rdftype": new List<dynamic>.from(rdftype.map((x) => x)),
"name": name.toJson(),
"homepage": homepage.toJson(),
};
}
class Homepage {
List<String> predicates;
String type;
Homepage({
this.predicates,
this.type,
});
factory Homepage.fromJson(Map<String, dynamic> json) => new Homepage(
predicates: new List<String>.from(json["predicates"].map((x) => x)),
type: json["type"],
);
Map<String, dynamic> toJson() => {
"predicates": new List<dynamic>.from(predicates.map((x) => x)),
"type": type,
};
}
class Name {
List<String> predicates;
Name({
this.predicates,
});
factory Name.fromJson(Map<String, dynamic> json) => new Name(
predicates: new List<String>.from(json["predicates"].map((x) => x)),
);
Map<String, dynamic> toJson() => {
"predicates": new List<dynamic>.from(predicates.map((x) => x)),
};
}
In comments, the following code is for demo purpose only, not best practice, there are other options can do this, but hard to describe in short since it's a huge topic, so from Global Variables in Dart
1 add globals.dart file
library my_prj.globals;
//import Payload class file too
Payload payload;
2 Import this library everywhere you need access to these fields.
import 'globals.dart' as globals;
...
globals.payload = payloadFromJson(jsonString); //from your parse or http logical
3 In your drawer class
import 'globals.dart' as globals;
...
return Drawer(
child: Column(
children: <Widget>[
UserAccountsDrawerHeader(
accountName: Text("${globals.payload.user.name}"),
accountEmail: Text("${globals.payload.user.mail}"),
Edit
In Homepage.dart add the following, then you can access your global variables
import 'globals.dart' as globals;
and do the same in LoginPage.dart, then you can
globals.payload = payloadFromJson(jsonString);
In theory, you will need an object which has a similar structure. However, if the JSON is complex and you need one/two attributes, following can be the quick way.
_emailId = decodedBody["user"]["mail"]
Now, let's say you get JSON response in the login page and need to pass _emailId to HomePage. You can do this like below :
HomePage.dart
class HomePage extends StatelessWidget {
final String emailId;
const HomePage({
Key key,
#required this.emailId,
}) : super(key: key);
#override
Widget build(BuildContext context) {
print (this.emailid);
return .....
);
}
}
Update _sendToRegisterPage() as below :
_sendToRegisterPage() {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => HomeScreen(emailId:_emailId)),
);
}