skip to Main Content

First of all a big request to solve my problem as i am trying since yesterday and almost more than 12 hours gone and seeing no hope…

My query is very simple, and i am doing such filters in other projects also and all time gone easy but this time i dont understand why i am getting setState error

after adding a video and if restart app it works fine..means i have to restart app whenever i add new video

setState() or markNeedsBuild() called during build.

Let me explain what is my project

I have two screen one for adding video and another is for all video list screen

its showing no error until i add new video.. here both screen has no connection with each other…

in all video screen i am using future builder to get all videos from collection and than passing allvideo list to a custom widget named ‘ShowAllVideos’ and here i am calling filter controller and passing all videos to filter’s rxList for filtering by likes in assending and descending order

this error comes only after adding video and this is what i cant understand because there is no connection with that screen…while tapping on navigationBar Item i am opening screen of allvideo list…

and this is my future function for getting all videos

Future<List<VideoModel>> fetAllVideos() async{
    try{
      final videoList=await videoRepo.fetchFollowingVideos();
      return videoList;
    }catch(e){
      MyHelperFunction.showSnackbar(e.toString());
      return [];
    }
  }

here is my all video screen coding and where i am calling ShowFilteredVideos widget and passing all video data,

class AllVideosScreen extends StatelessWidget {
  const AllVideosScreen({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    final controller=Get.put(VideoController());
    return Scaffold(
      body: SingleChildScrollView(
        child: Column(children: [
          FutureBuilder(
            future: controller.fetchFollowingVideos(),
            builder: (context,snapshot){
              final widget=MyHelperFunction.futureBuilderState(snapshot: snapshot);
              if(widget!=null) return widget;
              final videos=snapshot.data!;
              return ShowFilteredVideos(videos: videos);
            },
          )
        ],),
      ),
    );
  }
}

class ShowFilteredVideos extends StatelessWidget {
  final List<VideoModel> videos;
  const ShowFilteredVideos({Key? key, required this.videos}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    final profileVideoController = Get.put(ProfileVideoController());
    profileVideoController.assignVideos(videos);

    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
      
        Obx(() => MyGridView(
          itemCount: profileVideoController.videoList.length,
          itemBuilder: (_, index) {
            final video = profileVideoController.videoList[index];
            return CircularImage(
              imageUrl: video.videoUrl,
              isNetworkImage: true,
              fit: BoxFit.fill,
              onTap: () {
                //controller.openImage(video.videoUrl);
              },
            );
          },
          mainAxisExtent: 200,
        ))
      ],
    );
  }
}

this is controller for filtering videos based on likes sorting

class ProfileVideoController extends GetxController
{
  RxList<VideoModel> videoList=<VideoModel>[].obs;
  RxString selectedFilterOption='Popular'.obs;

  void filterVideos(String option)
  {
    selectedFilterOption.value=option;
    switch(option)
    {
      case 'Popular':
        videoList.sort((a,b)=>b.likes.length.compareTo(a.likes.length));
        break;
      case 'All':
        videoList.sort((a,b)=>a.likes.length.compareTo(b.likes.length));
        break;
      default:
        videoList.sort((a,b)=>a.likes.length.compareTo(b.likes.length));
    }


  }



  void assignVideos(List<VideoModel> videos)
  {
    videoList.assignAll(videos);
    filterVideos('Popular');
  }

}

2

Answers


  1. The problem is that you profileVideoController.assignVideos(videos); inside the build method. This would trigger the Obx to rebuild while it’s still being build. In general it’s bad to do any processing inside the build method because a rebuild could be triggered at any time. I’d suggest to rework it to a StatefulWidget and do it in the initState, like

    class ShowFilteredVideos extends StatefulWidget {
      final List<VideoModel> videos;
      const ShowFilteredVideos({Key? key, required this.videos}) : super(key: key);
    
      @override
      State<ShowFilteredVideos> createState() => _ShowFilteredVideosState();
    }
    
    class _ShowFilteredVideosState extends State<ShowFilteredVideos> {
      final profileVideoController = Get.put(ProfileVideoController());
      
      @override
      void initState() {
        profileVideoController.assignVideos(widget.videos);
        super.initState();
      } 
      
      @override
      Widget build(BuildContext context) {
        return Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
    
            Obx(() => MyGridView(
              itemCount: profileVideoController.videoList.length,
              itemBuilder: (_, index) {
                final video = profileVideoController.videoList[index];
                return CircularImage(
                  imageUrl: video.videoUrl,
                  isNetworkImage: true,
                  fit: BoxFit.fill,
                  onTap: () {
                    //controller.openImage(video.videoUrl);
                  },
                );
              },
              mainAxisExtent: 200,
            ))
          ],
        );
      }
    }
    
    Login or Signup to reply.
  2. Try adding the code inside initstate within the addPostFrameCallback method like this:

    @override
    void initState() {
            super.initState();
            WidgetsBinding.instance
                .addPostFrameCallback((_) {
                  profileVideoController.assignVideos(widget.videos);
                },);
          }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search