How to load data in the body property using flutter + (bloc) Pattern - flutter

Hello friends,
I have been learning to use flutter for weeks, I am creating an app that I develop as I learn to program in flutter.
My idea is to be able to follow the Pattern (BLoC). What I want to do now is like being able to load the movie data list into the home.dart file in the body property
I appreciate your help!
home.dart
import 'package:eva_icons_flutter/eva_icons_flutter.dart';
import 'package:flutter/material.dart';
import 'package:skyshowapp/styles/theme.dart' as Style;
class HomeScreen extends StatefulWidget{
#override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen>{
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Style.Colors.mainColor,
appBar: AppBar(
backgroundColor: Style.Colors.mainColor,
centerTitle: true,
leading: Icon(EvaIcons.menu2Outline , color: Colors.white),
title: Text("SKYSHOW APP"),
actions: <Widget>[
IconButton(icon: Icon(EvaIcons.searchOutline , color: Colors.white,), onPressed: null,)
],
),
body: ListView(
children: <Widget>[
],
),
);
}
}
movie_bloc.dart
import 'package:rxdart/subjects.dart';
import 'package:skyshowapp/model/movie.dart';
import 'package:skyshowapp/repository/repository.dart';
class MovieListBloc{
final MovieRepository _repository = new MovieRepository();
final BehaviorSubject<MovieRootClass> _subject = new BehaviorSubject<MovieRootClass>();
getMovies() async{
MovieRootClass response = await _repository.getMovies();
_subject.sink.add(response);
}
dispose(){
_subject.close();
}
BehaviorSubject<MovieRootClass> get subject => _subject;
}
final movieBloc = new MovieListBloc();
class MovieRootClass {
List<Movies> movies;
MovieRootClass({this.movies});
MovieRootClass.fromJson(Map<String, dynamic> json) {
if (json['movies'] != null) {
movies = new List<Movies>();
json['movies'].forEach((v) {
movies.add(new Movies.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.movies != null) {
data['movies'] = this.movies.map((v) => v.toJson()).toList();
}
return data;
}
}
class Movies {
String id;
String title;
String sinopsis;
String poster;
String rating;
String quality;
String year;
List<Extra> extra;
Movies(
{this.id,
this.title,
this.sinopsis,
this.poster,
this.rating,
this.quality,
this.year,
this.extra});
Movies.fromJson(Map<String, dynamic> json) {
id = json['id'];
title = json['title'];
sinopsis = json['sinopsis'];
poster = json['poster'];
rating = json['rating'];
quality = json['quality'];
year = json['year'];
if (json['extra'] != null) {
extra = new List<Extra>();
json['extra'].forEach((v) {
extra.add(new Extra.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['title'] = this.title;
data['sinopsis'] = this.sinopsis;
data['poster'] = this.poster;
data['rating'] = this.rating;
data['quality'] = this.quality;
data['year'] = this.year;
if (this.extra != null) {
data['extra'] = this.extra.map((v) => v.toJson()).toList();
}
return data;
}
}
// Extra class .....

You can use StreamBuilder widget which takes in a stream, and rebuilds itself when ever new data is added to the stream.
StreamBuilder(
stream: subject.stream,
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView.builder(
itemCount: snapshot.data.movies.length,
itemBuilder: (BuildContext context, int idnex) {
return ListTile(
title: Text(snapshot.data.someProperty),
);
},
);
}
return const CircularProgressIndicator();
},
);

Related

Flutter dropdown with future builder

This is my data model
class RoleModel {
int? id;
String? role;
RoleModel({this.id, this.role});
RoleModel.fromJson(Map<String, dynamic> json) {
id = json['id'];
role = json['role'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = id;
data['role'] = role;
return data;
}
}
This is my code to get api data
List<RoleModel> roles = [];
Future<List<RoleModel>> getRoles() async {
try {
final response = await http
.get(Uri.parse('https://localhost:8000/roles'));
var data = jsonDecode(response.body.toString());
if (response.statusCode == 200) {
for (Map<String, dynamic> i in data) {
roles.add(RoleModel.fromJson(i));
}
return roles;
} else {
throw Exception('Failed to load roles:$response');
}
} catch (e) {
throw Exception('Failed due to: $e');
}
}
How can I create a dropdown button which will have 'id' as value and 'role' will be displayed as text?
You can use the below the line of sample code for dropdown widget
DropdownButton<String>(
items: <String>['One', 'Two', 'Three', 'Four'].map((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
onChanged: (v) {},
),
you can create it like this
DropdownButton<int>(
items: [
DropdownMenuItem(
child: Text("${roleModel.role}"),
value: roleModel.id,
),
],
onChanged: (value) {},
),
You can also create a dropdown button just using a custom package from pub.dev :
Add the latest version of dropdown_button2 to your pubspec.yaml file from
[1]: https://pub.dev/packages/dropdown_button2/install
Run 'flutter pub add dropdown_button2' this command from your terminal.
Add 'import 'package:dropdown_button2/dropdown_button2.dart'; this line to your code page.
import 'dart:convert';
import 'package:dropdown_button2/custom_dropdown_button2.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
void main() => runApp(MyFlutterApp());
class MyFlutterApp extends StatelessWidget {
const MyFlutterApp({super.key});
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
const HomePage({super.key});
#override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
#override
List<String> get getAllRoles {
List<String> allRoles = [];
for (int i = 0; i < roles.length; i++) {
allRoles.add('${roles[i].id} ${roles[i].role}');
}
return allRoles; // String format of json taken from the web.
}
int index = 0;
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Dropdown with id and role'),
),
body: Padding(
padding: const EdgeInsets.all(8.0),
child: CustomDropdownButton2(
hint: 'Select Item',
dropdownItems: getAllRoles,
value: getAllRoles[index],
buttonWidth: double.infinity,
dropdownWidth: double.infinity,
buttonElevation: 7,
onChanged: (value) {
setState(() {
index = getAllRoles.indexOf(value.toString());
});
},
),
),
);
}
}
class RoleModel {
int? id;
String? role;
RoleModel({this.id, this.role});
RoleModel.fromJson(Map<String, dynamic> json) {
id = json['id'];
role = json['role'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = id;
data['role'] = role;
return data;
}
}
List<RoleModel> roles = [];
Future<List<RoleModel>> getRoles() async {
try {
final response = await http.get(Uri.parse('https://localhost:8000/roles'));
var data = jsonDecode(response.body.toString());
if (response.statusCode == 200) {
for (Map<String, dynamic> i in data) {
roles.add(RoleModel.fromJson(i));
}
return roles;
} else {
throw Exception('Failed to load roles:$response');
}
} catch (e) {
throw Exception('Failed due to: $e');
}
}
I've received an error, because the http URL isn't accessible now. If you try it with a new URL, i think this code will work correctly.

Flutter adding favourite feature with SQLITE

Hello flutter experts i am fetching data from Api and show in listview in my app when user click any item from listview its saved data in sqlite now i want if API data already exist in sqlite then my trailing star icon change into yellow color otherwise it will remain same please check my code let me know i can achieve this type functionality mobile app.
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:sqflite/sqflite.dart';
import 'package:testfproject/Model/Articlemodel.dart';
import 'package:testfproject/Model/Favourite/Favouritemodel.dart';
import 'package:testfproject/Services/services.dart';
import 'package:http/http.dart' as http;
import '../Db/Databasehelper.dart';
class Home extends StatefulWidget {
#override
State<Home> createState() => _HomeState();
}
class _HomeState extends State<Home> {
#override
void initState() {
// TODO: implement initState
super.initState();
// article();
}
Services api=Services();
Databasehelper databasehelper=Databasehelper();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('New Articles'),
),
body: Column(
children: [
FutureBuilder(
future: api.Article(),
builder: (BuildContext context, AsyncSnapshot<List<Articlemodel>> snapshot) {
if(snapshot.hasData){
List<Articlemodel>?articles=snapshot.data;
return Expanded(
child: ListView.separated(
shrinkWrap: true,
itemCount:articles!.length,
itemBuilder: (conext,index){
//this list tile when user press on trailing icon it saved data in sqlite
return ListTile(
trailing: IconButton(
icon:Icon(Icons.star),
onPressed: () {
databasehelper.insert(Favouritemodel(author: articles[index].author.toString(), title:articles[index].title.toString()));
},
),
title: Text(articles[index].title.toString()),
//subtitle: Text(articles[index].author.toString()),
);
}, separatorBuilder: (BuildContext context, int index) {
return Divider();
},),
);
}else{
return Container(
child: Text('NO data'),
);
}
},
)
],
),
);
}
}
//my Api services class
import 'dart:convert';
import 'package:testfproject/Model/Articlemodel.dart';
import 'package:http/http.dart' as http;
class Services{
Future<List<Articlemodel>>Article() async {
final response = await http.get(Uri.parse('https://newsapi.org/v2/top-headlines?country=us&apiKey=0fb3a9662c3747fba42ffd3d66cc612d'));
if(response.statusCode==200){
var data=jsonDecode(response.body.toString());
final Iterable json = data["articles"];
return json.map((article) => Articlemodel.fromJson(article)).toList();
}else{
throw Exception('Error');
}
}
}
model class of api
class Articlemodel {
Source? source;
String? author;
String? title;
String? description;
String? url;
String? urlToImage;
String? publishedAt;
String? content;
bool? iSfavourite;
Articlemodel(
{this.source,
this.author,
this.title,
this.description,
this.url,
this.urlToImage,
this.publishedAt,
this.content,
});
Articlemodel.fromJson(Map<String, dynamic> json) {
source =
json['source'] != null ? new Source.fromJson(json['source']) : null;
author = json['author'];
title = json['title'];
description = json['description'];
url = json['url'];
urlToImage = json['urlToImage'];
publishedAt = json['publishedAt'];
content = json['content'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.source != null) {
data['source'] = this.source!.toJson();
}
data['author'] = this.author;
data['title'] = this.title;
data['description'] = this.description;
data['url'] = this.url;
data['urlToImage'] = this.urlToImage;
data['publishedAt'] = this.publishedAt;
data['content'] = this.content;
return data;
}
}
class Source {
String? id;
String? name;
Source({this.id, this.name});
Source.fromJson(Map<String, dynamic> json) {
id = json['id'];
name = json['name'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['name'] = this.name;
return data;
}
}
//model class of sqlite for favouriting
class Favouritemodel {Favouritemodel(
{required this.author,required this.title,}
);
Favouritemodel.fromJson(dynamic json) {
author = json['author'];
title = json['title'];
}
String? author;
String? title;
Map<String, dynamic> toJson() {
final map = <String, dynamic>{};
map['author'] = author;
map['title'] = title;
return map;
}
}
//database helper class
import 'dart:io' as io;
import 'package:flutter/cupertino.dart';
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';
import 'package:path_provider/path_provider.dart';
import '../Model/Favourite/Favouritemodel.dart';
class Databasehelper{
static Database? _db;
bool check=false;
Future<Database?> get db async {
if(_db != null)
return _db;
_db = await initDb();
return _db;
}
//Creating a database with name test.dn in your directory
initDb() async {
io.Directory documentsDirectory = await getApplicationDocumentsDirectory();
String path = join(documentsDirectory.path, "favourite.db");
var theDb = await openDatabase(path, version: 1, onCreate: _onCreate);
return theDb;
}
// Creating a table
void _onCreate(Database db, int version) async {
// When creating the db, create the table
await db.execute(
"CREATE TABLE favourite(ID INTEGER PRIMARY KEY AUTOINCREMENT, author TEXT, title TEXT unique )");
print("Created tables");
}
//insert data
Future<Favouritemodel> insert(Favouritemodel favouritemodel) async {
Database? db = await this.db;
await db!.insert('favourite', favouritemodel.toJson()).catchError((e)=>(debugPrint(e)));
return favouritemodel;
}
first add this function to your database helper
Future<List<Favouritemodel>> favourites() async {
Database? db = await this.db;
final List<Map> data = await db!.query('favourite');
return data.map((e) => Favouritemodel.fromJson(e)).toList();
}
and override the equal operator in Favouritemodel
#override
bool operator ==(Object other) {
return identical(this, other) ||
(other is Favouritemodel &&
author == other.author &&
title == other.title);
receive the favourite list in the build method:
#override
Widget build(BuildContext context) {
final futureFavourites = databasehelper.favourites();
return Scaffold(
// ...
and finally change the itemBuilder to this:
itemBuilder: (conext, index) {
return FutureBuilder<List<Favouritemodel>>(
future: futureFavourites,
builder: (context, favouriteSnapshot) {
if(!favouriteSnapshot.hasData) {
return ListTile(title: Text('Loading...'));
}
final favourites = favouriteSnapshot.data!;
final favouriteModel = Favouritemodel(author: articles[index].author.toString(),
title:articles[index].title.toString());
final isFavourite = favourites.contains(favouriteModel);
return ListTile(
trailing: IconButton(
icon:Icon(Icons.star, color: isFavourite ? Colors.yellow : null),
onPressed: () {
databasehelper.insert(favouriteModel);
},
),
title: Text(articles[index].title.toString()),
//subtitle: Text(articles[index].author.toString()),
);
}
);
}

E/LB (26008): fail to open file: No such file or directory -Flutter

I try to get a List from this Api(https://www.getpostman.com/collections/fa1296508e65891de558)
But there does no appear any Object. Console showing => "E/LB (26008): fail to open file: No such file or directory
".
I tried to print respone.statusCode but the result does'n apper in console.
I hope to solve this problem, Thank you.
What can be the problem here?
My code:
class ApiSetting{
static const String _baseUri='http://demo-api.mr-dev.tech/api/';
static const String users= '${_baseUri}users';
}
**User Model
** class User {
late int id;
late String firstName;
late String lastName;
late String email;
late String mobile;
late String bio;
late String jobTitle;
late String latitude;
late String longitude;
late String country;
late String image;
late String active;
late String emailVerifiedAt;
late String imagesCount;
User.fromJson(Map<String, dynamic> json) {
id = json['id'];
firstName = json['first_name'];
lastName = json['last_name'];
email = json['email'];
mobile = json['mobile'];
bio = json['bio'];
jobTitle = json['job_title'];
latitude = json['latitude'];
longitude = json['longitude'];
country = json['country'];
image = json['image'];
active = json['active'];
emailVerifiedAt = json['email_verified_at'];
imagesCount = json['images_count'];
}
}
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'package:api_secand_project/api/api_setting.dart';
import 'package:api_secand_project/models/user.dart';
class UserApiController {
Future<List<User>> getUser() async {
var uri = Uri.parse(ApiSetting.users);
var response = await http.get(uri);
if (response.statusCode == 200) {
print(response.statusCode);
var jsonResponse = jsonDecode(response.body);
var userJsonArray = jsonResponse['data'] as List;
return userJsonArray
.map((jsonObject) => User.fromJson(jsonObject))
.toList();
}
return [];
}
}
import 'package:api_secand_project/api/controllers/user_api_controller.dart';
import 'package:api_secand_project/models/user.dart';
import 'package:flutter/material.dart';
class UsersScreen extends StatefulWidget {
const UsersScreen({Key? key}) : super(key: key);
#override
State<UsersScreen> createState() => _UsersScreenState();
}
class _UsersScreenState extends State<UsersScreen> {
List<User> _users=<User>[];
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Users'),
),
body: FutureBuilder<List<User>>(
future: UserApiController().getUser(),
builder: (context, snapshot) {
if(snapshot.connectionState == ConnectionState.waiting){
return const Center(
child: CircularProgressIndicator(),
);
}
else if(snapshot.hasData){
_users=snapshot.data!;
return ListView.builder(
itemCount: _users.length,
itemBuilder: (context, index) {
return ListTile(
leading: CircleAvatar(
radius: 30,
// child: NetworkImage(snapshot.data!.),
),
title: Text(_users[index].firstName),
subtitle: Text(_users[index].mobile),
);
},
);
}
else{
return Center(child: Text('No Data',style: TextStyle(fontWeight: FontWeight.bold,fontSize: 28),),);
}
},
));
}
}
The question was not very clear, and there is no clear screenshot or message from the error console,
It seems that you are using the BLOC pattern and since part of the code is missing, you decide to create one from scratch, maybe it will help you, I thought not to publish it, but maybe something from here will help you
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
class GetApi extends StatefulWidget {
const GetApi({super.key});
#override
State<GetApi> createState() => _GetApiState();
}
class _GetApiState extends State<GetApi> {
List<User> users = [];
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("Get Api")),
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ElevatedButton(
onPressed: () {
getApi();
},
child: const Text("Get Api"),
),
Flexible(
child: ListView.builder(
itemCount: users.length,
itemBuilder: (context, index) {
User user = users[index];
return ListTile(
title: Text(user.name),
subtitle: Text(user.id),
);
}),
),
],
),
);
}
Future<void> getApi() async {
users = [];
Uri uri = Uri.parse("https://www.getpostman.com/collections/fa1296508e65891de558 ");
http.Response response = await http.get(uri);
if (response.statusCode == 200) {
//debugPrint("body: ${response.body}");
Map data = jsonDecode(response.body);
for (MapEntry item in data.entries) {
//debugPrint("key: ${item.key} value: ${item.value}");
if ("item" == item.key) {
List usersResponse = data["item"];
//debugPrint("users: ${users}");
for (dynamic json in usersResponse) {
User user = User.fromJson(json);
users.add(user);
//debugPrint("user: ${_user.name}");
}
}
}
if (!mounted) return;
setState(() {});
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text("succes -> status: ${response.statusCode}"),
backgroundColor: Colors.green,
),
);
} else {
if (!mounted) return;
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text("fail -> status: ${response.statusCode}"),
backgroundColor: Colors.red,
),
);
}
}
}
class User {
late String name;
late String id;
User.fromJson(Map<String, dynamic> json) {
name = json['name'];
id = json['id'];
}
}

