Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

flutter provider MultiProvider using StreamProvider

I am developing a Flutter app using Provider (provider: 3.0.0+1). I am using MultiProvider using StreamProvider with controller. But I am always getting an error.

Below is my code

main.dart

Widget build(BuildContext context) {
return MultiProvider(
  providers: [
    StreamProvider<RecipeStreamService>.value(value: RecipeStreamService().controllerOut)
  ],
  child: MaterialApp(
        debugShowCheckedModeBanner: false,
        title: 'Home Food',
        routes: {
          '/register': (BuildContext context) => RegisterPage(),
          '/login': (BuildContext context) => LoginPage()
        },
        theme: ThemeData(
          primaryColor: Colors.lightBlue[300],
          accentColor: Colors.green[300],
          textTheme: TextTheme(
            headline: TextStyle(fontSize: 42.0, fontWeight: FontWeight.bold, color: Colors.black54),
            title: TextStyle(fontSize: 22.0, fontStyle: FontStyle.italic),
            body1: TextStyle(fontSize: 18.0),
            button: TextStyle(fontSize: 20.0,fontWeight: FontWeight.normal, color: Colors.white)
          )
        ),
        home: HomePage(title: 'Home'),
      ),
  );
}

RecipeStreamService.dart

class RecipeStreamService {
   List<Recipe> _recipes = <Recipe>[];

   final _controller = StreamController<List<Recipe>>.broadcast();
   get controllerOut => _controller.stream;
   get controllerIn => _controller.sink;

   RecipeStreamService() {
      getRecipes();
   }

   addNewRecipe(Recipe recipe) {
     _recipes.add(recipe);
    controllerIn.add(_recipes);
  }

  getRecipes() async{
     List<Map<String, dynamic>> result = await ApiService().getRecipes();
     List<Recipe> data = result.map((data) => Recipe.fromMap(data)).toList();
     data.map((f) => addNewRecipe(f));
 }

 void dispose() {
   _controller.close();
 }
}

But I Am always getting this error:

type '_BroadcastStream<List<Recipe>>' is not a subtype of type 'Stream<RecipeStreamService>'
I/flutter (16880): When the exception was thrown, this was the stack:
I/flutter (16880): #0      MyApp.build (package:app_recipe/main.dart:20:80)

Line: 20:80 in main.dart is (RecipeStreamService().controllerOut)

****** UPDATE ******

Changed Multiprovider to below code

 providers: [
    StreamProvider<List<Recipe>>.value(value: RecipeStreamService().controllerOut)
  ],

Also in HomePage.dart, where I use it, I have

final recipeService = Provider.of<List<Recipe>>(context);

Now, recipeService is always coming as null

Thanks

like image 941
user280960 Avatar asked Jul 31 '19 02:07

user280960


People also ask

How does MultiProvider work Flutter?

MultiProvider class Null safety A provider that merges multiple providers into a single linear widget tree. It is used to improve readability and reduce boilerplate code of having to nest multiple layers of providers. The widget tree representation of the two approaches are identical.

What is Streamprovider Flutter?

StreamsProvider is a Flutter widget which provides a provider to its children via Provider. of<T>(context) . It is used as a dependency injection (DI) widget so that a single instance of a provider can be provided to multiple widgets within a subtree.

How do you use provider value in Flutter?

Example Using Provider So, first to get the String value created in the main. dart , all we have to do is call Provider. of<String>(context) , the of() method here will obtain the nearest Provider up its widget tree and returns its value.


1 Answers

The reason you are seeing your error is because the type parameter you are passing to StreamProvider<T> as T is not matching what you are returning to create.

In this case, you want to stream values of type List<Recipe>.
Therefore, you should also pass that for the generic type:

StreamProvider<List<Recipe>>.value(value: stream)

Where the stream is your List<Recipe> stream.


If Provider.of<List<Recipe>>(context) is returning null for you, it means that you have not added a value to the stream.

If you want to have something other than null before you stream emits a value, you can pass initialValue:

StreamProvider<List<Recipe>>.value(
  value: stream,
  initialValue: initialRecipes,
)
like image 110
creativecreatorormaybenot Avatar answered Oct 11 '22 15:10

creativecreatorormaybenot