I'm fetching this API https://rickandmortyapi.com/api/character and putting the data inside a Stream so I can infinite scroll over a Gridview of Cards with every character. Fetching the first page with a FutureBuilder it works, but trying to use a StreamBuilder just doesn't update anything as if it wasn't receiving any data.
Here's the the Provider.dart
class CharacterProvider { final _url = 'rickandmortyapi.com'; final _characterStream = StreamController<List<Character>>.broadcast(); List<Character> _characters = []; int currentPage = 1; Function(List<Character>) get characterSink => _characterStream.sink.add; Stream<List<Character>> get characterStream => _characterStream.stream; void dispose() { _characterStream?.close(); } Future<Map<String, dynamic>> fetchData( String path, Map<String, dynamic> header) async { print(header); final response = await http.get( Uri.https(_url, 'api/$path', header), ); if (response.statusCode == 200) { final results = jsonDecode(response.body); return results; } else { throw Exception('Fallo al cargar personajes'); } } Future<List<Character>> fetchCharacters() async { final path = 'character'; final header = { 'page': currentPage.toString(), }; final data = await fetchData(path, header); final characterFetched = Characters.fromJsonList(data['results']); _characters.addAll(characterFetched.character); characterSink(_characters); if (currentPage < data['info']['pages']) { currentPage++; } return characterFetched.character; } } The stream of StreamBuilder in the widget is subscribed to characterStream but it is always on null.
class _CharacterCardsState extends State<CharacterCards> { final _scrollController = ScrollController(); Future<List<Character>> _characters; int cards; bool loading; @override void initState() { super.initState(); print('Cards: init'); _characters = initFetch(); loading = true; cards = 6; _scrollController.addListener(updateCards); } Future<List<Character>> initFetch() async { final fetch = await CharacterProvider().fetchCharacters(); return fetch; } @override Widget build(BuildContext context) { CharacterProvider().fetchCharacters(); print('Cards: build'); return GridView.builder( itemCount: cards, controller: _scrollController, itemBuilder: (context, index) { return StreamBuilder( stream: CharacterProvider().characterStream, builder: (BuildContext context, AsyncSnapshot<List<Character>> snapshot) { if (snapshot.hasData) { loading = false; final character = snapshot.data; return GestureDetector( onTap: () { cardView(context, character, index); }, child: ofCard(character, index), ); } else { return ofLoading(widget.size); } }, ); }); } On debug, the values added to the sink are non-null. The data is fetching correctly but the sink.add() doesn't seem to be working.
https://stackoverflow.com/questions/66131074/fetching-multiple-pages-from-an-api-and-adding-to-stream-sink February 10, 2021 at 12:51PM
没有评论:
发表评论