1

I want to display send a request to API, to get data, display this data in a Form. Here is the code that I have.

import 'dart:io';

import 'package:flutter/material.dart';

import 'package:sample/models/item.model.dart';
import 'package:sample/models/unit.model.dart';
import 'package:sample/services/unit.service.dart';

class ItemDialog extends StatefulWidget {

  Item? item;

  ItemDialog.add({super.key}) {
    item = Item();
  }

  ItemDialog.edit(this.item, {super.key}) {
    item = item;
  }

  @override
  State<ItemDialog> createState() => _ItemDialogState(item);
}

class _ItemDialogState extends State<ItemDialog> {
  Item? item;
  _ItemDialogState(this.item);


  final _formKey = GlobalKey<FormState>();

  late Future<List<Unit>> unitList;
  Unit? unit;

  AppBar _createAppBar(BuildContext context) {
    return AppBar(
      title: widget.item?.name == null
          ? const Text("Add new item")
          : Text("Edit item ${widget.item?.name}"),
      actions: [
        ElevatedButton(
          child: const Text("Save"),
          onPressed: () {
            if (_formKey.currentState!.validate()) {
              setValueFromForm();
              Navigator.of(context).pop(item);
            }
          },
        )
      ],
    );
  }

  @override
  void initState() {
    super.initState();
    setInitialValue();
  }

  setInitialValue() {
    getAllData(widget.item!);
  }

  getAllData(Item item) {
    unitList = getAllUnits(item.house!.id);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: _createAppBar(context),
      body: SingleChildScrollView(
        child: Center(
          child: Column(
            children: [
              Padding(
                padding: const EdgeInsets.only(left: 10, right: 10),
                child: Form(
                  key: _formKey,
                  child: Column(
                    children: [
                      FutureBuilder(
                        future:unitList,
                        builder: (BuildContext context, AsyncSnapshot snapshot) {
                          return snapshot.hasData
                              ? Container(
                            child: DropdownButton<Unit>(
                              hint: Text('Make a selection'),
                              items: snapshot.data.map<DropdownMenuItem<Unit>>((item) {
                                return DropdownMenuItem<Unit>(
                                  value: item,
                                  child: Text(item.title),
                                );
                              }).toList(),
                              onChanged: (value) {
                                setState(() {
                                  unit = value;
                                  print(value);
                                });
                              },
                            ),
                          )
                              : Container(
                            child: Center(
                              child: Text('Loading...'),
                            ),
                          );
                        },
                      ),
                    ],
                  ),
                ),
              )
            ],
          )
        )
      ),
    );
  }
}

I am getting the following error:

type 'List' is not a subtype of type 'Future<List>' of 'function result'

Future<List<Unit>> getAllUnits(String? id) async {
  final response = await getDio()
      .get('/unit/house/$id');
  if (response.statusCode == 200) {
    List<Unit> list =  List<Unit>.from(response.data.map((item) => Unit.fromJson(item)).toList());
    return list;
  } else {
    throw Exception('Failed to load data');
  }
}

There are may other textfields as well as more date pickers etc. However I have removed all of this for ease of readability. Any help is appreciated.

2
  • can you include more about getAllUnits Commented Mar 28, 2023 at 19:10
  • Updated the code with getAllUnits function Commented Mar 29, 2023 at 6:59

1 Answer 1

0

I have updated the component to be as below which is working fine.

DropdownButtonFormField2(
                        decoration: const InputDecoration(
                          isDense: true,
                          contentPadding: EdgeInsets.zero,
                        ),
                          isExpanded: true,
                          hint: const Text(
                            'Select unit',
                            style: TextStyle(
                                fontSize: 14),
                          ),
                          value: unit,
                          items: unitList.map((item) => DropdownMenuItem<Unit>(
                            value: item,
                            child: Text(
                              '${item.name}',
                              style: const TextStyle(
                                fontSize: 14,
                              ),
                            ),
                          )).toList(),
                          validator: (value) {
                            if (value == null) {
                              return 'Please select unit.';
                            }
                            return null;
                          },
                          onChanged: (value) {
                            newItem?.unit = (value as Unit).id;
                            item?.unit = value as Unit;
                          },
                          buttonStyleData: const ButtonStyleData(
                            height: 60,
                            padding: EdgeInsets.only(left: 20, right: 10),
                          ),
                          iconStyleData: const IconStyleData(
                            iconSize: 30,
                          ),
                          dropdownStyleData: DropdownStyleData(
                            decoration: BoxDecoration(
                              borderRadius: BorderRadius.circular(15),
                              color: darkThemePreference.darkOrLightGrey(context),
                            ),
                          ),
                        )

This should work fine.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.