Home > Back-end >  passing a function to from one stateful widget to another
passing a function to from one stateful widget to another

Time:10-19

I need to pass a function from one stateful widget to another.

Parent widget::

the function that I am passing is the following

  void _setJobAddress(jobAddress) {
    setState(() {
      _jobAddress = jobAddress;
    });
  }

here is the button that opens the new view, this is how I am passing the function

TextButton(
   onPressed: () => {
     Navigator.push(
     context,
     MaterialPageRoute(
       builder: (context) =>
       SearchLocationScreen(_setJobAddress)))
}

this is a little bit of the child view where I need to call the function::

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

  @override
  State<SearchLocationScreen> createState() => _SearchLocationScreenState();
}

class _SearchLocationScreenState extends State<SearchLocationScreen> {
  Function setJobAddess;  // i tried adding this, but its not working

  _SearchLocationScreenState(this.setJobAddess); // i tried adding this, but its not working
  List<AutocompletePrediction> placePredictions = [];

How can I make this work so that when I click a button on the child widget, the parent function passed is called?

I tried the following:

class SearchLocationScreen extends StatefulWidget {
  const SearchLocationScreen(
    this.setJobAddess, {
    Key? key,
  }) : super(key: key);
  final setJobAddess;

  @override
  State<SearchLocationScreen> createState() => _SearchLocationScreenState();
}

class _SearchLocationScreenState extends State<SearchLocationScreen> {
  //Function setJobAddess;

  //_SearchLocationScreenState(this.setJobAddess);
  List<AutocompletePrediction> placePredictions = [];
  @override
  void initState() {
    widget.setJobAddess();
  }



... a bunch of code that is not of importance goes here

