Home > OS >  Flutter StreamProvider<List<DogModel>> can't be assigned
Flutter StreamProvider<List<DogModel>> can't be assigned

Time:01-10

I'm getting the following error The argument type 'StreamProvider<List<DogModel>>' can't be assigned to the parameter type 'Stream<List<DogModel>>?'

Happing when I try to set the stream stream: stream,

Here the stream in the widget state

final stream = StreamProvider<List<DogModel>>(
create: (context) =>
    DogFirestoreService().getDogs('GeVnAbdq9BWs1STbytlAU65qkbc2'),
initialData: const [],

);

And the widget build

Widget build(BuildContext context) {
//final test = context.watch<List<DogModel>>();
//print(test);
return SizedBox(
  width: MediaQuery.of(context).size.width,
  child: StreamBuilder<List<DogModel>>(
    stream: stream,
    builder: (context, snapshot) {
      if (!snapshot.hasData) {
        return const Text('no data');
      }

      if (snapshot.hasError) {
        return const Text('error');
      }

      if (snapshot.hasData) {
        return SizedBox(
          width: double.infinity,
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Padding(
                padding: const EdgeInsets.only(
                  top: 65.0,
                  left: 18.0,
                  right: 18.0,
                ),
                child: Text(
                  dogsCount(value.dogsList.length),
                  style: AppStyles.listsHeaderTextStyle,
                ),
              ),
              ListView.builder(
                padding: const EdgeInsets.only(
                  top: 5,
                  bottom: 20,
                  left: 15,
                  right: 15,
                ),
                shrinkWrap: true,
                physics: const NeverScrollableScrollPhysics(),
                itemCount: value.dogsList.length,
                itemBuilder: (context, index) => DogProfileCardWidget(
                  dogInfo: value.dogsList[index],
                  editProfile: openProfileScreen,
                  dogIndex: index,
                ),
              ),
            ],
          ),
        );
      }
      return const Text('data');
    },
  ),
);

} }

CodePudding user response:

Your problem is that the stream variable is a StreamProvider.

StreamProviders are not Streams, they are Widgets. So StreamBuilder does not understand what it is.

Instead you may want to do:


class Example extends StatefulWidget {
  const Example({Key? key}) : super(key: key);

  @override
  _ExampleState createState() => _ExampleState();
}

class _ExampleState extends State<Example> {
  // The stream needs to be stored in a StatefulWidfet
  // as you shouldn't create a new stream when the widget rebuild
  final stream = DogFirestoreService().getDogs('GeVnAbdq9BWs1STbytlAU65qkbc2');

  @override
  Widget build(BuildContext context) {
    return StreamBuilder<List<Dog>>(
      stream: stream,
      builder: ...,
    );
  }
}

CodePudding user response:

You don't need StreamBuilder since you're using StreamProvider. Also, it's not obvious on your code where are you placing the StreamProvider. It's a widget by the way so it should be on the widget tree above the one shown on your example. I see you're assigning it to final stream = ... but I'm not sure why because it does not return a stream.

StreamProvider will subscribe to the stream you gave (i.e., DogFirestoreService().getDogs('...')) and once the data arrives, it'll provide it to you down the tree (initially, it'll provide the initialData).

I made a simple example on DartPad that you can view here: Stream Provider Example.

Once you place the StreamProvider widget above the widget of interest, then in your build method you can access the data directly like this:

final data = context.watch<List<DogModel>>();

In the first build, you'll get the initialData you gave to StreamProvider which is an empty list. So you can do:

@override 
build(BuildContext context) {
  final data = context.watch<List<DogModel>>();
  if (data.isEmpty) {
     return const Text('no data');
  } 
  
  return SizedBox(/* the rest of your code */);
}
  •  Tags:  
  • Related