Issue
I’m trying to create a list using bloc and rxdart but I get an error type ‘Future’ is not a subtype of type ‘Stream?’ I am using rxdart: ^0.27.1. Just want to put the Array response in list.
My List screen
Column(
children: [
StreamBuilder(
stream: bloc.fetchPosts(),
builder: (context, AsyncSnapshot<PostModel> snapshot) {
if (snapshot.hasData) {
return buildList(snapshot);
} else if (snapshot.hasError) {
return Text(snapshot.error.toString());
}
return Center(child: CircularProgressIndicator());
},
),
],
),
PostBloc bloc
Maybe the error is here when using stream but i’m unable to find the error.
class PostBloc {
final _repository = PostRepository();
final _postsFetcher = PublishSubject<PostModel>();
Stream<PostModel> get allPosts => _postsFetcher.stream;
fetchPosts() async {
PostModel itemModel = await _repository.fetchAllPosts();
_postsFetcher.sink.add(itemModel);
}
dispose() {
_postsFetcher.close();
}
}
final bloc = PostBloc();
Post Repository
class PostRepository {
final postApiProvider = PostApiProvider();
Future<PostModel> fetchAllPosts() => postApiProvider.getPostList();
}
Post ApiProvider
class PostApiProvider {
Client client = Client();
Future<PostModel> getPostList() async {
print("entered");
final response = await client
.get(Uri.parse("https://jsonplaceholder.typicode.com/posts"));
print(response.body.toString());
if (response.statusCode == 200) {
return PostModel.fromJson(json.decode(response.body));
} else {
// If that call was not successful, throw an error.
throw Exception('Failed to load post');
}
}
}
Post Model
class Post {
late int userId;
late int id;
late String title;
late String body;
Post(result) {
userId = result['userId'];
id = result['id'];
title = result['title'];
body = result['body'];
}
int get getUserID => userId;
int get getID => id;
String get getTitle => title;
String get getBody => body;
}
class PostModel {
List<Post> results = [];
PostModel.fromJson(Map<String, dynamic> parsedJson) {
List<Post> temp = [];
for (int i = 0; i < parsedJson.length; i++) {
Post result = Post(parsedJson[i]);
temp.add(result);
}
results = temp;
}
List<Post> get getResults => results;
}
Sample Response
[
{
"userId": 1,
"id": 1,
"title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
"body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
},
{
"userId": 1,
"id": 2,
"title": "qui est esse",
"body": "est rerum tempore vitae\nsequi sint nihil reprehenderit dolor beatae ea dolores neque\nfugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis\nqui aperiam non debitis possimus qui neque nisi nulla"
}
]
Solution
The basic concept of BLoC
is first you have to put data in stream with the help of sink
and then you can get data from stream with help of Stream
.
In your code, You’re using sink function as a StreamBuilder's
stream. Which is incorrect. You should call stream like below,
StreamBuilder(
stream: bloc.allPosts, /// THIS IS STREAM OF DATA
builder: (context, AsyncSnapshot<PostModel> snapshot) {
if (snapshot.hasData) {
return buildList(snapshot);
} else if (snapshot.hasError) {
return Text(snapshot.error.toString());
}
return Center(child: CircularProgressIndicator());
},
);
Call your sink function in initState or wherever you want like this
bloc.fetchPosts(); /// THIS WILL TRIGGER YOUR API
Second issue is in model, It’s about datatype. The response you’re getting from API is List<dynamic>
and you have declared Map<String, dynamic>
. Which is incorrect. Define as below
class PostModel {
List<Post> results = [];
PostModel.fromJson(List<dynamic> parsedJson) {
List<Post> temp = [];
for (int i = 0; i < parsedJson.length; i++) {
Post result = Post(parsedJson[i]);
temp.add(result);
}
results = temp;
}
List<Post> get getResults => results;
}
And one last thing, You forgot to return your model in fetchPosts()
function
Future<PostModel> fetchPosts() async {
PostModel itemModel = await _repository.fetchAllPosts();
_postsFetcher.sink.add(itemModel);
return itemModel;
}
Answered By – Hemal Moradiya
Answer Checked By – Marie Seifert (FlutterFixes Admin)