Flutter, how can I retrieve user info and display it on specific blog posts from firestore? - flutter

I'm new to dart and flutter comming from java(android). I have a list of posts, which are posted by different users. I want to display user name and user image for each post. The problem is I'm storing users in a "Users" collection and posts in a "Posts" collection. I have user id attached to each post and I can pull it(the id) together with the post details. But I can't use it(the id) to display profile info. Please help, some lines of code to give me some light will be much appreciated.
Bellow is my code to display the posts:
body: StreamBuilder(
stream: Firestore.instance.collection('Posts').snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
const Text('Loading...');
} else {
return ListView.builder(
itemCount: snapshot.data.documents.length,
itemBuilder: (context, index) {
DocumentSnapshot myPosts = snapshot.data.documents[index];
return Container(
width: MediaQuery.of(context).size.width,
//height: 350,
child: Padding(
padding: EdgeInsets.only(bottom: 8.0),
child: Center(
child: Padding(
padding: EdgeInsets.all(8.0),
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Row(
children: <Widget>[
CircleAvatar(
radius: 20.0,
backgroundColor: Colors.blueGrey,
),
Padding(
padding: const EdgeInsets.only(left: 8.0),
child: Container(
color: Colors.black45,
height: 30,
width: 2,
),
),
Padding(
padding: const EdgeInsets.only(left: 8.0),
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: <Widget>[
Text(
'user name',
style: TextStyle(
fontSize: 16.0,
fontWeight: FontWeight.bold,
color: Colors.black54,
),
overflow: TextOverflow.ellipsis,
),
Text(
'user status',
style: TextStyle(
color: Colors.grey,
fontSize: 14.0,
),
)
],
),
)
],
),
SizedBox(
height: 10.0,
),
Container(
width: MediaQuery.of(context).size.width,
//height: 200.0,
child: ClipRRect(
borderRadius: BorderRadius.circular(8.0),
child: AspectRatio(
aspectRatio: 16 / 9,
child: FadeInImage.assetNetwork(
width: MediaQuery.of(context).size.width,
placeholder: 'assets/images/loading.jpg',
image: '${myPosts['post_image']}',
fit: BoxFit.fill,
),
),
),
),
SizedBox(
height: 10.0,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Flexible(
child: Padding(
padding: const EdgeInsets.only(right: 8.0),
child: Text(
'${myPosts['post_title']}',
style: TextStyle(
fontSize: 18.0,
fontWeight: FontWeight.bold,
color: Colors.black87,
),
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
),
),
FlatButton(
child: Text(
'Download Pdf',
style: TextStyle(
fontSize: 14.0,
color: Colors.black54,
),
),
shape: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.black54, width: 1),
borderRadius: BorderRadius.circular(5),
),
padding: const EdgeInsets.fromLTRB(
15.0,
4.0,
15.0,
4.0,
),
onPressed: () {},
),
],
),
SizedBox(
height: 10.0,
),
Text(
'${myPosts['post_body']}',
style: TextStyle(
fontSize: 16.0,
),
overflow: TextOverflow.ellipsis,
maxLines: 8,
),
SizedBox(
height: 10.0,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
'Posted ' +
TimeAgo.getTimeAgo(
myPosts['post_time']),
style: TextStyle(color: Colors.grey)),
Text(
'${myPosts['comments_count']} Comment(s)',
style: TextStyle(color: Colors.grey)),
],
),
SizedBox(
height: 10.0,
),
],
),
),
),
),
);
},
);
}
return Loading();
},
),
Everything works fine, the problem is just to pull the user info. I have a class that I use to display user data on the profile page if it might be useful in this case here is the code of it below
import 'package:cloud_firestore/cloud_firestore.dart';
class ProfileService {
getProfileInfo(String uid) {
return Firestore.instance
.collection('Users')
.where('user_id', isEqualTo: uid)
.getDocuments();
}
}
Your help will be much appreciated I'm stuck.

try using this :
Future<DocumentSnapshot> _getDocument(String uid) async {
return await Firestore().collection('Users').where('user_id', isEqualTo: uid).get();
}
it will return u document snapshot which then u can use to get user information

Related

How to organize widgets on flutter?

This is my problem:
I want to achieve this design, like this:
This is my code:
#override
Widget build(BuildContext context) {
return BackdropFilter(
filter: ImageFilter.blur(sigmaX: 2, sigmaY: 2),
child: Scaffold(
backgroundColor: Colors.transparent,
body: Center(
child: Padding(
padding: const EdgeInsets.all(32.0),
child: ClipRRect(
//<---here
borderRadius: BorderRadius.circular(10),
child: Container(
height: MediaQuery.of(context).size.height,
width: 600,
decoration: const BoxDecoration(
color: Color(0xffF6F6F6),
),
child: LayoutBuilder(
builder: (context, constraints) => Stack(
children: [
Padding(
padding: const EdgeInsets.all(15.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: const [
Icon(FontAwesomeIcons.checkDouble,
size: 40, color: Color(0xffD6D6D6)),
Icon(FontAwesomeIcons.squareXmark,
size: 40, color: Color(0xff404040)),
],
),
),
Padding(
padding: const EdgeInsets.fromLTRB(15, 60, 15, 0),
child: Stack(
children: [
Center(
child: Text(
"We send you an Email",
style: TextStyle(
fontSize: 20,
fontStyle: FontStyle.normal,
fontWeight: FontWeight.normal,
color: Color(0xff3B3B3B),
),
),
),
Padding(
padding: EdgeInsets.symmetric(vertical: 8.0),
child: Divider(color: Color(0xff3B3B3B)),
),
Text(
"Please, check your Email inbox to log in and start using Pomoworko",
style: TextStyle(
fontSize: 20,
fontStyle: FontStyle.normal,
fontWeight: FontWeight.normal,
color: Color(0xff3B3B3B),
),
),
Padding(
padding: EdgeInsets.symmetric(vertical: 8.0),
child: Divider(color: Color(0xff3B3B3B)),
),
],
),
),
RiveAnimation.asset(
"img/letter_and_knife.riv",
),
],
),
),
),
),
),
),
),
);
}
I get stuck on this, I used a column, but don't work, and I don't know how to organize the widgets, what widget may be helpful to use in order to achieve the second design?
The pink color is: color: Color(0xffF4CFDD)
Thanks for considering my request.
You are using wrong widget, instead of stack, you need to use column like this:
BackdropFilter(
filter: ImageFilter.blur(sigmaX: 2, sigmaY: 2),
child: Scaffold(
backgroundColor: Colors.transparent,
body: Center(
child: Padding(
padding: const EdgeInsets.all(32.0),
child: ClipRRect(
borderRadius: BorderRadius.circular(10),
child: Container(
height: MediaQuery.of(context).size.height,
width: 600,
decoration: const BoxDecoration(
color: Color(0xffF6F6F6),
),
child: LayoutBuilder(
builder: (context, constraints) => Column(
children: [
Container(
color: Colors.white,
padding: const EdgeInsets.all(15.0),
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: const [
Icon(Icons.check,
size: 40, color: Color(0xffD6D6D6)),
Icon(Icons.close,
size: 40, color: Color(0xff404040)),
],
),
),
Padding(
padding:
const EdgeInsets.fromLTRB(15, 60, 15, 0),
child: Column(
children: [
Center(
child: Text(
"We send you an Email",
style: TextStyle(
fontSize: 20,
fontStyle: FontStyle.normal,
fontWeight: FontWeight.normal,
color: Color(0xff3B3B3B),
),
),
),
Padding(
padding:
EdgeInsets.symmetric(vertical: 8.0),
child: Divider(color: Color(0xff3B3B3B)),
),
Text(
"Please, check your Email inbox to log in and start using Pomoworko",
style: TextStyle(
fontSize: 20,
fontStyle: FontStyle.normal,
fontWeight: FontWeight.normal,
color: Color(0xff3B3B3B),
),
),
Padding(
padding:
EdgeInsets.symmetric(vertical: 8.0),
child: Divider(color: Color(0xff3B3B3B)),
),
],
),
),
Container(
color: Colors.red,
width: 100,
height: 100,
),
],
),
),
),
),
),
),
),
)

Flutter returning a bad state when firebase firestore delete is initiated

