skip to Main Content

I would like to break down my Scaffold into smaller pieces for easy read. I separate widgets into functions and return to the scaffold tree. But I don’t know how to make use of the function declared inside the stateful widget which need to setState the UI.

Part of my code:

Future<List<dataRecord>>? dataList;

class _clientDetailState extends State<clientDetail> {
  @override
  void initState() {
    super.initState();
  }

  List<dataRecord> parseJson(String responseBody) {
    final parsed =
        convert.jsonDecode(responseBody).cast<Map<String, dynamic>>();
    return parsed.map<dataRecord>((json) => dataRecord.fromJson(json)).toList();
  }

  Future<List<dataRecord>> fetchData(http.Client client) async {
    final response = await client
        .get(Uri.parse('test.php'));
    return parseJson(response.body);
  }

  Body: myButton,
        ListView,
Widget myButton() {
  return TextButton(
    child: Text('test'),
    onTap: () {
      dataList = fetchData(http.Client());   //Method not found
    },
}

2

Answers


  1. Here is simple way to do

    class ClientDetail extends StatefulWidget {
      const ClientDetail({Key? key}) : super(key: key);
    
      @override
      State<ClientDetail> createState() => _ClientDetailState();
    }
    
    class _ClientDetailState extends State<ClientDetail> {
    
      List<dataRecord> dataList = [];
    
      @override
      Widget build(BuildContext context) {
        return ListView(
      children: [
          myButton(),
          ...dataList.map((e) => Text(e)).toList(),
         ],
        );
      }
    
      List<dataRecord> parseJson(String responseBody) {
        final parsed =
            convert.jsonDecode(responseBody).cast<Map<String, dynamic>>();
        return parsed.map<dataRecord>((json) => dataRecord.fromJson(json)).toList();
      }
    
      Future<List<dataRecord>> fetchData(http.Client client) async {
        final response = await client.get(Uri.parse('test.php'));
        return parseJson(response.body);
      }
    
      Widget myButton() {
        return TextButton(
            child: const Text('test'),
            onPressed: () async {
              setState(() async {
                dataList = await fetchData(http.Client());
              });
            });
      }
    }
    

    Tip: always start class name with capital letter, e.g. ClientDetail instead of clienDetail also DataRecord instead of dataRecord

    Regards

    Login or Signup to reply.
  2. You can pass your actual function as a parameter to the widget’s function and then call it directly from state;

    Body: myButton(onPressed: () => fetchData(http.Client())),
    ListView,
    
    Widget myButton({required void Function()? onPressed}) {
      return TextButton(
        child: Text('test'),
        onPressed: onPressed,
      );
    }
    
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search