what does type 'Future<dynamic>' is not a subtype of type 'Stream<dynamic>?' means?
Your displayPercentage
function is marked as async
which makes whatever the function returns wrapped
into a Future
automaticallu.
You are returning a Widget
which makes the function's return type Future<Widget>
. But since you have not mentioned it specifically while defining the function, dart
is assuming it to Future<dynamic>
.
Now, coming to your StreamBuilder
, the parameter stream
is supposed to be assigned a Stream
. But you are assigning it your function which is actually a Future<dynamic>
.
This is why it is giving the error saying that, it expects a Stream<dynamic>
but you are giving it a Future<dynamic>
and since Future
is not a sub class
that extends from Stream
, the error says Future<dynamic> is not a subtype of type Stream<dynamic>
.
To fix this, change your StreamBuilder
into a FutureBuilder
like this,
@override
Widget build(BuildContext context) {
return Container(
child: SafeArea(
child: FutureBuilder(
future: displayPercentage(),
builder: (context, snapshot) {
// since futures dont immediately give a value, if data is null the show loader
if (snapshot.data == null) return CircularProgressIndicator();
// Since data is not null, we can return Scaffold
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.lightGreen,
title: Text('Student Welcome'),
actions: <Widget>[
TextButton.icon(
onPressed: () async {
// await _auth.signOut();
Navigator.of(context).pushNamed('/homepage');
},
icon: Icon(Icons.person),
label: Text('Logout'))
],
),
// Since your Future holds the Center widget that you are sending, use it like this
body: snapshot.data,
);
},
),
),
);
}
Learn
Updated on December 30, 2022Comments
-
Learn over 1 year
Can someone please let me know where im doing wrong and what changes have to be done in the code in order to overcome this error of 'Future' is not a subtype of type 'Stream?'.Earlier the error was like Future' is not a subtype of type 'Widget' for which i wrapped the wwidget undet the StreamBuilder.Doing so resulted in this error.
The below is the code which results in this error
class _StudentDashboardState extends State<StudentDashboard> { userdetails userdetail; String res; final FirebaseAuth _firebaseAuth = FirebaseAuth.instance; final CollectionReference student_details = FirebaseFirestore.instance.collection('students'); final CollectionReference tutor_details = FirebaseFirestore.instance.collection("tutors"); String uid = FirebaseAuth.instance.currentUser.uid; @override void initState() { super.initState(); } displayPercentage() async { var percentage = 0.0; var totalClassesTook; var totalClassesAttended; try { totalClassesTook = await tutor_details.doc(uid).get().then((doc) async { var val = await doc.data()['TotalClassesTook']; return val; }); totalClassesTook = await totalClassesTook == null ? 0 : totalClassesTook; totalClassesAttended = await student_details.doc(uid).get().then((doc) async { var val = await doc.data()['TotalClassesAttended']; return val; }); totalClassesAttended = await totalClassesAttended == null ? 0 : totalClassesAttended; percentage = await ((totalClassesAttended / totalClassesTook) * 100.0) / 100.0; } catch (e) { percentage = 0.0; } return Center( child: ListView(children: <Widget>[ Padding( padding: EdgeInsets.symmetric(vertical: 150.0), child: new CircularPercentIndicator( radius: 120.0, lineWidth: 13.0, animation: true, percent: percentage, center: new Text( "$percentage", style: new TextStyle(fontWeight: FontWeight.bold, fontSize: 20.0), ), footer: Padding( padding: EdgeInsets.symmetric(horizontal: 10.0, vertical: 10.0), child: new Text( "Attendance Percentage", style: new TextStyle(fontWeight: FontWeight.bold, fontSize: 17.0), ), ), circularStrokeCap: CircularStrokeCap.round, progressColor: Colors.purple, ), ), ]), ); } @override Widget build(BuildContext context) { return Container( child: SafeArea( child: StreamBuilder( stream: displayPercentage(), builder: (context, snapshot) { return Scaffold( appBar: AppBar( backgroundColor: Colors.lightGreen, title: Text('Student Welcome'), actions: <Widget>[ TextButton.icon( onPressed: () async { await _auth.signOut(); Navigator.of(context).pushNamed('/homepage'); }, icon: Icon(Icons.person), label: Text('Logout')) ], ), body: displayPercentage(), ); }), ), );
}
-
Learn almost 3 yearsgreat! That worked. But
var val = await doc.data()['TotalClassesAttended'];
in the displayPercentage() function changes dynamically , those realtime changes will reflect by using FutureBuilder? If not what is the alternative please let me know -
Nisanth Reddy almost 3 yearsIn that case, you would still need to use
StreamBuilder
but you should get thesnapshot
instead ofdata
. I suggest once you go thorugh the docs for getting realtime updates. If it is confusing tell me, Ill update the answer. -
Learn almost 3 yearsi have gone through the doc of StreamBuilder, but I'm a bit confused how can i use this in my case,in my code as im calling a displayPercentage() function. I'm unable to call the same function in "stream" of StreamBuilder.
-
Nisanth Reddy almost 3 yearsGive me a few minutes, I will create a chat room and tell you there.
-
Nisanth Reddy almost 3 years
-
Learn almost 3 yearsI must have atleast 20 reputation on Stack Overflow to be able to join chatroom?
-
Nisanth Reddy almost 3 yearsI have upvoted your question, you must be more than 20 now
-
Learn almost 3 yearsLet us continue this discussion in chat.