skip to Main Content

I have a function called pickDateRange and, for some reason, dateRangePicker does not update its value in widget after setState. I would like to know how to solve it. When I print the value of dateRangePicker from function body it changes, but in the widget nothing happend.

class _DealsInfoSectionState extends State<DealsInfoSection> {
  DateTimeRange dateTimeRange =
      DateTimeRange(start: DateTime.now(), end: DateTime.now());
  bool doItOnce = false;

  @override
  void initState() {
    super.initState();
    context.read<DealsBloc>().add(const FetchDeals());
  }

Future _pickDateRange(DateTimeRange dateTimeRange) async {
    DateTimeRange? newDateRange = await showDateRangePicker(
        context: context,
        initialDateRange: dateTimeRange,
        firstDate: DateTime(2010),
        lastDate: DateTime(2030),
        builder: (BuildContext? context, Widget? child) {
          return StatefulBuilder( ///<<here
              builder: (context, stateSetter) { ///<<here
                return FittedBox(
                  child: Theme(
                    data: ThemeData(
                      primaryColor: colorBlue,
                    ),
                    child: child!,
                  ),
                );
              }
          );
        });

    if (newDateRange == null) return;

    setState(() {
      dateTimeRange = newDateRange;
    });
    print(dateTimeRange);
    context.read<DealsBloc>().add(FetchDealsWithDate(
        startDate: newDateRange.start.millisecondsSinceEpoch,
        endDate: newDateRange.end.millisecondsSinceEpoch + 86400000));
  }

  @override
  Widget build(BuildContext context) {
    double width = MediaQuery.of(context).size.width;
    double height = MediaQuery.of(context).size.height;
    var income = 0.0;

    return Container(
  width: width * 0.85,
  child: BlocBuilder<DealsBloc, DealsState>(
      builder: (context, state) {
        income = 0;
        if (state.deals.isNotEmpty) {
          state.deals.forEach((element) {
            income += element.amount;
          });
          if (!doItOnce) {
            dateTimeRange = DateTimeRange(
                start: DateTime.fromMillisecondsSinceEpoch(
                    state.deals[state.deals.length - 1].dateCreated),
                end: DateTime.fromMillisecondsSinceEpoch(
                    state.deals[0].dateCreated));
            doItOnce = !doItOnce;
            print(dateTimeRange);
          }
        }
        return Column(children: [
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              Text(
                'Date: ',
                style: Theme
                    .of(context)
                    .textTheme
                    .headline6,
              ),
              InkWell(
                onTap: () => _pickDateRange(dateTimeRange),
                child: Text(
                  '${DateFormat('yyyy/MM/dd').format(
                      dateTimeRange.start)} - '
                      '${DateFormat('yyyy/MM/dd').format(
                      dateTimeRange.end)}',
                  style: Theme
                      .of(context)
                      .textTheme
                      .subtitle1
                      ?.copyWith(color: Colors.black),
                ),
              )
            ],
          )
        ]);
       }
     ),
   );
  }
}

Output:

I/flutter (25750): 2023-01-01 00:00:00.000 - 2023-01-05 10:51:12.127

When I choose a range

I/flutter (25750): 2023-01-02 00:00:00.000 - 2023-01-04 00:00:00.000

Output is right, but nothing is updated in Widget

2

Answers


  1. You are not able to see changes because Widgets are in the scope of BlocBuilder

    Mistake:

    Builder
    |_      👈 you are setting state here
    |_ BlocBuilder
       |_ Widget    👈 Your widget which is listening
    
    

    Correct Way:

    Builder
    |_              👈 setState here
    |_Widget        👈 Observable widget should be here
    |_ BlocBuilder
      |_ 
    
    Login or Signup to reply.
  2. I think this is how it should be

    ...
    
      InkWell(
                    onTap: ()async{
     DateTimeRange? newDateRange = await showDateRangePicker(
                                      context: context,
                                      initialDateRange: dateTimeRange,
                                      firstDate: DateTime(2010),
                                      lastDate: DateTime(2030),
                                      builder: (BuildContext? context, Widget? child) {
                                        return FittedBox(
                                          child: Theme(
                                            data: ThemeData(
                                              primaryColor: colorBlue,
                                            ),
                                            child: child!,
                                          ),
                                        );
    
                                      });
    
                                  if(newDateRange != null){
                                    setState(() {
                                      dateTimeRange = newDateRange;
                                    });
                                  };
            context.read<DealsBloc>().add(FetchDealsWithDate(
              startDate: newDateRange.start.millisecondsSinceEpoch,
              endDate: newDateRange.end.millisecondsSinceEpoch + 
            86400000));
     }                
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search