I am using Firestore as a database in my Flutter app, and I am using a StreamBuilder to access the data. But, whenever I try to do a delete operation using a button press, Flutter always returns this error:
The following StateError was thrown building StreamBuilder<DocumentSnapshot<Object?>>(dirty, state:
_StreamBuilderBaseState<DocumentSnapshot<Object?>, AsyncSnapshot<DocumentSnapshot<Object?>>>#3bac1):
Bad state: cannot get a field on a DocumentSnapshotPlatform which does not exist
but then proceeds to delete the item. I am able to add, update and read all the items in the collection, but this error always appears whenever I try to delete them. How could I make the error stop appearing?
This is the widget where the error occurs (It's quite long, I know), but I have removed some parts because they weren't very applicable or useful in this issue.
StreamBuilder<DocumentSnapshot<Map<String, dynamic>>>(
stream: FirebaseFirestore.instance
.collection('users')
.doc(widget.uid)
.collection('passwords')
.doc(widget.password['appName'])
.snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return const Center(
child: CircularProgressIndicator(),
);
} else {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const SizedBox(),
Padding(
padding: const EdgeInsets.fromLTRB(12, 12, 12, 0),
child: SizedBox.fromSize(
size: const Size.fromHeight(80),
child: Container(
decoration: BoxDecoration(
color: const Color(0xFF0C163F),
borderRadius: BorderRadius.circular(15)),
child: Row(
children: [
Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Padding(
padding: EdgeInsets.fromLTRB(16, 14, 0, 0),
child: Text(
'Login:',
style: TextStyle(color: Colors.white),
textAlign: TextAlign.left,
),
),
Padding(
padding:
const EdgeInsets.fromLTRB(18, 4, 0, 0),
child: Text(
snapshot.data!['login'],
style: const TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 16,
),
),
),
],
),
const Spacer(),
Padding(
padding: const EdgeInsets.only(right: 12.0),
child: GestureDetector(
child: const Icon(
Icons.copy,
color: Colors.white,
),
onTap: () {
Clipboard.setData(ClipboardData(
text:
snapshot.data!['login'],));
},
),
)
],
),
),
),
),
Padding(
padding: const EdgeInsets.fromLTRB(12, 12, 12, 0),
child: SizedBox.fromSize(
size: const Size.fromHeight(80),
child: Container(
decoration: BoxDecoration(
color: const Color(0xFF0C163F),
borderRadius: BorderRadius.circular(15)),
child: Row(
children: [
Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Padding(
padding: EdgeInsets.fromLTRB(16, 14, 0, 0),
child: Text('Password:',
style: TextStyle(color: Colors.white)),
),
FittedBox(
fit: BoxFit.cover,
child: Padding(
padding: const EdgeInsets.fromLTRB(
18, 4, 0, 0),
child: Text(
snapshot.data![‘password’]
style: const TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 16,
),
),
),
)
],
),
const Spacer(),
Padding(
padding: const EdgeInsets.only(right: 16.0),
child: GestureDetector(
child: const Icon(
Icons.remove_red_eye,
color: Colors.white,
),
onTap: () async {
},
),
),
Padding(
padding: const EdgeInsets.only(right: 12.0),
child: GestureDetector(
child: const Icon(
Icons.copy,
color: Colors.white,
),
onTap: () {
Clipboard.setData(ClipboardData(
text:
snapshot.data!['password']
));
},
),
)
],
),
),
),
),
Padding(
padding: const EdgeInsets.fromLTRB(20, 12, 20, 0),
child: Row(
children: const [
Text('URLs:',
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 15)),
],
),
),
Padding(
padding: const EdgeInsets.fromLTRB(5, 12, 5, 0),
child: ListView.builder(
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: snapshot.data!['url'].length,
itemBuilder: (context, index) {
List datalist = snapshot.data!['url'];
return Card(
child: ListTile(
title: Text(
datalist[index],
style: const TextStyle(
fontWeight: FontWeight.bold, fontSize: 18),
),
));
}),
)
,
const Spacer(),
Padding(
padding: const EdgeInsets.fromLTRB(12, 8, 12, 22),
child: ElevatedButton(
style: ElevatedButton.styleFrom(
minimumSize: const Size.fromHeight(50),
primary: const Color.fromARGB(255, 150, 13, 13),
shape: const RoundedRectangleBorder(
borderRadius:
BorderRadius.all(Radius.circular(10))),
),
child: const Text('Delete Password'),
onPressed: () async {
await FirebaseFirestore.instance
.collection('users')
.doc(widget.uid)
.collection('passwords')
.doc(widget.password(appname))
.delete();
},
))
],
),
);
}
}),
);
}
}
This is the Firebase Console view:
Try deleting by manually passing those arguments. I think it is not possible to delete items within a builder by referencing widget arguments.To delete any document you must know it's ID or have a DocumentReference to it. For that you just need to know the userId
FirebaseFirestore.instance
.collection('users')
.doc(userId)
.collection('favourites')
.where('id', whereIn: [...])
.get()
.then((snapshot) {
// ...
});
You may try deleting the snapshot using the following syntax
snapshot.docs[0].reference.delete(), where you can index into the object
or
snapshot.docs.get() where you can use the getter function.
You can refer link1 for Delete document by content of a field in Firestore and also may have a look at firestore doc

