How view single data from listView in flutter? - flutter

I fetched data from the database as a ListView.That's displayed perfectly.
output.
When clicking the view button then should display only that article's details.
Andalso for the fetch data I used model class.
All articles code
model
import 'dart:convert';
Articles articlesFromJson(String str) => Articles.fromJson(json.decode(str));
String articlesToJson(Articles data) => json.encode(data.toJson());
class Articles {
Articles({
required this.id,
required this.url,
required this.topic,
required this.description,
});
String id;
String topic;
String description;
String url;
factory Articles.fromJson(Map<String, dynamic> json) => Articles(
id: json["id"] ?? "",
topic: json["topic"] ?? "",
description: json["description"] ?? "",
url: json["url"] ?? "",
);
Map<String, dynamic> toJson() => {
"id": id,
"topic": topic,
"description": description,
"url": url,
};
}
View all articles
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:neerogi/screens/Articles/Admin/viewOne_articles.dart';
import '../articlesModel.dart';
class ViewArticlesScreens extends StatefulWidget {
const ViewArticlesScreens({Key? key}) : super(key: key);
#override
State<ViewArticlesScreens> createState() => _ViewArticlesScreensState();
}
class _ViewArticlesScreensState extends State<ViewArticlesScreens> {
#override
Future<List<Articles>> fetchRecords() async {
var records = await FirebaseFirestore.instance.collection('articles').get();
return mapRecords(records);
}
List<Articles> mapRecords(QuerySnapshot<Map<String, dynamic>> records) {
var _list = records.docs
.map(
(article) => Articles(
id: article.id,
topic: article['topic'],
description: article['description'],
url: article['url'],
),
)
.toList();
return _list;
}
#override
void initState() {
super.initState();
}
#override
Widget build(BuildContext context) {
double height = MediaQuery.of(context).size.height;
double width = MediaQuery.of(context).size.width;
return Scaffold(
body: Column(
children: [
SingleChildScrollView(
child: Column(
//chip words
children: <Widget>[
const SizedBox(height: 10),
SizedBox(
width: width * 0.94,
height: height * 0.90,
child: FutureBuilder<List<Articles>>(
future: fetchRecords(),
builder: (context, snapshot) {
if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
} else {
List<Articles> data = snapshot.data ?? [];
return ListView.builder(
itemCount: data.length,
itemBuilder: (context, index) {
return (SizedBox(
height: 100,
child: Column(
children: <Widget>[
ListTile(
leading: Image.network(
data[index].url,
height: 30,
fit: BoxFit.cover,
),
title: Text(data[index].topic),
subtitle:
Text(data[index].description),
trailing: ElevatedButton(
child: Text('View'),
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) =>
ViewOneArticleScreen(
id: article.id,
)));
},
))
],
),
));
});
}
}))
],
),
),
],
),
);
}
}
View one article code
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import '../articlesModel.dart';
class ViewOneArticleScreen extends StatefulWidget {
const ViewOneArticleScreen({Key? key}) : super(key: key);
#override
State<ViewOneArticleScreen> createState() => _ViewOneArticleScreenState();
}
class _ViewOneArticleScreenState extends State<ViewOneArticleScreen> {
Future<List<Articles>> fetchRecords() async {
var records = await FirebaseFirestore.instance.collection('articles').get();
return mapRecords(records);
}
List<Articles> mapRecords(QuerySnapshot<Map<String, dynamic>> records) {
var _list = records.docs
.map(
(article) => Articles(
id: article.id,
topic: article['topic'],
description: article['description'],
url: article['url'],
),
)
.toList();
return _list;
}
#override
void initState() {
super.initState();
}
#override
Widget build(BuildContext context) {
double height = MediaQuery.of(context).size.height;
double width = MediaQuery.of(context).size.width;
return Scaffold(
body: Column(
children: [
Image.network(
data[index].url,
height: 30,
fit: BoxFit.cover,
),
Text($topic),
Text($description),
],
),
);
}
}
How to view one article data from the list view?
Ex:- User when cleck article 1 view button then should redirect to the View one article page and in there should display article 1 image , topic , description.

Related

How to fetch image from firestore on flutter?

I tried to fetch images and topic and descriptions for each "doc id ", Successfully fetch topic and description but when I tried to fetch image then shows "URL undefined" .For this code I used model class also.And in there I decleard "URL" and in the UI code I called that in an" Imagenetwrok widget".
code
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import '../articlesModel.dart';
class ViewArticlesScreens extends StatefulWidget {
const ViewArticlesScreens({Key? key}) : super(key: key);
#override
State<ViewArticlesScreens> createState() => _ViewArticlesScreensState();
}
class _ViewArticlesScreensState extends State<ViewArticlesScreens> {
#override
Future<List<Articles>> fetchRecords() async {
var records = await FirebaseFirestore.instance.collection('articles').get();
return mapRecords(records);
}
List<Articles> mapRecords(QuerySnapshot<Map<String, dynamic>> records) {
var _list = records.docs
.map(
(article) => Articles(
id: article.id,
topic: article['topic'],
description: article['description'],
url: article['url'],
),
)
.toList();
return _list;
}
#override
void initState() {
super.initState();
}
#override
Widget build(BuildContext context) {
double height = MediaQuery.of(context).size.height;
double width = MediaQuery.of(context).size.width;
return Scaffold(
body: Column(
children: [
SingleChildScrollView(
child: Column(
//chip words
children: <Widget>[
const SizedBox(height: 10),
SizedBox(
width: width * 0.94,
height: height * 0.30,
child: FutureBuilder<List<Articles>>(
future: fetchRecords(),
builder: (context, snapshot) {
if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
} else {
List<Articles> data = snapshot.data ?? [];
return ListView.builder(
itemCount: data.length,
itemBuilder: (context, index) {
return (ListTile(
leading: Image.network(
url,
height: 30,
fit: BoxFit.cover,
),
title: Text(data[index].topic),
subtitle: Text(data[index].description),
tileColor: Colors.red,
));
});
}
}))
],
),
),
],
),
);
}
}
model class
import 'dart:convert';
Articles articlesFromJson(String str) => Articles.fromJson(json.decode(str));
String articlesToJson(Articles data) => json.encode(data.toJson());
class Articles {
Articles({
required this.id,
required this.url,
required this.topic,
required this.description,
});
String id;
String topic;
String description;
String url;
factory Articles.fromJson(Map<String, dynamic> json) => Articles(
id: json["id"] ?? "",
topic: json["topic"] ?? "",
description: json["description"] ?? "",
url: json["url"] ?? "",
);
Map<String, dynamic> toJson() => {
"id": id,
"topic": topic,
"description": description,
"url": url,
};
}
you just set url instead of data[index].url
here try this :
itemBuilder: (context, index) {
return (ListTile(
leading: Image.network(
data[index].url,
height: 30,
fit: BoxFit.cover,
),
title: Text(data[index].topic),
subtitle: Text(data[index].description),
tileColor: Colors.red,
));
});
}