     Padding(
            padding: const EdgeInsets.all(defaultPadding),
            child: ElevatedButton.icon(
              onPressed: () async {
                print('setting job location');
                widget.setJobAddess('TEXT');
                Navigator.pop(context);
              },
              icon: Icon(Icons.home),
              label: const Text("Set job location"),
              style: ElevatedButton.styleFrom(
                backgroundColor: secondaryColor10LightTheme,
                foregroundColor: textColorLightTheme,
                elevation: 0,
                fixedSize: const Size(double.infinity, 40),
                shape: const RoundedRectangleBorder(
                  borderRadius: BorderRadius.all(Radius.circular(10)),
                ),
              ),
            ),
          ),

I got the following error::


════════ Exception caught by widgets library ═══════════════════════════════════
The following NoSuchMethodError was thrown building Builder:
Closure call with mismatched arguments: function '_CreateUpdateJobViewState._setJobAddress'
Receiver: Closure: (dynamic) => void from Function '_setJobAddress@43263735':.
Tried calling: _CreateUpdateJobViewState._setJobAddress()
Found: _CreateUpdateJobViewState._setJobAddress(dynamic) => void

The relevant error-causing widget was
MaterialApp
lib/main.dart:20
When the exception was thrown, this was the stack
#0      Object.noSuchMethod (dart:core-patch/object_patch.dart:38:5)
#1      _objectNoSuchMethod (dart:core-patch/object_patch.dart:85:9)
#2      _SearchLocationScreenState.initState
package:ijob_clone_app/…/location/location_search_screen.dart:26
#3      StatefulElement._firstBuild
package:flutter/…/widgets/framework.dart:5015
#4      ComponentElement.mount
package:flutter/…/widgets/framework.dart:4853
...     Normal element mounting (275 frames)
#279    Element.inflateWidget
package:flutter/…/widgets/framework.dart:3863
#280    MultiChildRenderObjectElement.inflateWidget
package:flutter/…/widgets/framework.dart:6435
#281    Element.updateChild
package:flutter/…/widgets/framework.dart:3592
#282    RenderObjectElement.updateChildren
package:flutter/…/widgets/framework.dart:5964
#283    MultiChildRenderObjectElement.update
package:flutter/…/widgets/framework.dart:6460
#284    Element.updateChild
package:flutter/…/widgets/framework.dart:3570
#285    ComponentElement.performRebuild
package:flutter/…/widgets/framework.dart:4904
#286    StatefulElement.performRebuild
package:flutter/…/widgets/framework.dart:5050
#287    Element.rebuild
package:flutter/…/widgets/framework.dart:4604
#288    StatefulElement.update
package:flutter/…/widgets/framework.dart:5082
#289    Element.updateChild
package:flutter/…/widgets/framework.dart:3570
#290    ComponentElement.performRebuild
package:flutter/…/widgets/framework.dart:4904
#291    Element.rebuild
package:flutter/…/widgets/framework.dart:4604
#292    ProxyElement.update
package:flutter/…/widgets/framework.dart:5228
#293    Element.updateChild
package:flutter/…/widgets/framework.dart:3570
#294    ComponentElement.performRebuild
package:flutter/…/widgets/framework.dart:4904
#295    Element.rebuild
package:flutter/…/widgets/framework.dart:4604
#296    ProxyElement.update
package:flutter/…/widgets/framework.dart:5228
#297    _InheritedNotifierElement.update
package:flutter/…/widgets/inherited_notifier.dart:107
#298    Element.updateChild
package:flutter/…/widgets/framework.dart:3570
#299    SingleChildRenderObjectElement.update
package:flutter/…/widgets/framework.dart:6307
#300    Element.updateChild
package:flutter/…/widgets/framework.dart:3570
#301    ComponentElement.performRebuild
package:flutter/…/widgets/framework.dart:4904
#302    StatefulElement.performRebuild
package:flutter/…/widgets/framework.dart:5050
#303    Element.rebuild
package:flutter/…/widgets/framework.dart:4604
#304    StatefulElement.update
package:flutter/…/widgets/framework.dart:5082
#305    Element.updateChild
package:flutter/…/widgets/framework.dart:3570
#306    SingleChildRenderObjectElement.update
package:flutter/…/widgets/framework.dart:6307
#307    Element.updateChild
package:flutter/…/widgets/framework.dart:3570
#308    SingleChildRenderObjectElement.update
package:flutter/…/widgets/framework.dart:6307
#309    Element.updateChild
package:flutter/…/widgets/framework.dart:3570
#310    ComponentElement.performRebuild
package:flutter/…/widgets/framework.dart:4904
#311    Element.rebuild
package:flutter/…/widgets/framework.dart:4604
#312    ProxyElement.update
package:flutter/…/widgets/framework.dart:5228
#313    Element.updateChild
package:flutter/…/widgets/framework.dart:3570
#314    ComponentElement.performRebuild
package:flutter/…/widgets/framework.dart:4904
#315    StatefulElement.performRebuild
package:flutter/…/widgets/framework.dart:5050
#316    Element.rebuild
package:flutter/…/widgets/framework.dart:4604
#317    BuildOwner.buildScope
package:flutter/…/widgets/framework.dart:2667
#318    WidgetsBinding.drawFrame
package:flutter/…/widgets/binding.dart:882
#319    RendererBinding._handlePersistentFrameCallback
package:flutter/…/rendering/binding.dart:378
#320    SchedulerBinding._invokeFrameCallback
package:flutter/…/scheduler/binding.dart:1175
#321    SchedulerBinding.handleDrawFrame
package:flutter/…/scheduler/binding.dart:1104
#322    SchedulerBinding._handleDrawFrame
package:flutter/…/scheduler/binding.dart:1015
#323    _invoke (dart:ui/hooks.dart:148:13)
#324    PlatformDispatcher._drawFrame (dart:ui/platform_dispatcher.dart:318:5)
#325    _drawFrame (dart:ui/hooks.dart:115:31)
════════════════════════════════════════════════════════════════════════════════
D/EGL_emulation(15747): app_time_stats: avg=25.04ms min=14.73ms max=497.29ms count=59
D/TrafficStats(15747): tagSocket(145) with statsTag=0xffffffff, statsUid=-1
D/TrafficStats(15747): tagSocket(121) with statsTag=0xffffffff, statsUid=-1

CodePudding user response:

with this you can pass it and get it from the constructor.

class SearchLocationScreen extends StatefulWidget {
  const SearchLocationScreen(this.setJobAddess,{Key? key, }) : super(key: key);
final setJobAddess;  
  @override
  State<SearchLocationScreen> createState() => _SearchLocationScreenState();
}

class _SearchLocationScreenState extends State<SearchLocationScreen> {

/*now you can use call it with like this */

@override
void initState() {
  widget.setJobAddess();
    } 



  List<AutocompletePrediction> placePredictions = [];

 // your other code

the StatefulWidget gives you the possibility to get properties from the constructor, and to access that property from the State class you need just to use widget.setJobAddess();

CodePudding user response:

this is what worked for me

    TextButton(
                          onPressed: () => {
                            Navigator.push(
                                context,
                                MaterialPageRoute(
                                    builder: (context) => SearchLocationScreen(
                                        setJobAddress: _setJobAddress)))
                          },
                          child: Text(_jobAddress),
                        ),

child widget::

class SearchLocationScreen extends StatefulWidget {
  final Function setJobAddress;
  const SearchLocationScreen({Key? key, required this.setJobAddress})
      : super(key: key);

  @override
  State<SearchLocationScreen> createState() => _SearchLocationScreenState();
}

class _SearchLocationScreenState extends State<SearchLocationScreen> {
  List<AutocompletePrediction> placePredictions = [];
  @override


...

          Expanded(
            child: ListView.builder(
                itemCount: placePredictions.length,
                itemBuilder: ((context, index) => LocationListTile(
                      press: () {
                        widget
                            .setJobAddress(placePredictions[index].description);
                        Navigator.pop(context);
                      },
                      location: placePredictions[index].description!,
                    ))),
          ),



  • Related