diff --git a/website/docs/providers/stream_provider.mdx b/website/docs/providers/stream_provider.mdx index 070c96797..b168a30a1 100644 --- a/website/docs/providers/stream_provider.mdx +++ b/website/docs/providers/stream_provider.mdx @@ -7,6 +7,8 @@ import TabItem from "@theme/TabItem"; import CodeBlock from "@theme/CodeBlock"; import configProvider from "!!raw-loader!/docs/providers/future_provider/config_provider.dart"; import configConsumer from "!!raw-loader!/docs/providers/future_provider/config_consumer.dart"; +import streamProvider from "!!raw-loader!/docs/providers/stream_provider/live_stream_chat_provider.dart"; +import streamConsumer from "!!raw-loader!/docs/providers/stream_provider/live_stream_chat_consumer.dart"; import { trimSnippet } from "../../src/components/CodeSnippet"; `StreamProvider` is similar to [FutureProvider] but for [Stream]s instead of @@ -42,3 +44,14 @@ Using `StreamProvider` over [StreamBuilder] has numerous benefits: [stream.periodic]: https://api.dart.dev/stable/2.15.1/dart-async/Stream/Stream.periodic.html [family]: ../concepts/modifiers/family [streambuilder]: https://api.flutter.dev/flutter/widgets/StreamBuilder-class.html + +## Usage example: live chat using sockets + +`StreamProvider` is used in when we handle stream of asynchronous data +such as Video Streaming, Weather broadcasting Apis. + +{trimSnippet(streamProvider)} + +Then, the UI can listen to live streaming chats like so: + +{trimSnippet(streamConsumer)} diff --git a/website/docs/providers/stream_provider/live_stream_chat_consumer.dart b/website/docs/providers/stream_provider/live_stream_chat_consumer.dart new file mode 100644 index 000000000..79c186f7a --- /dev/null +++ b/website/docs/providers/stream_provider/live_stream_chat_consumer.dart @@ -0,0 +1,26 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; + +import 'live_stream_chat_provider.dart'; + +/* SNIPPET START */ +Widget build(BuildContext context, WidgetRef ref) { + final liveChats = ref.watch(chatProvider); + // Like FutureProvider, it is possible to handle loading/error states using AsyncValue.when + return liveChats.when( + loading: () => const CircularProgressIndicator(), + error: (error, stackTrace) => Text(error.toString()), + data: (messages) { + // Display all the messages in a scrollable list view. + return ListView.builder( + // Show messages from bottom to top + reverse: true, + itemCount: messages.length, + itemBuilder: (context, index) { + final message = messages[index]; + return Text(message); + }, + ); + }, + ); +} diff --git a/website/docs/providers/stream_provider/live_stream_chat_provider.dart b/website/docs/providers/stream_provider/live_stream_chat_provider.dart new file mode 100644 index 000000000..d2bb3ad2a --- /dev/null +++ b/website/docs/providers/stream_provider/live_stream_chat_provider.dart @@ -0,0 +1,18 @@ +import 'dart:convert'; +import 'dart:io'; + +import 'package:flutter_riverpod/flutter_riverpod.dart'; + +/* SNIPPET START */ +final chatProvider = StreamProvider>((ref) async* { + // Connect to an API using sockets, and decode the output + final socket = await Socket.connect('my-api', 4242); + ref.onDispose(socket.close); + + var allMessages = const []; + await for (final message in socket.map(utf8.decode)) { + // A new message has been received. Let's add it to the list of all messages. + allMessages = [...allMessages, message]; + yield allMessages; + } +});