Although there is no error in the application that I want to show the weather from the internet, a white screen appears

launchUrl not working
import 'package:flutter/material.dart';
import 'package:haber_app/data/new_service.dart';
import 'package:haber_app/models/articles.dart';
import 'package:url_launcher/url_launcher.dart';
class Home extends StatefulWidget {
#override
State<Home> createState() => _HomeState();
}
class _HomeState extends State<Home> {
List<Articles> articles = [];
#override
void initState() {
NewsService.getNews().then((value) {
setState(() {
articles = value!;
});
});
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Haberler'),
centerTitle: true,
),
body: Center(
child: ListView.builder(
itemCount: articles.length,
itemBuilder: (context, index) {
return Card(
child: Column(
children: [
Image.network(articles[index].urlToImage!),
ListTile(
leading: Icon(Icons.arrow_drop_down_circle),
title: Text(articles[index].title!),
subtitle: Text(articles[index].author!),
),
Padding(
padding: const EdgeInsets.all(16.0),
child: Text(
'açıklama açıklama açıklamaaçıklama açıklamaaçıklama'),
),
ButtonBar(
alignment: MainAxisAlignment.start,
children: [
ElevatedButton(
onPressed: () async {
await launchUrl(articles[index].url);
},
child: Text('Habere git'))
],
)
],
),
);
})),
);
}
}
Link of the code: https://github.com/ghedtoboss/haber_app
I am making a pull request, check the changes and merge. haber_app/pull/1
Changes are on
source.dart
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 = Map<String, dynamic>();
data['id'] = id;
data['name'] = name;
return data;
}
}
news.dart
import 'articles.dart';
class News {
String? status;
int? totalResults;
List<Articles>? articles;
News({this.status, this.totalResults, this.articles});
News.fromJson(Map<String, dynamic> json) {
status = json['status'];
totalResults = json['totalResults'];
if (json['articles'] != null) {
articles = <Articles>[];
json['articles'].forEach((v) {
print(v);
articles!.add(Articles.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = Map<String, dynamic>();
data['status'] = status;
data['totalResults'] = totalResults;
if (articles != null) {
data['articles'] = articles!.map((v) => v.toJson()).toList();
}
return data;
}
}
NewsService
import 'package:haber_app/models/articles.dart';
import 'package:haber_app/models/news.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
class NewsService {
static NewsService _singleton = NewsService._internal();
NewsService._internal();
factory NewsService() {
return _singleton;
}
static Future<List<Articles>?> getNews() async {
String api =
'https://newsapi.org/v2/top-headlines?country=tr&category=business&apiKey=0002834b74c04acd987883986ea38f96';
final Uri url = Uri.parse(api);
final response = await http.post(url);
if (response.body.isNotEmpty) {
final responseJson = json.decode(response.body);
News news = News.fromJson(responseJson);
return news.articles;
}
return null;
}
}
On body
import 'package:flutter/material.dart';
import 'package:haber_app/data/new_service.dart';
import 'package:haber_app/models/articles.dart';
import 'package:url_launcher/url_launcher.dart';
class Home extends StatefulWidget {
#override
State<Home> createState() => _HomeState();
}
class _HomeState extends State<Home> {
List<Articles> articles = [];
#override
void initState() {
super.initState();
loadData();
}
loadData() async {
NewsService.getNews().then((value) {
print(value);
setState(() {
articles = value ?? [];
});
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Haberler'),
centerTitle: true,
),
body: Center(
child: articles.isEmpty
? Text("loading or something")
: ListView.builder(
itemCount: articles.length,
itemBuilder: (context, index) {
return Card(
child: Column(
children: [
if (articles[index].urlToImage != null)
Image.network(articles[index].urlToImage!),
ListTile(
leading: Icon(Icons.arrow_drop_down_circle),
title: Text(articles[index].title ?? ""),
subtitle: Text(articles[index].author ?? ""),
),
Padding(
padding: const EdgeInsets.all(16.0),
child: Text(
'açıklama açıklama açıklamaaçıklama açıklamaaçıklama'),
),
ButtonBar(
alignment: MainAxisAlignment.start,
children: [
ElevatedButton(
onPressed: () async {
if (articles[index].url == null) {
return;
}
await launchUrl(
Uri.parse(articles[index].url!));
},
child: Text('Habere git'))
],
)
],
),
);
})),
);
}
}
You need to use Uri to launch
onPressed: () async {
if (articles[index].url == null) {
return;
}
await launchUrl(
Uri.parse(articles[index].url!));
},
Also make sure to set up the configurationsection
More about url_launcher

Troubles with making a Favorite page with Hive DB Flutter

Hello everyone here's my test app and I have some problems with making a Favorite page section where you can tap on button and add the item into fav page.
I'm receiving a data from API and implementing it by Listview.builder
Here are some photos of how it should look like:
Home page
Favorite page
main.dart, here I'm openning a box called 'favorites_box'
import 'package:get/get.dart';
import 'package:get_storage/get_storage.dart';
import 'package:hive/hive.dart';
import 'package:hive_flutter/hive_flutter.dart';
void main() async{
await GetStorage.init();
await Hive.openBox('favorites_box');
runApp(MainPage());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return GetMaterialApp(
initialRoute: '/',
getPages: [
GetPage(name: '/', page: () => MyApp()),
GetPage(name: '/main-page', page: () => MainPage()),
GetPage(name: '/favorite_page', page: () => FavoritePage()),
// Dynamic route
],
home: MainPage(),
);
}
}
Well here's a code of home page:
main_page.dart
import 'package:flutter/material.dart';
import '../View/listview_api.dart';
class MainPage extends StatefulWidget {
#override
State<MainPage> createState() => _MainPageState();
}
class _MainPageState extends State<MainPage> {
int currentIndex = 0;
List<BottomNavigationBarItem>? items;
final screens = [
HomePage(),
HomePage()
FavoritePage(),
HomePage()
];
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: SafeArea(
child: Scaffold(
appBar: AppBar(
backgroundColor: Colors.white,
title: Container(
width: double.infinity,
height: 40,
color: Colors.white,
child: Center(
child: TextField(
decoration: InputDecoration(
border: OutlineInputBorder(
),
hintText: 'Searching',
prefixIcon: Icon(Icons.search),
suffixIcon: Icon(Icons.notifications)),
),
),
),
),
body: screens[currentIndex],
bottomNavigationBar: BottomNavigationBar(
unselectedItemColor: Colors.grey,//AppColors.unselectedBottomNavItem,
selectedItemColor: Colors.blue,//AppColors.assets,
onTap: (index) => setState(() {
currentIndex = index;
}),//controller.setMenu(BottomMenu.values[pos]),
//currentIndex: ,//controller.bottomMenu.index,
type: BottomNavigationBarType.fixed,
backgroundColor: Colors.white,
currentIndex: currentIndex,
selectedLabelStyle: const TextStyle(
fontSize: 10,
fontWeight: FontWeight.w500,
),
unselectedLabelStyle: const TextStyle(
fontSize: 10,
fontWeight: FontWeight.w500,
),
elevation: 8,
items: [
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Home',
backgroundColor: Colors.blue,
),
BottomNavigationBarItem(
icon: Icon(Icons.add_shopping_cart),
label: 'Shopping cart',
backgroundColor: Colors.red,
),
BottomNavigationBarItem(
icon: Icon(Icons.favorite),
label: 'Favorite',
backgroundColor: Colors.green,
),
BottomNavigationBarItem(
icon: Icon(Icons.person),
label: 'Profile',
backgroundColor: Colors.yellow,
),
],
),
),
),
);
}
}
class HomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return SafeArea(
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Center(
child: Padding(
padding: EdgeInsets.all(10.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
//Image.asset('images/image0.jpg'),
SizedBox(
height: 25.0,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'New!',
textAlign: TextAlign.left,
style: TextStyle(
fontSize: 25.0,
fontWeight: FontWeight.bold,
),
),
IconButton(
onPressed: () {},
icon: Icon(
Icons.arrow_forward_outlined,
),
),
],
),
SizedBox(
height: 25.0,
),
SizedBox(
height: 300.0,
width: double.infinity,
child: ListViewAPI(),
),
],
),
),
),
),
);
}
}
And now, below is a code of ListViewAPI(), here I've added the elements which I tap to the box('favorites_box'): listview_api.dart
import 'package:flutter/material.dart';
import 'package:hive/hive.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
String? stringResponse;
Map? mapResponse;
Map? dataResponse;
List? listResponse;
class ListViewAPI extends StatefulWidget {
const ListViewAPI({Key? key}) : super(key: key);
#override
_ListViewAPIState createState() => _ListViewAPIState();
}
class _ListViewAPIState extends State<ListViewAPI> {
Future apiCall() async {
http.Response response;
response = await http.get(Uri.parse("https://api.client.macbro.uz/v1/product"));
if(response.statusCode == 200) {
setState(() {
// stringResponse = response.body;
mapResponse = jsonDecode(response.body);
listResponse = mapResponse!['products'];
});
}
}
#override
void initState() {
super.initState();
apiCall();
}
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scrollbar(
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemBuilder: (context, index) {
return Stack(
children: [
Card(
child: Image.network(
listResponse![index]['image'],
),
),
Positioned(
right: 0,
child: InkWell(
child: IconButton(
onPressed: () async {
await Hive.box('favorites_box').put(listResponse![index]['image'], listResponse);
},
icon: Icon(
Icons.favorite_rounded,
color: Colors.red,
),
),
),
),
],
);
},
itemCount: listResponse == null ? 0 : listResponse!.length,
),
),
);
}
}
So here, I created a list, and tried to save the elements from box named "favorites_box" and got data which was added while I tap favorite IconButton upper but without success( :
favorite_page.dart
import 'package:flutter/material.dart';
import 'package:hive/hive.dart';
import 'package:hive_flutter/hive_flutter.dart';
import '../View/gridview_api.dart';
class FavoritePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: ValueListenableBuilder(
valueListenable: Hive.box('favorites_box').listenable(),
builder: (context, box, child) {
List posts = List.from(Hive.box('favorites_box').values);
return ListView.builder(
scrollDirection: Axis.horizontal,
itemBuilder: (context, index) {
return Column(
children: [
Text(
'List of favorite products'
),
Card(
child: posts[index] == null ? Text('nothing(') : posts[index],
// child: Hive.box('favorites_box').get(listResponse),
),
],
);
},
);
},
),
);
}
}
I'll be grateful if someone could help me with this problem, as I'm trying to fix this issue for a couple of days
P.s. I'm so sorry for some inconveniences, I'm a novice yet that's why hope you'll understand me
Thanks!
Alright. I now have a solution. It is a bit more complex than what you started with but it worked during testing.
Using https://marketplace.visualstudio.com/items?itemName=hirantha.json-to-dart I created a model class from the API data JSON. One for the Product and one for the Price map inside of Product.
product_model.dart
import 'dart:convert';
import 'package:equatable/equatable.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'price.dart';
part 'product_model.g.dart';
#HiveType(typeId: 1)
class ProductModel extends Equatable {
#HiveField(0)
final String? id;
#HiveField(1)
final String? name;
#HiveField(2)
final String? slug;
#HiveField(3)
final bool? active;
#HiveField(4)
final String? image;
#HiveField(5)
final String? code;
#HiveField(6)
final String? order;
#HiveField(7)
final int? cheapestPrice;
#HiveField(8)
final Price? price;
#HiveField(9)
final int? discount;
const ProductModel({
this.id,
this.name,
this.slug,
this.active,
this.image,
this.code,
this.order,
this.cheapestPrice,
this.price,
this.discount,
});
factory ProductModel.fromMap(Map<String, dynamic> data) => ProductModel(
id: data['id'] as String?,
name: data['name'] as String?,
slug: data['slug'] as String?,
active: data['active'] as bool?,
image: data['image'] as String?,
code: data['code'] as String?,
order: data['order'] as String?,
cheapestPrice: data['cheapest_price'] as int?,
price: data['price'] == null
? null
: Price.fromMap(data['price'] as Map<String, dynamic>),
discount: data['discount'] as int?,
);
Map<String, dynamic> toMap() => {
'id': id,
'name': name,
'slug': slug,
'active': active,
'image': image,
'code': code,
'order': order,
'cheapest_price': cheapestPrice,
'price': price?.toMap(),
'discount': discount,
};
/// `dart:convert`
///
/// Parses the string and returns the resulting Json object as [ProductModel].
factory ProductModel.fromJson(String data) {
return ProductModel.fromMap(json.decode(data) as Map<String, dynamic>);
}
/// `dart:convert`
///
/// Converts [ProductModel] to a JSON string.
String toJson() => json.encode(toMap());
ProductModel copyWith({
String? id,
String? name,
String? slug,
bool? active,
String? image,
String? code,
String? order,
int? cheapestPrice,
Price? price,
int? discount,
}) {
return ProductModel(
id: id ?? this.id,
name: name ?? this.name,
slug: slug ?? this.slug,
active: active ?? this.active,
image: image ?? this.image,
code: code ?? this.code,
order: order ?? this.order,
cheapestPrice: cheapestPrice ?? this.cheapestPrice,
price: price ?? this.price,
discount: discount ?? this.discount,
);
}
#override
bool get stringify => true;
#override
List<Object?> get props {
return [
id,
name,
slug,
active,
image,
code,
order,
cheapestPrice,
price,
discount,
];
}
}
price.dart
import 'dart:convert';
import 'package:equatable/equatable.dart';
import 'package:hive_flutter/hive_flutter.dart';
part 'price.g.dart';
#HiveType(typeId: 2)
class Price extends Equatable {
#HiveField(0)
final int? price;
#HiveField(1)
final int? oldPrice;
#HiveField(2)
final int? uzsPrice;
#HiveField(3)
final int? secondPrice;
#HiveField(4)
final int? secondUzsPrice;
const Price({
this.price,
this.oldPrice,
this.uzsPrice,
this.secondPrice,
this.secondUzsPrice,
});
factory Price.fromMap(Map<String, dynamic> data) => Price(
price: data['price'] as int?,
oldPrice: data['old_price'] as int?,
uzsPrice: data['uzs_price'] as int?,
secondPrice: data['second_price'] as int?,
secondUzsPrice: data['second_uzs_price'] as int?,
);
Map<String, dynamic> toMap() => {
'price': price,
'old_price': oldPrice,
'uzs_price': uzsPrice,
'second_price': secondPrice,
'second_uzs_price': secondUzsPrice,
};
/// `dart:convert`
///
/// Parses the string and returns the resulting Json object as [Price].
factory Price.fromJson(String data) {
return Price.fromMap(json.decode(data) as Map<String, dynamic>);
}
/// `dart:convert`
///
/// Converts [Price] to a JSON string.
String toJson() => json.encode(toMap());
Price copyWith({
int? price,
int? oldPrice,
int? uzsPrice,
int? secondPrice,
int? secondUzsPrice,
}) {
return Price(
price: price ?? this.price,
oldPrice: oldPrice ?? this.oldPrice,
uzsPrice: uzsPrice ?? this.uzsPrice,
secondPrice: secondPrice ?? this.secondPrice,
secondUzsPrice: secondUzsPrice ?? this.secondUzsPrice,
);
}
#override
bool get stringify => true;
#override
List<Object?> get props {
return [
price,
oldPrice,
uzsPrice,
secondPrice,
secondUzsPrice,
];
}
}
I then used https://docs.hivedb.dev/#/custom-objects/generate_adapter to create adapters for both of those. You can read the documentation to see how that is done using build_runner and the hive_generator packages.
In main.dart I registered both of the adapters and opened up a box with the ProductModel type from product_model.dart.
main.dart
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:test/product_model/price.dart';
import 'package:test/product_model/product_model.dart';
import 'favorite_page.dart';
import 'homepage.dart';
void main() async {
// await GetStorage.init();
await Hive.initFlutter();
Hive.registerAdapter(PriceAdapter());
Hive.registerAdapter(ProductModelAdapter());
await Hive.openBox<ProductModel>('favorites_box');
runApp(MainPage());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return GetMaterialApp(
initialRoute: '/',
getPages: [
GetPage(name: '/', page: () => MyApp()),
GetPage(name: '/main-page', page: () => MainPage()),
GetPage(name: '/favorite_page', page: () => FavoritePage()),
// Dynamic route
],
home: MainPage(),
);
}
}
listview_api.dart is mostly the same with the exception of mapping the products from listResponse to ProductModel objects.
import 'package:flutter/material.dart';
import 'package:hive/hive.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'package:test/product_model/product_model.dart';
String? stringResponse;
Map? mapResponse;
Map? dataResponse;
List? listResponse;
class ListViewAPI extends StatefulWidget {
const ListViewAPI({Key? key}) : super(key: key);
#override
_ListViewAPIState createState() => _ListViewAPIState();
}
class _ListViewAPIState extends State<ListViewAPI> {
Future apiCall() async {
http.Response response;
response =
await http.get(Uri.parse("https://api.client.macbro.uz/v1/product"));
if (response.statusCode == 200) {
setState(() {
// stringResponse = response.body;
mapResponse = jsonDecode(response.body);
listResponse = mapResponse!['products'];
listResponse =
listResponse!.map((e) => ProductModel.fromMap(e)).toList(); // Map all of the products in listResponse to a ProductModel object.
});
}
}
#override
void initState() {
super.initState();
apiCall();
}
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scrollbar(
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemBuilder: (context, index) {
return Stack(
children: [
Card(
child: Image.network(
listResponse![index].image!,
),
),
Positioned(
right: 0,
child: InkWell(
child: IconButton(
onPressed: () async {
await Hive.box<ProductModel>('favorites_box').put(
listResponse![index].image, listResponse![index]);
},
icon: Icon(
Icons.favorite_rounded,
color: Colors.red,
),
),
),
),
],
);
},
itemCount: listResponse == null ? 0 : listResponse!.length,
),
),
);
}
}
homepage.dart is unchanged.
favorite_page.dart was changed to a stateful widget and then gets the box values on init.
import 'package:flutter/material.dart';
import 'package:hive/hive.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:test/product_model/product_model.dart';
class FavoritePage extends StatefulWidget {
#override
State<FavoritePage> createState() => _FavoritePageState();
}
class _FavoritePageState extends State<FavoritePage> {
var posts;
#override
void initState() {
super.initState();
posts = Hive.box<ProductModel>('favorites_box').values.toList();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: ListView.builder(
scrollDirection: Axis.horizontal,
itemBuilder: (context, index) {
return Stack(
children: [
Card(
child: Image.network(
posts[index].image!,
),
),
Positioned(
right: 0,
child: InkWell(
child: IconButton(
onPressed: () async {
await Hive.box<ProductModel>('favorites_box')
.delete(posts[index]);
},
icon: Icon(
Icons.favorite_rounded,
color: Colors.red,
),
),
),
),
],
);
},
itemCount: posts == null ? 0 : posts.length,
),
);
}
}
I really encourage you to read the documentation on Hive as it contains a wealth of information. Another tip when coding with hive is to make sure you are clearing out the storage and cache for your emulator or physical device regularly. I have had too many headaches dealing with errors in Hive simply because I forgot to clear the storage and cache which was resulting in bad data despite having changed my source code.
I don't believe this is a problem with your code. However, I do recommend creating a model class for your data and maybe using a FutureBuilder https://api.flutter.dev/flutter/widgets/FutureBuilder-class.html.
I believe the problem is that you have not updated your AndroidManifest.xml file to allow for internet connectivity.
Try adding:
<uses-permission android:name="android.permission.INTERNET" />
to your android\app\src\main\AndroidManifest.xml, above <application.
Further reading: https://flutter-examples.com/add-permissions-in-androidmanifest-xml-file/
After taking a closer look at your issue, I think I figured out the problem.
Hive requires an init:
void main() async {
// await GetStorage.init(); // Not sure why this was here but doesn't seem to be needed.
await Hive.initFlutter();
await Hive.openBox('favorites_box');
runApp(MainPage());
}
You were also missing a comma in main_page.dart
final screens = [
HomePage(),
HomePage() <----
FavoritePage(),
HomePage()
];
For your favorites page, I replaced the ValueListenableBuilder with just a ListView.builder:
class FavoritePage extends StatelessWidget {
List posts = List.from(Hive.box('favorites_box').values);
#override
Widget build(BuildContext context) {
return Scaffold(
body: ListView.builder(
scrollDirection: Axis.horizontal,
itemBuilder: (context, index) {
return Stack(
children: [
Card(
child: Image.network(
posts[index]['image'],
),
),
Positioned(
right: 0,
child: InkWell(
child: IconButton(
onPressed: () async {
await Hive.box('favorites_box').delete(posts[index]);
},
icon: Icon(
Icons.favorite_rounded,
color: Colors.red,
),
),
),
),
],
);
},
itemCount: posts == null ? 0 : posts.length,
),
);
}
}
There is still an error when you try to use this that says that posts[index]['image'] type 'String' is not a subtype of type 'int' of 'index' but you can easily fix this by creating a model class and accessing everything with those properties. Using model class in flutter (dart) here is an example of a model class. Instead of using DocumentSnapshot, you can add a toList() or toMap() method.
Hope this helps. It is working on my emulator. but I am just printing out the full string instead of using the image in the Card child.
Example Model Class:
import 'dart:convert';
void main() async {
String data = '{"id":"626694d4f1ce2a0012f0fe1c","name":"JBL Party Box On-The-Go","slug":"jbl-party-box-on-the-go-juqgil2ep8ult","active":true,"image":"https://cdn.macbro.uz/macbro/1fad4f47-51f4-4f12-975b-657d780c98af","code":"","order":"0","cheapest_price":0,"price":{"price":520,"old_price":0,"uzs_price":5994000,"second_price":0,"second_uzs_price":7012500},"discount":0}';
var test = new ProductModel.fromJson(json.decode(data));
print(test.image);
}
class ProductModel {
String? name;
String? image;
ProductModel.fromJson(Map json) {
this.name = json['id'];
this.image = json['image'];
}
}

