Search code examples
flutterprovider

convert StreamBuilder to StreamProvider


I have a StreamBuilder like this:

StreamBuilder<List<AuthInfo>>(
            stream: myDatabase.authInfosDao.watch(),
            builder: (context, snapshot) => (snapshot.data?.length ?? 0) > 0
                ? Home()
                : Auth()),

and I want to redo it into a Stream Provider and that's what happened:

StreamProvider<List<AuthInfo>>.value(
            value: myDatabase.authInfosDao.watch(),
            initialData: [],
            builder: (BuildContext context, AsyncSnapshop snapshot)...

and I can't figure out how to use the data that came in "Value" to load the desired page since there is no snapshot in StreamProvider


Solution

  • The StreamProvider will rebuild the widget every time new data arrives on the stream. It functions similar to ChangeNotificationProvider which does not generate a new change put updates data that the provider is listen on.

    dependencies:
      flutter:
        sdk: flutter
      provider: ^6.0.2
    
    import 'package:flutter/material.dart';
    import 'package:provider/provider.dart';
    
    void main() {
      runApp(
        const MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({Key? key}) : super(key: key);
    
      // This widget is the root of your application.
      @override
      Widget build(BuildContext context) {
        return
        StreamProvider<ModelObject>(
          initialData: ModelObject(value:0),
          create:(_)=>createStream(),
          child:  MaterialApp(
            home: Test_StreamProviderWidget(),
          ));
        
      }
    }
    
    class ModelObject{
    
      ModelObject({this.value});
      int ? value;
    }
    Stream<ModelObject> createStream(){
      return 
      Stream<ModelObject>.periodic( Duration(seconds:1), (currentPeriodicValue)=>ModelObject(value:currentPeriodicValue+1)).take(10000);
    }
    
    class Test_StreamProviderWidget extends StatefulWidget {
      Test_StreamProviderWidget({Key? key}) : super(key: key);
    
      @override
      State<Test_StreamProviderWidget> createState() => _Test_StreamProviderWidgetState();
    }
    
    class _Test_StreamProviderWidgetState extends State<Test_StreamProviderWidget> {
      @override
      Widget build(BuildContext context) {
        return Scaffold(appBar: AppBar(title:Text("stream provider")),body:
        Consumer<ModelObject>(
          builder:(context, model, child) {
            return 
            Center(child:Column(
              mainAxisAlignment: MainAxisAlignment.center,
              crossAxisAlignment: CrossAxisAlignment.center,
              children: [
            
            Text('${model.value.toString()}',style: Theme.of(context).textTheme.headline2,)
    
            ],));
            
          },
        
        )
        )
        ;
      }
    }