Listing Data from API with Flutter

I can pull my data but not mirror it. The examples on the internet have always been used to reflect a single data. The data I have is multiple data. I want to reflect the data of different countries as a list.
I used Listview.builder and ListTile but it didn't work. I keep getting different errors. I couldn't find an up-to-date and working example. Could you help?
I have an API.
API URL: https://covid19-mohfw.herokuapp.com/
I converted this data as a model.
My Model:
class CovidModel {
List<States>? states;
Totals? totals;
CovidModel({this.states, this.totals});
CovidModel.fromJson(Map<String, dynamic> json) {
if (json['states'] != null) {
states = <States>[];
json['states'].forEach((v) {
states!.add(new States.fromJson(v));
});
}
totals =
json['totals'] != null ? new Totals.fromJson(json['totals']) : null;
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.states != null) {
data['states'] = this.states!.map((v) => v.toJson()).toList();
}
if (this.totals != null) {
data['totals'] = this.totals!.toJson();
}
return data;
}
}
class States {
String? state;
int? cases;
int? recoveries;
int? deaths;
int? total;
States({this.state, this.cases, this.recoveries, this.deaths, this.total});
States.fromJson(Map<String, dynamic> json) {
state = json['state'];
cases = json['cases'];
recoveries = json['recoveries'];
deaths = json['deaths'];
total = json['total'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['state'] = this.state;
data['cases'] = this.cases;
data['recoveries'] = this.recoveries;
data['deaths'] = this.deaths;
data['total'] = this.total;
return data;
}
}
class Totals {
int? cases;
int? recoveries;
int? deaths;
int? total;
Totals({this.cases, this.recoveries, this.deaths, this.total});
Totals.fromJson(Map<String, dynamic> json) {
cases = json['cases'];
recoveries = json['recoveries'];
deaths = json['deaths'];
total = json['total'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['cases'] = this.cases;
data['recoveries'] = this.recoveries;
data['deaths'] = this.deaths;
data['total'] = this.total;
return data;
}
}
and my fetchCountry file from which I Pulled Data
import 'dart:convert';
import 'package:covidapp/models/covidModel.dart';
import 'package:http/http.dart' as http;
class FetchCountry {
Future<CovidModel> fetchData() async {
final response =
await http.get(Uri.parse("https://covid19-mohfw.herokuapp.com/"));
if (response.statusCode == 200) {
final result = CovidModel.fromJson(jsonDecode(response.body));
return result;
} else {
throw Exception('Error');
}
}
}
Finally, the part where I try to reflect the data:
import 'package:covidapp/models/covidModel.dart';
import 'package:flutter/material.dart';
import 'package:covidapp/services/fetchCountry.dart';
class covidPage extends StatefulWidget {
const covidPage({Key? key}) : super(key: key);
#override
State<covidPage> createState() => _covidPageState();
}
class _covidPageState extends State<covidPage> {
late Future<CovidModel> futureCountry = FetchCountry().fetchData();
#override
void initState() {
super.initState();
futureCountry = FetchCountry().fetchData();
}
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Container(
width: double.infinity,
height: double.infinity,
color: Color.fromRGBO(255, 246, 234, 1),
child: Column(children: [
SizedBox(
height: MediaQuery.of(context).size.height * 0.03,
),
const Text(
'Covid Data',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 29,
fontWeight: FontWeight.w700,
color: Color.fromARGB(255, 112, 108, 112)),
),
]),
)),
);
}
}
Store all your data in model instead of future model will work
class _covidPageState extends State<covidPage> {
late CovidModel? futureCountry;
#override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
futureCountry = await FetchCountry().fetchData();
print(futureCountry?.states?.length); // You can access all data with futureCountry?.
setState(() {});
});
}
/// your code
You can use a FutureBuilder like this:
FutureBuilder(
future: futureCountry,
builder: (context, snap) {
if (snap.connectionState == ConnectionState.waiting) {
return CupertinoActivityIndicator();
}
if (snap.hasError) {
return Text("Error!");
}
final data =
snap.data as CovidModel;
return ListView.builder(
shrinkWrap: true,
padding: EdgeInsets.symmetric(vertical: 20),
physics: const AlwaysScrollableScrollPhysics(),
itemCount: data.states.length,
itemBuilder: (c, index) => CovidDetailWidget(data[index]),
);
},
)
Use the Below code to show data in List view
import 'package:flutter/material.dart';
import 'package:link/deep_link.dart';
class covidPage extends StatefulWidget {
const covidPage({Key? key}) : super(key: key);
#override
State<covidPage> createState() => _covidPageState();
}
class _covidPageState extends State<covidPage> {
late CovidModel? futureCountry = null;
#override
void initState() {
super.initState();
_getData();
}
void _getData() async {
futureCountry = (await FetchCountry().fetchData());
Future.delayed(const Duration(seconds: 1)).then((value) => setState(()
{}));
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('REST API Example'),
),
body: futureCountry?.states == null || futureCountry?.states?.length == 0
? const Center(
child: CircularProgressIndicator(),
)
: ListView.builder(
itemCount: futureCountry?.states?.length,
itemBuilder: (context, index) {
return Card(
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Text(futureCountry?.states![index].state ?? ''),
],
),
],
),
);
},
),
);
}
}

