Related
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):
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
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
}
How to Login Using API with Model Class in Flutter?
I have Json response as below.
{
"success": 1,
"user": {
"user_id": "609cab2cd5b6c",
"name": "Test User",
"mobile": "9909413561",
"email": "sunil#gmail.com",
"standard_id": "5d1594e283e1a",
"medium_id": "5d15938aa1344",
"location": "Bardoli",
"avatar": "upload/avatar/609cab2cd5b6c609cb9205afef.png",
"device_id": "y",
"created_at": "2021-05-13",
"updated_at": "2021-05-13"
},
"plan_id": "0",
"msg": "You have not purchased any plan"
}
Created Model Class from above response in loginmodel.dart file as below.
// To parse this JSON data, do
//
// final loginModel = loginModelFromJson(jsonString);
import 'dart:convert';
LoginModel loginModelFromJson(String str) =>
LoginModel.fromJson(json.decode(str));
String loginModelToJson(LoginModel data) => json.encode(data.toJson());
class LoginModel {
LoginModel({
required this.success,
required this.user,
required this.planId,
required this.msg,
});
int success;
User user;
String planId;
String msg;
factory LoginModel.fromJson(Map<String, dynamic> json) => LoginModel(
success: json["success"],
user: User.fromJson(json["user"]),
planId: json["plan_id"],
msg: json["msg"],
);
Map<String, dynamic> toJson() => {
"success": success,
"user": user.toJson(),
"plan_id": planId,
"msg": msg,
};
}
class User {
User({
required this.userId,
required this.name,
required this.mobile,
required this.email,
required this.standardId,
required this.mediumId,
required this.location,
required this.avatar,
required this.deviceId,
required this.createdAt,
required this.updatedAt,
});
String userId;
String name;
String mobile;
String email;
String standardId;
String mediumId;
String location;
String avatar;
String deviceId;
DateTime createdAt;
DateTime updatedAt;
factory User.fromJson(Map<String, dynamic> json) => User(
userId: json["user_id"],
name: json["name"],
mobile: json["mobile"],
email: json["email"],
standardId: json["standard_id"],
mediumId: json["medium_id"],
location: json["location"],
avatar: json["avatar"],
deviceId: json["device_id"],
createdAt: DateTime.parse(json["created_at"]),
updatedAt: DateTime.parse(json["updated_at"]),
);
Map<String, dynamic> toJson() => {
"user_id": userId,
"name": name,
"mobile": mobile,
"email": email,
"standard_id": standardId,
"medium_id": mediumId,
"location": location,
"avatar": avatar,
"device_id": deviceId,
"created_at":
"${createdAt.year.toString().padLeft(4, '0')}-${createdAt.month.toString().padLeft(2, '0')}-${createdAt.day.toString().padLeft(2, '0')}",
"updated_at":
"${updatedAt.year.toString().padLeft(4, '0')}-${updatedAt.month.toString().padLeft(2, '0')}-${updatedAt.day.toString().padLeft(2, '0')}",
};
}
And Created Function as below in apimanager.dart file.
Future<User> loginUser(
String mobile, String standardid, String mediumid) async {
final loginUrl = "$baseUrl/user/login";
var data;
final response = await http.post(Uri.parse(loginUrl), body: {
'mobile': mobile,
'standardid': standardid,
'mediumid': mediumid,
});
if (response.statusCode == 200) {
data = User.fromJson(jsonDecode(response.body));
Navigator.push(
context, MaterialPageRoute(builder: (context) => DashBoard()));
print(data);
} else {
throw Exception('Failed.');
}
return data;
}
Here is my Login screen file login.dart as below.
class Login2 extends StatefulWidget {
const Login2({Key? key}) : super(key: key);
#override
_Login2State createState() => _Login2State();
}
class _Login2State extends State<Login2> {
final baseUrl = SankalpApi().baseUrl;
GlobalKey<FormState> globalFormKey = GlobalKey<FormState>();
bool value = false;
var _standards = <Standard>[];
var _mediums = <Medium>[];
Standard? selectedStandard;
Medium? selectedMedium;
var standardId;
var mediumId;
#override
void initState() {
super.initState();
ApiManager().getStandards().then((standards) {
setState(() {
_standards = standards;
});
});
}
void onMediumChange(standard) {
setState(() {
selectedStandard = standard;
_mediums = [];
});
String mediumUrl =
"$baseUrl/medium/get_by_course_id?standard_id=${selectedStandard?.standardId}";
ApiManager().getMediums(mediumUrl).then((List<Medium> value) => {
setState(() {
_mediums = value;
})
});
}
final TextEditingController mobileController = TextEditingController();
#override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.only(top: 40, bottom: 20, right: 10, left: 10),
child: SingleChildScrollView(
child: Form(
key: globalFormKey,
child: Container(
padding: EdgeInsets.all(12),
child: Column(
children: [
TextFormField(
decoration: InputDecoration(labelText: "Mobile Number"),
controller: mobileController,
//onSaved: (input) => userModel.mobile = input!,
),
SizedBox(height: 20),
DropdownButton<Standard>(
isExpanded: true,
hint: Text('Select Standard'),
value: selectedStandard,
items: _standards.map((Standard standard) {
return DropdownMenuItem<Standard>(
value: standard,
child: Text(standard.standardName),
);
}).toList(),
onChanged: (val) {
setState(() {
selectedStandard = val;
standardId = val!.standardId;
//print("StandardId : ${val.standardId}");
//print("StandardId : ${val.standardName}");
onMediumChange(val);
});
}),
SizedBox(height: 20),
DropdownButton<Medium>(
isExpanded: true,
hint: Text('Select Medium'),
value: selectedMedium,
items: _mediums.map((Medium medium) {
return DropdownMenuItem<Medium>(
value: medium,
child: Text(medium.mediumName),
);
}).toList(),
onChanged: (val) {
setState(() {
selectedMedium = val;
mediumId = val!.mediumId;
print("Medium id : ${val.mediumId}");
print("Medium id : ${val.mediumName}");
});
}),
SizedBox(
height: 20,
),
ElevatedButton(
onPressed: () {
setState(() {
ApiManager().loginUser(
mobileController.text, standardId, mediumId);
//print("Mobile No : ${mobileController.text}");
//print("StandardId : ${standardId}");
//print("MediumId : ${mediumId}");
});
},
child: Text('Login'),
),
],
),
),
),
),
);
}
}
I am not able to log in.
in both DropDown i get the values perfectly, which medium is based on standard which also get by standardperfectly, but i am not able to log in please help.
I have a json object here -
{
"error": "0",
"message": "Got it!",
"data": [
{
"status": false,
"_id": "5e04a27692928701258b9b06",
"group_id": "5df8aaae2f85481f6e31db59",
"date": "2019-12-29T00:00:00.000Z",
"title": "new task",
"priority": 5,
"description": "just a description",
"tasks": [],
"created_date": "2019-12-26T12:07:18.301Z",
"__v": 0
}
]
}
I am using this plugin to implement a calendar in my application - https://github.com/aleksanderwozniak/table_calendar.
I want to fetch the json objects in the format of Map <DateTime, List> (the plugin has an assertion for using Map <DateTime, List> for displaying events) where the "date" parameter should be mapped to "title" parameter.
the plugin uses initState to create a few hard coded events -
Map<DateTime, List> _events;
#override
void initState() {
super.initState();
final _selectedDay = DateTime.now();
_events = {_selectedDay : ["event 1"]};
}
Could i get some help on how to fetch a json object and convert it to a format of Map<DateTime, List>? Fetching the data on initState to _events ` should be fine.
data model -
class Post {
dynamic markComplete;
dynamic groupID;
dynamic date;
dynamic taskName;
dynamic taskID;
//dynamic subtasks;
dynamic priority;
dynamic description;
/// IMPLEMENT PARAMETERS AFTER CONFIRMING WITH VAMSHI
Post({
this.markComplete,
this.groupID,
this.taskID,
this.date,
this.taskName,
// this.subtasks,
this.priority,
this.description,
});
/// MIGHT NEED TO CHANGE JSON VALUES; CONFIRM FROM VAMSHI
factory Post.fromJson(Map<String, dynamic> json) {
return Post(
markComplete : json['status'],
groupID : json['group_id'],
taskID: json["_id"],
date : json['date'],
taskName : json['title'],
// subtasks : json['subTasks'],
priority : json['priority'],
description : json['description']
);
}
Map toMapFetch() {
var map = new Map<dynamic, dynamic>();
// map['status'] = markComplete;
// map["group_id"] = taskid;
// map['date'] = date;
map['title'] = taskName;
// map['subTasks'] = subtasks;
//
// map['priority'] = priority;
// map['description'] = description;
return map;
}
}
method to fetch -
Future<Map<DateTime, List>> getTask() async {
Map<DateTime, List> mapFetch;
String link = baseURL + fetchTodoByDate;
var res = await http.post(Uri.encodeFull(link), headers: {"Accept": "application/json"});
if (res.statusCode == 200) {
// need help in creating fetch logic here
}
return mapFetch;
}
data model =
class dataArray {
// final dynamic status;
final dynamic id;
final dynamic groupName;
// final dynamic description;
// final dynamic created_date;
// final dynamic v;
dataArray(this.groupName, this.id);
dataArray.fromJson(Map jsonMap)
: groupName = jsonMap['name'],
id = jsonMap['_id'];
Map toMapData(){
var mapGroup = new Map<String, dynamic>();
mapGroup["name"] = groupName;
mapGroup['_id'] = id;
return mapGroup;
}
}
updated getTask method =
Future<List<dataArray>> getTask() async {
List<dataArray> groupMap;
String link = baseURL + fetchGroups;
var res = await http
.get(Uri.encodeFull(link), headers: {"Accept": "application/json"});
// print(res.body);
if (res.statusCode == 200) {
var data = json.decode(res.body);
var rest = data["data"] as List;
final demoJsonMapEntries = rest.map((data) {
return MapEntry(DateTime.parse(data['created_date']), data['name']);
});
demoJsonMapEntries.forEach((e) {
// Normalize the `date` - this is necessary to ensure proper `Map` behavior
final key = DateTime.utc(e.key.year, e.key.month, e.key.day, 12);
_events.update(key, (list) => list..add(e.value), ifAbsent: () => [e.value]);
});
print(demoJsonMapEntries);
}
print("PRINTING MAP = $groupMap");
return groupMap;
}
You can copy paste run full code below
Simulate API call with 3 seconds delay
Suppose you have two event on 12/29 and 12/30 , then parse with Event event = eventFromJson(responseString); and return mapFetch after for loop
You can get full Event class define in full code
code snippet
WidgetsBinding.instance.addPostFrameCallback((_) {
getTask().then((val) => setState(() {
_events = val;
}));
});
...
Future<Map<DateTime, List>> getTask() async {
Map<DateTime, List> mapFetch = {};
await Future.delayed(const Duration(seconds: 3), () {});
/*String link = baseURL + fetchTodoByDate;
var res = await http.post(Uri.encodeFull(link), headers: {"Accept": "application/json"});
if (res.statusCode == 200) {
// need help in creating fetch logic here
}*/
String responseString = '''
{
"error": "0",
"message": "Got it!",
"data": [
{
"status": false,
"_id": "5e04a27692928701258b9b06",
"group_id": "5df8aaae2f85481f6e31db59",
"date": "2019-12-29T00:00:00.000Z",
"title": "new task",
"priority": 5,
"description": "just a description",
"tasks": [],
"created_date": "2019-12-26T12:07:18.301Z",
"__v": 0
},
{
"status": false,
"_id": "5e04a27692928701258b9b06",
"group_id": "5df8aaae2f85481f6e31db59",
"date": "2019-12-30T00:00:00.000Z",
"title": "abc",
"priority": 5,
"description": "just a description",
"tasks": [],
"created_date": "2019-12-26T12:07:18.301Z",
"__v": 0
}
]
}
''';
Event event = eventFromJson(responseString);
for (int i = 0; i < event.data.length; i++) {
mapFetch[event.data[i].date] = [event.data[i].title];
}
return mapFetch;
}
working demo
full code
import 'package:flutter/material.dart';
import 'package:table_calendar/table_calendar.dart';
// To parse this JSON data, do
//
// final event = eventFromJson(jsonString);
import 'dart:convert';
Event eventFromJson(String str) => Event.fromJson(json.decode(str));
String eventToJson(Event data) => json.encode(data.toJson());
class Event {
String error;
String message;
List<Datum> data;
Event({
this.error,
this.message,
this.data,
});
factory Event.fromJson(Map<String, dynamic> json) => Event(
error: json["error"],
message: json["message"],
data: List<Datum>.from(json["data"].map((x) => Datum.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"error": error,
"message": message,
"data": List<dynamic>.from(data.map((x) => x.toJson())),
};
}
class Datum {
bool status;
String id;
String groupId;
DateTime date;
String title;
int priority;
String description;
List<dynamic> tasks;
DateTime createdDate;
int v;
Datum({
this.status,
this.id,
this.groupId,
this.date,
this.title,
this.priority,
this.description,
this.tasks,
this.createdDate,
this.v,
});
factory Datum.fromJson(Map<String, dynamic> json) => Datum(
status: json["status"],
id: json["_id"],
groupId: json["group_id"],
date: DateTime.parse(json["date"]),
title: json["title"],
priority: json["priority"],
description: json["description"],
tasks: List<dynamic>.from(json["tasks"].map((x) => x)),
createdDate: DateTime.parse(json["created_date"]),
v: json["__v"],
);
Map<String, dynamic> toJson() => {
"status": status,
"_id": id,
"group_id": groupId,
"date": date.toIso8601String(),
"title": title,
"priority": priority,
"description": description,
"tasks": List<dynamic>.from(tasks.map((x) => x)),
"created_date": createdDate.toIso8601String(),
"__v": v,
};
}
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
List _selectedEvents;
int _counter = 0;
Map<DateTime, List> _events;
CalendarController _calendarController;
AnimationController _animationController;
void _incrementCounter() {
setState(() {
_counter++;
});
}
Future<Map<DateTime, List>> getTask() async {
Map<DateTime, List> mapFetch = {};
await Future.delayed(const Duration(seconds: 3), () {});
/*String link = baseURL + fetchTodoByDate;
var res = await http.post(Uri.encodeFull(link), headers: {"Accept": "application/json"});
if (res.statusCode == 200) {
// need help in creating fetch logic here
}*/
String responseString = '''
{
"error": "0",
"message": "Got it!",
"data": [
{
"status": false,
"_id": "5e04a27692928701258b9b06",
"group_id": "5df8aaae2f85481f6e31db59",
"date": "2019-12-29T00:00:00.000Z",
"title": "new task",
"priority": 5,
"description": "just a description",
"tasks": [],
"created_date": "2019-12-26T12:07:18.301Z",
"__v": 0
},
{
"status": false,
"_id": "5e04a27692928701258b9b06",
"group_id": "5df8aaae2f85481f6e31db59",
"date": "2019-12-30T00:00:00.000Z",
"title": "abc",
"priority": 5,
"description": "just a description",
"tasks": [],
"created_date": "2019-12-26T12:07:18.301Z",
"__v": 0
}
]
}
''';
Event event = eventFromJson(responseString);
for (int i = 0; i < event.data.length; i++) {
mapFetch[event.data[i].date] = [event.data[i].title];
}
return mapFetch;
}
void _onDaySelected(DateTime day, List events) {
print('CALLBACK: _onDaySelected');
setState(() {
_selectedEvents = events;
});
}
#override
void initState() {
final _selectedDay = DateTime.now();
_selectedEvents = [];
_calendarController = CalendarController();
_animationController = AnimationController(
vsync: this,
duration: const Duration(milliseconds: 400),
);
_animationController.forward();
WidgetsBinding.instance.addPostFrameCallback((_) {
getTask().then((val) => setState(() {
_events = val;
}));
//print( ' ${_events.toString()} ');
});
super.initState();
}
#override
void dispose() {
_calendarController.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
_buildTableCalendarWithBuilders(),
const SizedBox(height: 8.0),
const SizedBox(height: 8.0),
Expanded(child: _buildEventList()),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
Widget _buildTableCalendarWithBuilders() {
return TableCalendar(
//locale: 'pl_PL',
calendarController: _calendarController,
events: _events,
//holidays: _holidays,
initialCalendarFormat: CalendarFormat.month,
formatAnimation: FormatAnimation.slide,
startingDayOfWeek: StartingDayOfWeek.sunday,
availableGestures: AvailableGestures.all,
availableCalendarFormats: const {
CalendarFormat.month: '',
CalendarFormat.week: '',
},
calendarStyle: CalendarStyle(
outsideDaysVisible: false,
weekendStyle: TextStyle().copyWith(color: Colors.blue[800]),
holidayStyle: TextStyle().copyWith(color: Colors.blue[800]),
),
daysOfWeekStyle: DaysOfWeekStyle(
weekendStyle: TextStyle().copyWith(color: Colors.blue[600]),
),
headerStyle: HeaderStyle(
centerHeaderTitle: true,
formatButtonVisible: false,
),
builders: CalendarBuilders(
selectedDayBuilder: (context, date, _) {
return FadeTransition(
opacity: Tween(begin: 0.0, end: 1.0).animate(_animationController),
child: Container(
margin: const EdgeInsets.all(4.0),
padding: const EdgeInsets.only(top: 5.0, left: 6.0),
color: Colors.deepOrange[300],
width: 100,
height: 100,
child: Text(
'${date.day}',
style: TextStyle().copyWith(fontSize: 16.0),
),
),
);
},
todayDayBuilder: (context, date, _) {
return Container(
margin: const EdgeInsets.all(4.0),
padding: const EdgeInsets.only(top: 5.0, left: 6.0),
color: Colors.amber[400],
width: 100,
height: 100,
child: Text(
'${date.day}',
style: TextStyle().copyWith(fontSize: 16.0),
),
);
},
markersBuilder: (context, date, events, holidays) {
final children = <Widget>[];
if (events.isNotEmpty) {
children.add(
Positioned(
right: 1,
bottom: 1,
child: _buildEventsMarker(date, events),
),
);
}
if (holidays.isNotEmpty) {
children.add(
Positioned(
right: -2,
top: -2,
child: _buildHolidaysMarker(),
),
);
}
return children;
},
),
onDaySelected: (date, events) {
_onDaySelected(date, events);
_animationController.forward(from: 0.0);
},
onVisibleDaysChanged: _onVisibleDaysChanged,
);
}
void _onVisibleDaysChanged(
DateTime first, DateTime last, CalendarFormat format) {
print('CALLBACK: _onVisibleDaysChanged');
}
Widget _buildEventsMarker(DateTime date, List events) {
return AnimatedContainer(
duration: const Duration(milliseconds: 300),
decoration: BoxDecoration(
shape: BoxShape.rectangle,
color: _calendarController.isSelected(date)
? Colors.brown[500]
: _calendarController.isToday(date)
? Colors.brown[300]
: Colors.blue[400],
),
width: 16.0,
height: 16.0,
child: Center(
child: Text(
'${events.length}',
style: TextStyle().copyWith(
color: Colors.white,
fontSize: 12.0,
),
),
),
);
}
Widget _buildHolidaysMarker() {
return Icon(
Icons.add_box,
size: 20.0,
color: Colors.blueGrey[800],
);
}
Widget _buildEventList() {
return ListView(
children: _selectedEvents
.map((event) => Container(
decoration: BoxDecoration(
border: Border.all(width: 0.8),
borderRadius: BorderRadius.circular(12.0),
),
margin:
const EdgeInsets.symmetric(horizontal: 8.0, vertical: 4.0),
child: ListTile(
title: Text(event.toString()),
onTap: () => print('$event tapped!'),
),
))
.toList(),
);
}
}
I think your fetch method should be like this:
Future<List<Post>> getData() async{
String link = baseURL + fetchTodoByDate;
var res = await http.post(Uri.encodeFull(link), headers: {"Accept": "application/json"});
var fetch = List<Data>();
if (res.statusCode == 200 ) {
var datesJson = json.decode(res.body);
for(var dateJson in datesJson){
fetch.add(Data.fromJson((dateJson)));
}
}
return fetch;
}