How to get value from reference field in firestore flutter and display in stream builder?

i have a firestore collection named 'orders'. It has user details as field name 'uid'. The field 'uid' is a reference to user data present in 'users' collections. No i have to display username along with order details. So i need to get data from the reference field. i'm using Streambuilder to display data. Here is what i did:
Widget build(BuildContext context) {
Map UserSnapshot = Map();
return Scaffold(
body: StreamBuilder(
stream:_db.collection('users').snapshots(),
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot<Map<String, dynamic>>> UsersSnapshot) {
UsersSnapshot.data?.docs.forEach((element) {
UserSnapshot[element.id] = element;
});
return StreamBuilder(
stream:_db.collection('orders').where(
'driverId', isEqualTo: sp.getString('uid')).snapshots(),
builder: (BuildContext context,
AsyncSnapshot<QuerySnapshot> OrdersSnapshot) {
if (!OrdersSnapshot.hasData) return const Text('Loading...');
return ListView.builder(
itemCount: OrdersSnapshot.data!.docs.length,
itemBuilder:(context,index) {
var documentSnapshot= OrdersSnapshot.data!.docs[index].data() as Map<String,dynamic>;
return Padding(
padding: EdgeInsets.symmetric(vertical: 20),
child: Container(
width: MediaQuery.of(context).size.width,
height: 260,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
border: Border.all(color: Colors.black38, width: 1)),
child: Column(
children: [
Row(
children: [
Padding(
padding: EdgeInsets.symmetric(vertical: 10, horizontal: 10),
child: Container(
height: 60,
width: 60,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(6),
border: Border.all(color: Colors.black12)),
child: Image.network(
'https://indiaeducationdiary.in/wp-content/uploads/2020/10/IMG-20201024-WA0014.jpg')),
),
Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Paradise Multicuisine Restaurant',
style: GoogleFonts.poppins(
fontWeight: FontWeight.bold, fontSize: 14),
overflow: TextOverflow.ellipsis,
),
Text(
'372,Kamarajar Salai, Karaikal',
style: GoogleFonts.poppins(
fontWeight: FontWeight.w400,
fontSize: 11,
color: hexStringToColor('636567')),
overflow: TextOverflow.ellipsis,
),
],
),
),
],
),
DottedLine(
dashColor: Colors.black26,
dashGapLength: 10,
),
Padding(
padding: EdgeInsets.all(20),
child: Container(
width: MediaQuery.of(context).size.height,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Icon(Icons.account_circle),
SizedBox(
width: 7,
),
Text(
UserSnapshot[documentSnapshot['uid']['fullname']] ?? 'Deleted User',
style: GoogleFonts.poppins(
fontSize: 12,
fontWeight: FontWeight.w500,
color: hexStringToColor('636567')),
),
SizedBox(width: 3),
Text(
'#'+ documentSnapshot['orderId'],
style: GoogleFonts.poppins(
fontSize: 12,
fontWeight: FontWeight.w500,
color: hexStringToColor('636567')),
)
],
),
Container(
width: MediaQuery.of(context).size.width * 0.90,
child: Row(
children: [
Icon(Icons.location_on_rounded),
SizedBox(
width: 7,
),
Expanded(
child: Text(
'6/8, RR Colony, Ambedkar Street, Karaikal',
style: GoogleFonts.poppins(
fontSize: 12,
fontWeight: FontWeight.w500,
color: hexStringToColor('636567')),
overflow: TextOverflow.clip,
maxLines: 4,
),
),
],
),
),
SizedBox(height: 20,),
Row(
children: [
Container(
decoration: BoxDecoration(
color: hexStringToColor('aeaeae'),
borderRadius: BorderRadius.circular(5)
),
width: 80,
height: 20,
child: Row (
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('3 Items',
style: GoogleFonts.poppins(fontSize: 10, fontWeight: FontWeight.w500),
)
],
),
),
SizedBox(width: 20,),
Container(
decoration: BoxDecoration(
color: hexStringToColor('aeaeae'),
borderRadius: BorderRadius.circular(5)
),
width: 80,
height: 20,
child: Row (
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text("₹"+documentSnapshot['grandTotal'].toString(),
style: GoogleFonts.poppins(fontSize: 10, fontWeight: FontWeight.w500),
)
],
),
),
],
),
Align(
child: ElevatedButton(onPressed: ()=>{},
child: Text('View Details'),
style: ElevatedButton.styleFrom(
elevation: 3,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5)
),
textStyle: GoogleFonts.poppins(fontWeight: FontWeight.w400,fontSize: 14)
),
),
alignment: Alignment.centerRight,
)
],
),
),
)
],
),
),
);
}
);
}
);
},
)
);
}}
You can iterate over the snapshots using asyncMap.
For example:
stream:_db.collection('users').snapshots().asyncMap((event) async {
event.docs.map((userDoc) {
var userData = userDoc.data() as Map<String, dynamic>;
var referenceSnapshot = userData["someReference"].get();
});
})