Postman Return Body Response ( thumbnail url) into Flutter json map into Dart object and it doesnt work on Grid view Builder

I am a beginner in flutter app development and I want to display thumb images into flutter grid view builder. My postman return response is 200. This is the response from postman
This is my flutter code. I donot know what i am doing wrong.
import 'dart:async';
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
Future<List<Photo>> fetchPhotos(http.Client client) async {
var headers = {
'Authorization': 'Bearer $bearer_token'
};
var request = http.Request('GET', Uri.parse('https://xxxxx.execute-api.us-east-2.amazonaws.com/stg/assets'));
request.headers.addAll(headers);
http.StreamedResponse response = await request.send();
if (response.statusCode == 200) {
// print(await response.stream.bytesToString());
return compute(parsePhotos, response.body);
}
else {
print(response.reasonPhrase);
}
}
List<Photo> parsePhotos(String responseBody) {
final parsed = jsonDecode(responseBody).cast<Map<String, dynamic>>();
return parsed.map<Photo>((json) => Photo.fromJson(json)).toList();
}
class Photo {
List<Assets> assets;
Photo({this.assets});
Photo.fromJson(Map<String, dynamic> json) {
if (json['assets'] != null) {
assets = new List<Assets>();
json['assets'].forEach((v) {
assets.add(new Assets.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.assets != null) {
data['assets'] = this.assets.map((v) => v.toJson()).toList();
}
return data;
}
}
class Assets {
String assetId;
String createdAt;
String description;
bool isPrivate;
bool isThumbnailGenerated;
Metadata metadata;
String name;
Null sharedBy;
int sizeInBytes;
List<String> tags;
String thumbnailUrl;
String title;
String type;
String uploadDate;
String uploadStatus;
Assets(
{this.assetId,
this.createdAt,
this.description,
this.isPrivate,
this.isThumbnailGenerated,
this.metadata,
this.name,
this.sharedBy,
this.sizeInBytes,
this.tags,
this.thumbnailUrl,
this.title,
this.type,
this.uploadDate,
this.uploadStatus});
Assets.fromJson(Map<String, dynamic> json) {
assetId = json['asset_id'];
createdAt = json['created_at'];
description = json['description'];
isPrivate = json['is_private'];
isThumbnailGenerated = json['is_thumbnail_generated'];
metadata = json['metadata'] != null
? new Metadata.fromJson(json['metadata'])
: null;
name = json['name'];
sharedBy = json['shared_by'];
sizeInBytes = json['size_in_bytes'];
tags = json['tags'].cast<String>();
thumbnailUrl = json['thumbnail_url'];
title = json['title'];
type = json['type'];
uploadDate = json['upload_date'];
uploadStatus = json['upload_status'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['asset_id'] = this.assetId;
data['created_at'] = this.createdAt;
data['description'] = this.description;
data['is_private'] = this.isPrivate;
data['is_thumbnail_generated'] = this.isThumbnailGenerated;
if (this.metadata != null) {
data['metadata'] = this.metadata.toJson();
}
data['name'] = this.name;
data['shared_by'] = this.sharedBy;
data['size_in_bytes'] = this.sizeInBytes;
data['tags'] = this.tags;
data['thumbnail_url'] = this.thumbnailUrl;
data['title'] = this.title;
data['type'] = this.type;
data['upload_date'] = this.uploadDate;
data['upload_status'] = this.uploadStatus;
return data;
}
}
class Metadata {
int exifOffset;
int imageLength;
int imageWidth;
int lightSource;
int orientation;
Metadata(
{this.exifOffset,
this.imageLength,
this.imageWidth,
this.lightSource,
this.orientation});
Metadata.fromJson(Map<String, dynamic> json) {
exifOffset = json['ExifOffset'];
imageLength = json['ImageLength'];
imageWidth = json['ImageWidth'];
lightSource = json['LightSource'];
orientation = json['Orientation'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['ExifOffset'] = this.exifOffset;
data['ImageLength'] = this.imageLength;
data['ImageWidth'] = this.imageWidth;
data['LightSource'] = this.lightSource;
data['Orientation'] = this.orientation;
return data;
}
}
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
const appTitle = 'Get Assets';
return const MaterialApp(
title: appTitle,
home: MyHomePage(title: appTitle),
);
}
}
class MyHomePage extends StatelessWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(title),
),
body: FutureBuilder<List<Photo>>(
future: fetchPhotos(http.Client()),
builder: (context, snapshot) {
if (snapshot.hasError) {
return const Center(
child: Text('An error has occurred!'),
);
} else if (snapshot.hasData) {
return PhotosList(photos: snapshot.data!);
} else {
return const Center(
child: CircularProgressIndicator(),
);
}
},
),
);
}
}
class PhotosList extends StatelessWidget {
const PhotosList({Key? key, required this.photos}) : super(key: key);
final List<Photo> photos;
#override
Widget build(BuildContext context) {
return GridView.builder(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
),
itemCount: photos.length,
itemBuilder: (context, index) {
return Image.network(photos[index].thumbnailUrl);
},
);
}
}
in Gridview Builder ... thumbnail images are not loading and it is throwing error.
[![enter image description here][2]][2]
I want the result like this
[2]: https://i.stack.imgur.com/Bnyaj.gif