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
The problem is that you
profileVideoController.assignVideos(videos);
inside the build method. This would trigger theObx
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 aStatefulWidget
and do it in theinitState
, likeTry adding the code inside initstate within the addPostFrameCallback method like this: