title: How to create a form using dynamic fields from a JSON array in Flutter
body: <p>I want to create a form with dynamic fields. The fields are fetched from a database; these are determined by a user on the web application and then displayed to another user on the mobile application so the fields keep changing.
  Although there are no errors in the code, the form does not display. I have simplified it to a single input field so as to test the logic. Below is what I have tried so far:</p>
  <p>the file to create the form :</p>
  <pre><code>import 'dart:convert';
  
  import 'package:flutter/material.dart';
  import 'package:mne/Network/api.dart';
  
  import 'form_model.dart';
  
  class CreateForm extends StatefulWidget {
    const CreateForm({Key? key}) : super(key: key);
  
    @override
    State&lt;CreateForm&gt; createState() =&gt; _CreateFormState();
  }
  
  class _CreateFormState extends State&lt;CreateForm&gt; {
    late List&lt;Map&lt;String, dynamic&gt;&gt; _values;
  
    final List&lt;FormFields&gt; _formFields = &lt;FormFields&gt;[];
  
    @override
    void initState() {
      super.initState();
      _values = [];
    }
  
    Future&lt;List&lt;FormFields&gt;&gt; _fetchFormFields() async {
      var res = await Network().getData('company/fields');
      var fields = &lt;FormFields&gt;[];
      if (res.StatusCode == 200) {
        var body = json.decode(res.body);
        var tdata = body['data'];
        var formsJson = tdata;
        for (var formJson in formsJson) {
          fields.add(FormFields.fromJson(formJson));
        }
      }
      return fields;
    }
  
    _displayForm(index) {
      _fetchFormFields().then((value) {
        _formFields.addAll(value);
      });
  
      if (_formFields[index].type == &quot;text&quot;) {
        return Padding(
            padding: const EdgeInsets.all(8),
            child: TextFormField(
              decoration: InputDecoration(
                labelText: _formFields[index].name,
                enabledBorder: OutlineInputBorder(
                    borderSide: const BorderSide(color: Colors.green),
                    borderRadius: BorderRadius.circular(10)),
              ),
              onChanged: (val) {},
            ));
      }
    }
  
    @override
    Widget build(BuildContext context) {
      return Scaffold(
          body: Container(
              alignment: Alignment.center,
              padding: const EdgeInsets.all(10),
              child: Column(
                children: [
                  Flexible(
                      child: ListView.builder(
                          shrinkWrap: true,
                          itemCount: _formFields.length,
                          itemBuilder: (context, index) {
                            return _displayForm(index);
                          }))
                ],
              )));
    }
  }
  </code></pre>
  <p>the form model:</p>
  <pre><code>  class FormFields {
    String name;
    String type;
    String option;
  
    FormFields({required this.name, required this.type, required this.option});
  
    factory FormFields.fromJson(Map&lt;String, dynamic&gt; json) =&gt; FormFields(
          name: json['name'],
          type: json['type'],
          option: json['option'],
        );
  
    Map&lt;String, String&gt; toJson() =&gt;
        {'name': name, 'type': type, 'option': option};
  }
  </code></pre>
  <p>I want a circular progress indicator to show loading. I also want the user to move from the login directly to a display of the form so I put the create form class inside another one, to make it easier to reference in the login button. I called it test :</p>
  <pre><code>import 'package:flutter/material.dart';
  import 'package:mne/Forms/create_form.dart';
  
  class Test extends StatefulWidget {
    const Test({Key? key}) : super(key: key);
  
    @override
    State&lt;Test&gt; createState() =&gt; _TestState();
  }
  
  class _TestState extends State&lt;Test&gt; {
    bool _isLoading = true;
  
    @override
    Widget build(BuildContext context) {
      return Scaffold(
          body: Column(children: [
        if (_isLoading)
          Container(
              alignment: Alignment.center,
              child: ElevatedButton(
                child: const Text('Add Form'),
                onPressed: () async {
                  setState(() {
                    _isLoading = false;
                  });
                  await Navigator.push(
                  context,
                  MaterialPageRoute(
                      builder: (context) =&gt; const CreateForm()));;
                  if (!mounted) return;
                  setState(() {
                    _isLoading = true;
                  });
                },
              ))
        else
          const Center(
            child: CircularProgressIndicator(backgroundColor: Color.fromRGBO(0, 161, 39, 1)),
          )
      ]));
    }
  }
  </code></pre>
  <p>Currently, after clicking on the login button which navigates to the test page <a href="https://i.stack.imgur.com/7xmnk.jpg" rel="nofollow noreferrer">it displays the add form button</a>.</p>
  <p>On clicking the add form button, the circular progress indicator displays very briefly before displaying a blank page. Should I perhaps add all the possible field type options for it to work? Please let me know where I have gone wrong thanks</p>