Flutter - Argument type 'List<List<SubCategoriesFolder>> Function(String)' can't be assigned to the parameter type

I'm trying to apply the function compute to get the data from responseJSON.
I used quicktype.io to generate the function for this purpose.
This is what i have done so far:
final subCategoriesFolder = await compute(subCategoriesFolderFromJson, responseJSON);
Error 1:
error: The argument type 'List<List<SubCategoriesFolder>> Function(String)' can't be assigned to the parameter type 'FutureOr<List<List<SubCategoriesFolder>>> Function(dynamic)'. (argument_type_not_assignable at lib\src\ui\pages\subcategories.dart:84)
Error 2:
error: Couldn't infer type parameter 'Q'.
Tried to infer 'dynamic' for 'Q' which doesn't work:
Parameter 'callback' declared as 'FutureOr<R> Function(Q)'
but argument is 'List<List<SubCategoriesFolder>> Function(String)'.
The type 'dynamic' was inferred from:
Parameter 'message' declared as 'Q'
but argument is 'dynamic'.
Consider passing explicit type argument(s) to the generic.
(could_not_infer at lib\src\ui\pages\subcategories.dart:84)
Source:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'package:flutter/foundation.dart';
// import 'dart:isolate';
// import 'package:flutter/foundation.dart';
// import 'catwidget.dart';
// To parse this JSON data, do
//
// final subCategoriesFolder = subCategoriesFolderFromJson(jsonString);
List<List<SubCategoriesFolder>> subCategoriesFolderFromJson(String str) => List<List<SubCategoriesFolder>>.from(json.decode(str).map((x) => List<SubCategoriesFolder>.from(x.map((x) => SubCategoriesFolder.fromJson(x)))));
String subCategoriesFolderToJson(List<List<SubCategoriesFolder>> data) => json.encode(List<dynamic>.from(data.map((x) => List<dynamic>.from(x.map((x) => x.toJson())))));
class SubCategoriesFolder {
SubCategoriesFolder({
this.children,
this.title,
});
List<Child> children;
String title;
factory SubCategoriesFolder.fromJson(Map<String, dynamic> json) => SubCategoriesFolder(
children: List<Child>.from(json["children"].map((x) => Child.fromJson(x))),
title: json["title"],
);
Map<String, dynamic> toJson() => {
"children": List<dynamic>.from(children.map((x) => x.toJson())),
"title": title,
};
}
class Child {
Child({
this.title,
this.uri,
this.iconuri,
this.charset,
});
String title;
String uri;
String iconuri;
String charset;
factory Child.fromJson(Map<String, dynamic> json) => Child(
title: json["title"],
uri: json["uri"],
iconuri: json["iconuri"] == null ? null : json["iconuri"],
charset: json["charset"] == null ? null : json["charset"],
);
Map<String, dynamic> toJson() => {
"title": title,
"uri": uri,
"iconuri": iconuri == null ? null : iconuri,
"charset": charset == null ? null : charset,
};
}
class Subfolder extends StatefulWidget {
#override
SubFolder createState() => SubFolder();
}
class SubFolder extends State<Subfolder> {
Future _fetchJSON() async {
var response = await http.get(
"http://10.0.2.2:5000/subcategories",
headers: {"Accept": "application/json"},
);
if (response.statusCode == 200) {
String responseBody = response.body;
//var responseJSON = json.decode(responseBody);
var responseJSON = await compute(jsonDecode, responseBody);
//final subCategoriesFolder = subCategoriesFolderFromJson(responseJSON);
final subCategoriesFolder = await compute(subCategoriesFolderFromJson, responseJSON);
print(subCategoriesFolder.runtimeType);//THis is not being set, error here
print(subCategoriesFolder);
// name = responseJSON['name'];
// avatar = responseJSON['avatar_url'];
}
return true;
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: CupertinoColors.darkBackgroundGray,
body: FutureBuilder(
future: _fetchJSON(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.data == null) {
return Center(child: Text('No data'));
} else
return Container(
child: Text(snapshot.data),
);
/*return GridView(
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
children: <Widget>[
for(var item in snapshot.data ) singleCategoryTemp(item)
],
); */
} else if (snapshot.connectionState == snapshot.error) {
return Center(
child: Text('Error: Please try again later')); // error
} else {
return Center(child: CircularProgressIndicator()); // loading
}
}),
);
}
}
You can copy paste run full code below
You can use compute(subCategoriesFolderFromJson, responseBody)
I use nested ListView to show data, you check full code
code snippet
Future<List<List<SubCategoriesFolder>>> _fetchJSON() async {
...
if (response.statusCode == 200) {
String responseBody = response.body;
return compute(subCategoriesFolderFromJson, responseBody);
}
working demo
full code
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
List<List<SubCategoriesFolder>> subCategoriesFolderFromJson(String str) =>
List<List<SubCategoriesFolder>>.from(json.decode(str).map((x) =>
List<SubCategoriesFolder>.from(
x.map((x) => SubCategoriesFolder.fromJson(x)))));
String subCategoriesFolderToJson(List<List<SubCategoriesFolder>> data) =>
json.encode(List<dynamic>.from(
data.map((x) => List<dynamic>.from(x.map((x) => x.toJson())))));
class SubCategoriesFolder {
SubCategoriesFolder({
this.children,
this.title,
});
List<Child> children;
String title;
factory SubCategoriesFolder.fromJson(Map<String, dynamic> json) =>
SubCategoriesFolder(
children:
List<Child>.from(json["children"].map((x) => Child.fromJson(x))),
title: json["title"],
);
Map<String, dynamic> toJson() => {
"children": List<dynamic>.from(children.map((x) => x.toJson())),
"title": title,
};
}
class Child {
Child({
this.title,
this.uri,
this.iconuri,
this.charset,
});
String title;
String uri;
String iconuri;
String charset;
factory Child.fromJson(Map<String, dynamic> json) => Child(
title: json["title"],
uri: json["uri"],
iconuri: json["iconuri"] == null ? null : json["iconuri"],
charset: json["charset"] == null ? null : json["charset"],
);
Map<String, dynamic> toJson() => {
"title": title,
"uri": uri,
"iconuri": iconuri == null ? null : iconuri,
"charset": charset == null ? null : charset,
};
}
class Subfolder extends StatefulWidget {
#override
SubFolder createState() => SubFolder();
}
class SubFolder extends State<Subfolder> {
Future<List<List<SubCategoriesFolder>>> _fetchJSON() async {
/*var response = await http.get(
"http://10.0.2.2:5000/subcategories",
headers: {"Accept": "application/json"},
);*/
String jsonString = '''
[[
{
"title" : "1",
"children" : [{
"title":"abc1",
"uri" : "def1",
"iconuri" : "123",
"charset" : "456"
},
{
"title":"abc2",
"uri" : "def1",
"iconuri" : "123",
"charset" : "456"
}]
},
{
"title" : "2",
"children" : [{
"title":"abc2",
"uri" : "def2",
"iconuri" : "789",
"charset" : "321"
}]
}
]]
''';
http.Response response = http.Response(jsonString, 200);
if (response.statusCode == 200) {
String responseBody = response.body;
return compute(subCategoriesFolderFromJson, responseBody);
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
//backgroundColor: CupertinoColors.darkBackgroundGray,
body: FutureBuilder(
future: _fetchJSON(),
builder: (BuildContext context,
AsyncSnapshot<List<List<SubCategoriesFolder>>> snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.none:
return Text('none');
case ConnectionState.waiting:
return Center(child: CircularProgressIndicator());
case ConnectionState.active:
return Text('');
case ConnectionState.done:
if (snapshot.hasError) {
return Text(
'${snapshot.error}',
style: TextStyle(color: Colors.red),
);
} else {
return ListView.separated(
separatorBuilder: (BuildContext context, int index) {
return SizedBox(
height: 10,
);
},
shrinkWrap: true,
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
/* Expanded(
flex: 1, child: Text(snapshot.data[index].toString())),*/
Expanded(
flex: 2,
child: Container(
height: 50,
child: ListView.separated(
separatorBuilder:
(BuildContext context,
int index) {
return SizedBox(
width: 10,
);
},
shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemCount:
snapshot.data[index].length,
itemBuilder: (context, index1) {
return Row(
mainAxisAlignment:
MainAxisAlignment.center,
crossAxisAlignment:
CrossAxisAlignment.center,
children: <Widget>[
Container(
width: 120,
child: Column(
children: <Widget>[
Text(
snapshot
.data[index]
[index1]
.title,
style: TextStyle(
color:
Colors.red),
),
Expanded(
child: ListView
.separated(
separatorBuilder:
(BuildContext
context,
int
index) {
return SizedBox(
width:
2,
);
},
shrinkWrap:
true,
scrollDirection:
Axis
.horizontal,
itemCount: snapshot
.data[
index]
[
index1]
.children
.length,
itemBuilder:
(context,
index2) {
return Row(
mainAxisAlignment: MainAxisAlignment
.spaceEvenly,
children: <
Widget>[
Text(snapshot.data[index][index1].children[index2].title,
style: TextStyle(color: Colors.red)),
]);
}),
),
],
),
)
]);
}),
),
)
])
],
);
});
}
}
}));
}
}
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: Subfolder(),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}

