Flutter, pass datetime value to a method

835

You are using form in your class but it is not useful at all in this case. I recommend you to remove the form, then you replace the onSaved by onChanged like that :

onChanged: (value) {
setState(() {
 dateRange = value!;
});

Create a method to send your searched value :

void _sendSearch(String value) {
    _debounce.run(() {
      setState(() {
        searchedValue = value;
      });
    });
  }

You can now replace your onChanged method for the namespace :

onChanged: _sendSearch

And finally replace your extanded method by this one ( now you give to your deploymentList the dateRangeand the searchedValue:

Expanded(child: DeploymentList(searchedValue, dateRange: dateRange))

So each time you change the daterange or the searched value, the component will be rebuilt.

Share:
835
Kévin
Author by

Kévin

Updated on December 29, 2022

Comments

  • Kévin
    Kévin over 1 year

    I currently have a page where i can select a date range, after that i have a search bar, and then a listview. When i select dates, and i click on submit, dates are displayed. Now i need to pass those dates to a method, but it is received as null. It seems that i forget something to be able to use this variable..

    class HistoriquePage extends StatefulWidget {
      final String title;
      final String namespace;
    
      const HistoriquePage({Key? key, required this.title, required this.namespace})
          : super(key: key);
    
      @override
      _HistoriquePageState createState() => _HistoriquePageState();
    }
    
    class _HistoriquePageState extends State<HistoriquePage> {
      GlobalKey<FormState> myFormKey = new GlobalKey();
      DateTimeRange? dateRange;
      Post? user;
    
      void _submitForm() {
        final FormState? form = myFormKey.currentState;
        form!.save();
      }
    
      @override
      Widget build(BuildContext context) => Scaffold(
            appBar: AppBar(
              title: Text(widget.title),
            ),
            body: SafeArea(
              child: Form(
                key: myFormKey,
                child: Column(
                  children: [
                    Container(
                      child: SafeArea(
                        child: DateRangeField(
                            enabled: true,
                            initialValue: DateTimeRange(
                                start: DateTime.parse("2020-01-01"),
                                end: DateTime.now()),
                            firstDate: new DateTime(2020),
                            decoration: InputDecoration(
                              labelText: 'Interval de temps pour la recherche',
                              prefixIcon: Icon(Icons.date_range),
                              border: OutlineInputBorder(),
                            ),
                            onSaved: (value) {
                              setState(() {
                                dateRange = value!;
                              });
                            }),
                      ),
                    ),
                    Container(
                      padding: EdgeInsets.all(16),
                      child: TextField(
                          decoration: InputDecoration(
                            prefixIcon: Icon(Icons.search),
                            border: OutlineInputBorder(),
                            labelText: 'Select the namespace...',
                          ),
                          onChanged: (searchedValue) {
                            setState(() {
                              HistoriqueService.filterList(searchedValue,
                                  dateRange: dateRange);
                            });
                          }),
                    ),
                    ElevatedButton(
                      child: Text('Submit'),
                      onPressed: _submitForm,
                    ),
                    if (dateRange != null)
                      Text("Saved value is: ${dateRange.toString()}"),
                    Expanded(child: DeploymentList())
                  ],
                ),
              ),
            ),
          );
    }
    
    class HistoriqueService {
      static Future<List<User>> filterList(String value,
          {DateTimeRange? dateRange}) async {
        print("value" + value);
        if (dateRange != null) {
          print("dateRange: " + dateRange.toString());
        }
        List<User> postsList = await HttpService.fetchHistorique();
        return postsList
            .where((user) => user.name.toLowerCase().contains(value.toLowerCase()))
            .toList();
      }
    }
    

    enter image description here

    • SilkeNL
      SilkeNL almost 3 years
      If I understand correctly you can do historiqueService.yourFunction(dateRange) in this case the historiqueService is made with final HistoriqueService historiqueService = HistoriqueService()
    • Kévin
      Kévin almost 3 years
      @SilkeNL This is already what i have here ; HistoriqueService.filterList(searchedValue, dateRange: dateRange);
    • SilkeNL
      SilkeNL almost 3 years
      Are you sure it set the state right? Can you print dateRange in onChanged: (searchedValue) { setState(() { HistoriqueService.filterList(searchedValue, dateRange: dateRange); }); }),
    • Kévin
      Kévin almost 3 years
      The state for the dataRange is above here : onSaved: (value) {setState(() { dateRange = value!;}); As i said, i can see the value when i click on Submit
    • SilkeNL
      SilkeNL almost 3 years
      I understand but something isn't right in the code. To find out where, try printing dateRange in multiple places. Where is it a date and where is it null?
    • Kévin
      Kévin almost 3 years
      Text("Saved value is: ${dateRange.toString()}") is working, after i press the Submit button. It is null in the filterList method.
    • Abel Rodríguez
      Abel Rodríguez almost 3 years
      The filterList function returns a Future. Put the async modifier to the onChanged function and the await keyword when you call the filterList function, like this: onChanged: (searchedValue) async { setState(() { await HistoriqueService.filterList(searchedValue, dateRange: dateRange); });} . Hope this works!
    • Kévin
      Kévin almost 3 years
      @AbelRodríguez Hum no it breaks : ( [ERROR:flutter/lib/ui/ui_dart_state.cc(186)] Unhandled Exception: setState() callback argument returned a Future. E/flutter (27540): The setState() method on _HistoriquePageState#7bf88 was called with a closure or method that returned a Future. Maybe it is marked as "async". E/flutter (27540): Instead of performing asynchronous work inside a call to setState(), first execute the work (without updating the widget state), and then synchronously update the state inside a call to setState(). daterange is not printed
    • SilkeNL
      SilkeNL almost 3 years
      The error states the problem and possible solution: Instead of performing asynchronous work inside a call to setState(), first execute the work (without updating the widget state), and then synchronously update the state inside a call to setState(). So maybe get the value for inside the setState first, then set the state for real?
    • Abel Rodríguez
      Abel Rodríguez almost 3 years
      Just put the filterList function outside the setState , like this: onChanged: (searchedValue) async { await HistoriqueService.filterList(searchedValue, dateRange: dateRange); setState(() {});}. I already tested it and it works like a charm.