A RenderShrinkWrappingViewport expected a child of type RenderSliver but received a child of type RenderFlex

i am new in flutter and firebase integration. i am trying to build mobile app that connect to firestore.
i am trying to use paginate firestore in my mobile app. But i got error message that said "A RenderShrinkWrappingViewport expected a child of type RenderSliver but received a child of type RenderFlex."
this is my code
Widget build(BuildContext context) {
return Container(
child: StreamBuilder<QuerySnapshot>(
stream: FirebaseFirestore.instance
.collection('vendors')
.orderBy('shopName').snapshots(),
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapShot) {
if (snapShot.data == null) return CircularProgressIndicator();
if(snapShot.hasData){
print("error");
}
return Padding(
padding: EdgeInsets.all(8),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
RefreshIndicator(
child: PaginateFirestore(
bottomLoader: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(
Theme.of(context).primaryColor),
),
header: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding:
const EdgeInsets.only(left: 8, right: 8, top: 20),
child: Text(
'All Nearby Stores',
style: TextStyle(
fontWeight: FontWeight.w900, fontSize: 18),
),
),
Padding(
padding:
const EdgeInsets.only(left: 8, right: 8, top: 20),
child: Text(
'Find quality products near you',
style: TextStyle(
fontWeight: FontWeight.w900,
fontSize: 12,
color: Colors.grey),
),
),
],
),
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemBuilderType: PaginateBuilderType.listView,
itemBuilder: (index, context, document) => Padding(
padding: const EdgeInsets.all(4),
child: Container(
width: MediaQuery.of(context).size.width,
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(
width: 120,
height: 100,
child: Card(
child: ClipRRect(
borderRadius: BorderRadius.circular(4),
child: Image.network(
document['imageUrl'],
fit: BoxFit.fill,
),
),
),
),
SizedBox(
width: 10,
),
Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
height: 35,
child: Text(
document['shopName'],
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.bold,
),
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
),
SizedBox(
height: 3,
),
Container(
width:
MediaQuery.of(context).size.width - 250,
child: Text(
document['location'],
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.bold),
)),
SizedBox(
height: 3,
),
Row(
children: [
Icon(
Icons.star,
size: 12,
color: Colors.grey,
),
SizedBox(
width: 4,
),
Text(
'3.2',
style: TextStyle(
fontSize: 10,
),
)
],
)
],
)
],
),
),
),
query: FirebaseFirestore.instance
.collection('vendors')
.orderBy('shopName'),
listeners: [
refreshChangeListener,
],
footer: Padding(
padding: const EdgeInsets.only(top: 30),
child: Container(
child: Stack(
children: [
Center(
child: Text(
"that's al folks",
style: TextStyle(color: Colors.grey),
),
),
Image.asset(
"image/city.png",
),
Positioned(
right: 10,
top: 80,
child: Container(
width: 100,
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(
'Made By : ',
style: TextStyle(color: Colors.black),
),
Text(
"IZZILLY TEAM",
style: TextStyle(
fontWeight: FontWeight.bold,
letterSpacing: 2,
color: Colors.grey),
)
],
),
))
],
),
),
),
),
onRefresh: ()async{
refreshChangeListener.refreshed = true;
},
)
],
),
);
},
),
);
}
does anyone know how to solve this error?
thank you
According to related issues, something that your code should do is to wrap the header and footer widgets (and other box type widgets) inside a SliverToBoxAdapter. You can refer to this other question and this Github issue to see sample code which resemble yours. Wrapping your header, for example, would look like this according to the related question:
header: SliverToBoxAdapter(
child: Column(
...
),
),
You should also attach logs and error details in your question like those present in the github issue and related question I linked. It would shine more light into the details leading to the error.

"'borderRadius != null I/flutter (28205): || clipper != null': is not true" why am i getting this error?

I am trying to fetch data from an api and just show it in my list of cards. But whenever i load the app i get this error
'borderRadius != null
I/flutter (28205): || clipper != null': is not true.
and i not sure how to solve this.
I have tried making changes in the line the error has occurred but the error remains the same.
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:news/model/businessModel.dart';
import 'package:http/http.dart' as http;
class Discover extends StatefulWidget {
final Source source;
Discover({Key key, this.source}) : super(key: key);
#override
_DiscoverState createState() => _DiscoverState();
}
class _DiscoverState extends State<Discover> {
String API_KEY = '0ca85f22bce44565ba4fee8d2224adb5';
Future<List<Articles>> fetchArticleBySource() async {
final response = await http.get(
'https://newsapi.org/v2/top-headlines?
category=business&language=en&apiKey=${API_KEY}');
if (response.statusCode == 200) {
List articles = json.decode(response.body)['articles'];
return articles.map((article) => new
Articles.fromJson(article)).toList();
} else {
throw Exception('Failed to load article list');
}
}
var list_articles;
var refreshKey = GlobalKey<RefreshIndicatorState>();
#override
void initState() {
// TODO: implement initState
super.initState();
refreshListArticle();
}
Future<Null> refreshListArticle() async {
refreshKey.currentState?.show(atTop: false);
setState(() {
list_articles = fetchArticleBySource();
});
}
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(
left: 15.0,
top: 15.0,
right: 15.0,
),
child: ListView(
children: <Widget>[
topArea(),
SizedBox(
height: 10.0,
),
slideCard(),
SizedBox(
height: 5.0,
),
Padding(
padding: const EdgeInsets.only(left: 4.0),
child: Divider(),
),
recentNews(),
],
),
);
}
Widget topArea() {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
"WEDNESDAY, NOVEMBER 29",
style: TextStyle(color: Colors.grey, fontWeight:
FontWeight.bold),
),
SizedBox(
height: 5.0,
),
Text(
"TOP NEWS",
style: TextStyle(fontSize: 25.0, fontWeight: FontWeight.bold),
),
],
),
Hero(
tag: 'img',
child: InkWell(
//onTap: () => Navigator.push(context, MaterialPageRoute(builder:
(context) => )),
child: CircleAvatar(
radius: 25.0,
//backgroundColor: Colors.transparent,
backgroundImage: NetworkImage(
"https://images.pexels.com/photos/1138409/pexels-photo-
1138409.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260",
),
),
),
),
],
);
}
Widget slideCard() {
return FutureBuilder<List<Articles>>(
future: list_articles,
builder: (context, snapshot) {
if (snapshot.hasError) {
return Text("${snapshot.error}");
} else if (snapshot.hasData) {
List<Articles> articles = snapshot.data;
return Container(
height: 310.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(0.0),
),
child: ListView(
scrollDirection: Axis.horizontal,
children: articles
.map((article) => GestureDetector(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Expanded(
child: Card(
elevation: 3.0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
child: ClipRRect(
clipper: ,
child: article.urlToImage != null
? Image.network(article.urlToImage)
: Image.asset('images/logo.jpg'),
),
),
),
SizedBox(
height: 10.0,
),
Padding(
padding: const EdgeInsets.only(left: 4.0),
child: Text("${article.title}",
style: TextStyle(
color: Colors.blueAccent,
fontSize: 12.0,
fontWeight: FontWeight.bold),
),
),
SizedBox(
height: 10.0,
),
Padding(
padding: const EdgeInsets.only(left: 4.0),
child: Text(
"${article.description}",
style: TextStyle(
color: Colors.black,
fontSize: 14.0,
fontWeight: FontWeight.bold),
),
),
],
),
))
.toList(),
),
);
}
return CircularProgressIndicator();
},
);
}
Widget recentNews() {
return Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.only(left: 4.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
"Recent News",
style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold),
),
Align(
alignment: Alignment.centerRight,
child: Text(
"See All",
style: TextStyle(color: Colors.lightBlueAccent),
),
)
],
),
),
SizedBox(
height: 7.0,
),
Container(
height: 200.0,
child: ListView(
scrollDirection: Axis.horizontal,
children: <Widget>[
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Expanded(
child: Card(
elevation: 3.0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
child: ClipRRect(
child: Image.network(
"https://images.pexels.com/photos/935789/pexels-photo-935789.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260"),
borderRadius: BorderRadius.circular(10.0),
),
),
),
SizedBox(
height: 10.0,
),
Padding(
padding: const EdgeInsets.only(left: 4.0),
child: Text(
"STARTUPS",
style: TextStyle(
color: Colors.blueAccent,
fontSize: 12.0,
fontWeight: FontWeight.bold),
),
),
SizedBox(
height: 10.0,
),
Padding(
padding: const EdgeInsets.only(left: 4.0),
child: Text(
"Top startups that are \nchanging the way we travel",
style: TextStyle(
color: Colors.black,
fontSize: 15.0,
fontWeight: FontWeight.bold),
),
),
],
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Expanded(
child: Card(
elevation: 3.0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
child: ClipRRect(
child: Image.network(
"https://images.pexels.com/photos/935789/pexels-photo-935789.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260"),
borderRadius: BorderRadius.circular(10.0),
),
),
),
SizedBox(
height: 10.0,
),
Padding(
padding: const EdgeInsets.only(left: 4.0),
child: Text(
"STARTUPS",
style: TextStyle(
color: Colors.blueAccent,
fontSize: 12.0,
fontWeight: FontWeight.bold),
),
),
SizedBox(
height: 10.0,
),
Padding(
padding: const EdgeInsets.only(left: 4.0),
child: Text(
"Top startups that are \nchanging the way we travel",
style: TextStyle(
color: Colors.black,
fontSize: 15.0,
fontWeight: FontWeight.bold),
),
),
],
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Expanded(
child: Card(
elevation: 3.0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
child: ClipRRect(
child: Image.network(
"https://images.pexels.com/photos/935789/pexels-photo-935789.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260"),
borderRadius: BorderRadius.circular(10.0),
),
),
),
SizedBox(
height: 10.0,
),
Padding(
padding: const EdgeInsets.only(left: 4.0),
child: Text(
"STARTUPS",
style: TextStyle(
color: Colors.blueAccent,
fontSize: 12.0,
fontWeight: FontWeight.bold),
),
),
SizedBox(
height: 10.0,
),
Padding(
padding: const EdgeInsets.only(left: 4.0),
child: Text(
"Top startups that are \nchanging the way we travel",
style: TextStyle(
color: Colors.black,
fontSize: 15.0,
fontWeight: FontWeight.bold),
),
),
],
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Expanded(
child: Card(
elevation: 3.0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
child: ClipRRect(
child: Image.network(
"https://images.pexels.com/photos/935789/pexels-photo-935789.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260"),
borderRadius: BorderRadius.circular(10.0),
),
),
),
SizedBox(
height: 10.0,
),
Padding(
padding: const EdgeInsets.only(left: 4.0),
child: Text(
"STARTUPS",
style: TextStyle(
color: Colors.blueAccent,
fontSize: 12.0,
fontWeight: FontWeight.bold),
),
),
SizedBox(
height: 10.0,
),
Padding(
padding: const EdgeInsets.only(left: 4.0),
child: Text(
"Top startups that are\n changing the way we travel",
style: TextStyle(
color: Colors.black,
fontSize: 15.0,
fontWeight: FontWeight.bold),
),
),
],
),
],
),
),
],
);
}
}
If you look closely, you will see one ClipRRect whose clipper is empty, thus null.
According to the error message, if the clipper is null, then you have to specify a borderRadius.
child: ClipRRect(
clipper: ,
child: article.urlToImage != null
? Image.network(article.urlToImage)
: Image.asset('images/logo.jpg'),
),