How to get the specific data through api by using flutter_bloc

I am beginner in flutter and working on fetching the specific data by using flutter_bloc package. I have successfully fetch the api data by using flutter_bloc in HomePage but how do i fetch the more specific data.For example in Home Page it fetch the data when i open the app and there is a button at the bottom which moves to new screen that is a Settings Screen which has Two radio buttons and one Raised Button named as Save.When i select any of the radiobutton and click on save button it should moves back to the homepage and calls the api and update the data which was already fetched in homepage. Below is the dart code and bloc code, it will be lengthy but hope you understand my code
Main.dart
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MultiBlocProvider(
providers: [
BlocProvider<PrayerBloc>(
create: (BuildContext context) => PrayerBloc(repository: PrayerRepositoryImpl()),
),
BlocProvider<MethodBloc>(
create: (BuildContext context) => MethodBloc(methodRepository: MethodRepositoryImpl()),
),
],
child: HomePage(),
);
HomePage.dart
class HomePage extends StatefulWidget {
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
PrayerBloc prayerBloc;
#override
void initState() {
super.initState();
prayerBloc = BlocProvider.of<PrayerBloc>(context);
prayerBloc.add(FetchPrayerEvent());
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Builder(
builder: (context) {
return Material(
child: Scaffold(
appBar: AppBar(
title: Text("Prayer API"),
),
body: Container(
child: BlocListener<PrayerBloc, PrayerState>(
listener: (context, state) {
if (state is PrayerErrorState) {
Scaffold.of(context).showSnackBar(
SnackBar(
content: Text(state.message),
),
);
}
},
child: BlocBuilder<PrayerBloc, PrayerState>(
builder: (context, state) {
if (state is InitialPrayerState) {
return buildLoading();
} else if (state is PrayerLoadingState) {
return buildLoading();
} else if (state is PrayerLoadedState) {
return buildArticleList(state.item);
} else if (state is PrayerErrorState) {
return buildErrorUi(state.message);
}
},
),
),
),
),
);
},
),
);
}
Widget buildLoading() {
return Center(
child: CircularProgressIndicator(),
);
}
Widget buildErrorUi(String message) {
return Center(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
message,
style: TextStyle(color: Colors.red),
),
),
);
}
Widget buildArticleList(List<Item> item) {
return ListView.builder(
itemCount: item == null ? 0 : item.length,
itemBuilder: (BuildContext ctx, int pos) {
return new Container(
child: new Center(
child: new Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
new Card(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: new Container(
child: Column(
children: <Widget>[
Padding(
padding: EdgeInsets.only(top: 10.0),
),
Row(
children: <Widget>[
Text("Fajr"),
Padding(
padding: EdgeInsets.only(left: 50.0),
),
Text(item[pos].fajr),
],
),
Row(
children: <Widget>[
Text("Dhuhr"),
Padding(
padding: EdgeInsets.only(left: 30.0),
),
Text(item[pos].dhuhr),
],
),
Builder(
builder: (context)=>
RaisedButton(
onPressed: (){
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SettingsPage()),
);
},
),
)
],
),
),
),
)
],
),
),
);
},
);
}
Prayer_bloc.dart
class PrayerBloc extends Bloc<PrayerEvent, PrayerState> {
PrayerRepository repository;
PrayerBloc({#required this.repository});
#override
PrayerState get initialState => InitialPrayerState();
#override
Stream<PrayerState> mapEventToState(
PrayerEvent event,
) async* {
if (event is FetchPrayerEvent) {
yield PrayerLoadingState();
try {
List<Item> item = await repository.getItem();
yield PrayerLoadedState(item: item);
} catch (e) {
yield PrayerErrorState(message: e.toString());
}
}
}
}
PrayerEvent.dart
abstract class PrayerEvent extends Equatable {}
class FetchPrayerEvent extends PrayerEvent {
#override
// TODO: implement props
List<Object> get props => null;
}
PrayerState.dart
abstract class PrayerState extends Equatable {
const PrayerState();
}
class InitialPrayerState extends PrayerState {
#override
List<Object> get props => [];
}
class PrayerLoadingState extends PrayerState {
#override
List<Object> get props => [];
}
class PrayerLoadedState extends PrayerState {
List<Item> item;
PrayerLoadedState({#required this.item});
#override
List<Object> get props => null;
}
class PrayerErrorState extends PrayerState {
String message;
PrayerErrorState({#required this.message});
#override
List<Object> get props => [message];
}
PrayerRepository.dart
abstract class PrayerRepository {
Future<List<Item>> getItem();
}
class PrayerRepositoryImpl implements PrayerRepository {
#override
Future<List<Item>> getItem() async {
var response = await http.get("https://muslimsalat.com/riyadh.json?key=");
if (response.statusCode == 200) {
var data = json.decode(response.body);
List<Item> item = Welcome.fromJson(data).items;
return item;
} else {
throw Exception();
}
}
}
So these dart code fetch the data from api and load in HomePage when i open the application.Now the second page which is settings page, below is the code
SettingsPage.dart
class SettingsPage extends StatefulWidget {
#override
_SettingsPageState createState() => _SettingsPageState();
}
class _SettingsPageState extends State<SettingsPage> {
int selectedRadio;
#override
void initState() {
super.initState();
selectedRadio=0;
}
setSelectedRadio(int val){
setState(() {
selectedRadio=val;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Container(
child: ListView(
children: <Widget>[
BlocBuilder<MethodBloc,MethodState>(
builder: (context,state){
return Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Container(
padding: EdgeInsets.all(15.0),
child: Text(
"Prayer Methods",
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
),
),
Column(
children: <Widget>[
RadioListTile(
value: 1,
groupValue: selectedRadio,
activeColor: Colors.black,
title: Text(
"Egyptian General Authority of Survey",
),
onChanged: (val) {
print(val);
setSelectedRadio(val);
}),
RadioListTile(
value: 2,
groupValue: selectedRadio,
activeColor: Colors.black,
title: Text(
"University Of Islamic Sciences, Karachi (Shafi)",
),
onChanged: (val) {
print(val);
setSelectedRadio(val);
}),
FloatingActionButton(
onPressed: (){
Navigator.pop(context);
BlocProvider.of<MethodBloc>(context).add(MethodChangedEvent(method: selectedRadio)); //I have try this code in onpressed but unfortunately not succeed
print(selectedRadio);
},
child: Text('Save')
)
],
),
],
);
},
)
],
),
),
);
}
}
MethodBloc.dart
class MethodBloc extends Bloc<MethodEvent, MethodState> {
MethodRepository methodRepository;
MethodBloc({#required this.methodRepository});
#override
MethodState get initialState => InitialMethodState();
#override
Stream<MethodState> mapEventToState(
MethodEvent event,
) async* {
if(event is MethodChangedEvent){
yield MethodLoadingState();
try {
List<Item> item = await methodRepository.getMethod(event.method);
yield MethodLoadedState(item: item);
} catch (e) {
yield MethodErrorState(message: e.toString());
}
}
}
}
MethodEvent.dart
abstract class MethodEvent extends Equatable {
const MethodEvent();
}
class MethodChangedEvent extends MethodEvent {
final int method;
MethodChangedEvent({this.method}) : assert(method != null);
#override
List<Object> get props => null;
}
MethodState.dart
abstract class MethodState extends Equatable {
const MethodState();
}
class InitialMethodState extends MethodState {
#override
List<Object> get props => [];
}
class MethodLoadingState extends MethodState {
#override
List<Object> get props => [];
}
class MethodLoadedState extends MethodState {
List<Item> item;
MethodLoadedState({#required this.item});
#override
List<Object> get props => null;
}
class MethodErrorState extends MethodState {
String message;
MethodErrorState({#required this.message});
#override
List<Object> get props => [message];
}
MethodRepository.dart
abstract class MethodRepository{
Future<List<Item>> getMethod(int method);
}
class MethodRepositoryImpl implements MethodRepository {
#override
Future<List<Item>> getMethod(int method) async {
var response = await http.get("https://muslimsalat.com/riyadh/$method.json?key=");
if (response.statusCode == 200) {
var data = json.decode(response.body);
List<Item> item = Welcome.fromJson(data).items;
return item;
} else {
throw Exception();
}
}
}
PrayerModel.dart
class Welcome {
String title;
String query;
String welcomeFor;
int method;
String prayerMethodName;
String daylight;
String timezone;
String mapImage;
String sealevel;
TodayWeather todayWeather;
String link;
String qiblaDirection;
String latitude;
String longitude;
String address;
String city;
String state;
String postalCode;
String country;
String countryCode;
List<Item> items;
int statusValid;
int statusCode;
String statusDescription;
Welcome({
this.title,
this.query,
this.welcomeFor,
this.method,
this.prayerMethodName,
this.daylight,
this.timezone,
this.mapImage,
this.sealevel,
this.todayWeather,
this.link,
this.qiblaDirection,
this.latitude,
this.longitude,
this.address,
this.city,
this.state,
this.postalCode,
this.country,
this.countryCode,
this.items,
this.statusValid,
this.statusCode,
this.statusDescription,
});
factory Welcome.fromJson(Map<String, dynamic> json) => Welcome(
title: json["title"],
query: json["query"],
welcomeFor: json["for"],
method: json["method"],
prayerMethodName: json["prayer_method_name"],
daylight: json["daylight"],
timezone: json["timezone"],
mapImage: json["map_image"],
sealevel: json["sealevel"],
todayWeather: TodayWeather.fromJson(json["today_weather"]),
link: json["link"],
qiblaDirection: json["qibla_direction"],
latitude: json["latitude"],
longitude: json["longitude"],
address: json["address"],
city: json["city"],
state: json["state"],
postalCode: json["postal_code"],
country: json["country"],
countryCode: json["country_code"],
items: List<Item>.from(json["items"].map((x) => Item.fromJson(x))),
statusValid: json["status_valid"],
statusCode: json["status_code"],
statusDescription: json["status_description"],
);
Map<String, dynamic> toJson() => {
"title": title,
"query": query,
"for": welcomeFor,
"method": method,
"prayer_method_name": prayerMethodName,
"daylight": daylight,
"timezone": timezone,
"map_image": mapImage,
"sealevel": sealevel,
"today_weather": todayWeather.toJson(),
"link": link,
"qibla_direction": qiblaDirection,
"latitude": latitude,
"longitude": longitude,
"address": address,
"city": city,
"state": state,
"postal_code": postalCode,
"country": country,
"country_code": countryCode,
"items": List<dynamic>.from(items.map((x) => x.toJson())),
"status_valid": statusValid,
"status_code": statusCode,
"status_description": statusDescription,
};
}
class Item {
String dateFor;
String fajr;
String shurooq;
String dhuhr;
String asr;
String maghrib;
String isha;
Item({
this.dateFor,
this.fajr,
this.shurooq,
this.dhuhr,
this.asr,
this.maghrib,
this.isha,
});
factory Item.fromJson(Map<String, dynamic> json) => Item(
dateFor: json["date_for"],
fajr: json["fajr"],
shurooq: json["shurooq"],
dhuhr: json["dhuhr"],
asr: json["asr"],
maghrib: json["maghrib"],
isha: json["isha"],
);
Map<String, dynamic> toJson() => {
"date_for": dateFor,
"fajr": fajr,
"shurooq": shurooq,
"dhuhr": dhuhr,
"asr": asr,
"maghrib": maghrib,
"isha": isha,
};
}
class TodayWeather {
int pressure;
String temperature;
TodayWeather({
this.pressure,
this.temperature,
});
factory TodayWeather.fromJson(Map<String, dynamic> json) => TodayWeather(
pressure: json["pressure"],
temperature: json["temperature"],
);
Map<String, dynamic> toJson() => {
"pressure": pressure,
"temperature": temperature,
};
}
Once you've defined the Model for the Stream in bloc, you can easily access the object using BlocBuilder. As demonstrated on the code you've shared, you're able to build a List with buildArticleList() from the Stream. To access a specific data, you can follow a similar approach for that object.