Home > front end >  Flutter - Variable in function available when building Widget
Flutter - Variable in function available when building Widget

Time:09-15

If I understood correctly (but clearly I don't) when you need a var available when you build the widget you need to call the function in the initState(). The function is 'void getDevices()'

I need var _documentsIds to build DropdownMenuItem.

var _documentsIds is docs ID from a query I make to FirebaseFirestore

How do I make _documentsIds available to be used in my Widget?

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:modal_progress_hud_nsn/modal_progress_hud_nsn.dart';
import 'package:safegaurd/constants.dart';
import 'package:flutter_time_picker_spinner/flutter_time_picker_spinner.dart';
import 'package:safegaurd/screens/log_in_page.dart';
import 'package:safegaurd/components/buttons_navigate.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'new_device_page.dart';

class DeviceSelectionPage extends StatefulWidget {
  const DeviceSelectionPage({Key? key}) : super(key: key);
  static const String id = 'device_selection_page';

  @override
  State<DeviceSelectionPage> createState() => _DeviceSelectionPageState();
}

class _DeviceSelectionPageState extends State<DeviceSelectionPage> {
  final _auth = FirebaseAuth.instance;
  User? loggedInUser;

  final firestoreInstance = FirebaseFirestore.instance;
  final String devices = 'devices';
  List? _documentsIds;

  bool showSpinner = false;

  String? selectedValue;
  final bool checkOne = false;
  Color sDeviceAlways = Colors.white54;
  Color sDeviceTime = Colors.white54;
  FontWeight sDeviceAlwaysW = FontWeight.normal;
  FontWeight sDeviceTimeW = FontWeight.normal;

  @override
  void initState() {
    super.initState();
    getCurrentUser();
    getDevices();
  }

  void getCurrentUser() async {
    try {
      final user = await _auth.currentUser;
      if (user != null) {
        getDevices();
      };
    } catch (e) {
      print(e);
    }
  }

  void getDevices() async {
      var firebaseUser = FirebaseAuth.instance.currentUser?.email;
      print('firebaseUser: $firebaseUser');
      var query = await firestoreInstance
          .collection(devices)
          .where('email', isEqualTo: '$firebaseUser')
          .get();
      var _documentsIds = query.docs.map((doc) => doc.id).toList();
      print('_documentsIds: $_documentsIds');
  }

  @override
  Widget build(BuildContext context) {
    print('_documentsIds: $_documentsIds');
    return Scaffold(
        appBar: AppBar(
          leading: null,
          actions: [
            IconButton(
                onPressed: () {
                  _auth.signOut();
                  Navigator.pop(context);
                },
                icon: Icon(Icons.close))
          ],
          title: const Text('Device Selection page'),
        ),
        body: ModalProgressHUD(
          inAsyncCall: showSpinner,
          child: Container(
              child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              const SizedBox(
                height: 40,
                child: Text(
                  'SAFEGAURD',
                  style: kAppTextStyle,
                ),
              ),
              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  Container(
                    width: 380,
                    padding: const EdgeInsets.symmetric(horizontal: 24.0),
                    decoration: BoxDecoration(
                        border: Border.all(
                            color: Colors.lightBlueAccent, width: 1.0),
                        borderRadius: kBorderRadius),
                    child: DropdownButtonHideUnderline(
                      child: DropdownButton(
                        hint: const Text(
                          'Safegaurd Devices',
                          style: TextStyle(color: Colors.white54, fontSize: 25),
                        ),
                        style:
                            const TextStyle(color: Colors.orange, fontSize: 25),
                        borderRadius: kBorderRadius,
                        iconSize: 40,
                        elevation: 16,
                        onChanged: (value) {
                          setState(() {
                            selectedValue = value.toString();
                            setState(() {
                              selectedValue;
                              print(selectedValue);
                            });
                          });
                        },
                        value: selectedValue,
                        items: _documentsIds?.map((itemsList) {
                          return DropdownMenuItem<String>(
                            value: itemsList,
                            child: Text(itemsList),
                          );
                        }).toList(),
                      ),
                    ),
                  )
                ],
              ),
              Row(
                children: [
                  Buttons_Navigate(
                    colour: Colors.teal,
                    title: 'Save Settings',
                    onPressed: () {},
                    width: 200,
                  ),
                ],
              ),
              Row(
                children: [
                  Buttons_Navigate(
                    colour: Colors.teal,
                    title: 'Claim new Device',
                    onPressed: () {
                      Navigator.pushNamed(context, NewDevicePage.id);
                    },
                    width: 200,
                  )
                ],
              ),
              Row(
                mainAxisAlignment: MainAxisAlignment.end,
                children: [
                  Buttons_Navigate(
                      colour: Colors.orange,
                      title: 'Back',
                      onPressed: () {
                        Navigator.pushNamed(context, LogInPage.id);
                      },
                      width: 40)
                ],
              )
            ],
          )),
        ));
  }

}

CodePudding user response:

wall, you can use futureBuilder and show A CircularProgressBar until the query is done check the documentation here: FutureBuilder

CodePudding user response:

I am getting the FutureBuilder to build 1/2 way, I can see it build the BoxDecoration with 'Waiting Devices' and then it changes to 'Safegaurd Devices' but the DropdownMenuItem never get build in the DropdownButton.

In the Future<List> getDevices() I print out 'print('_documentsIds: $_documentsIds');' , I can see that this list gets printed and contains the correct list {I/flutter ( 7423): _documentsIds: [76CF168FA8DA8874, BA8669ED73FF8107]}

Any pointers as why it is not building the DropdownMenuItem?

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:modal_progress_hud_nsn/modal_progress_hud_nsn.dart';
import 'package:safegaurd/constants.dart';
//import 'package:flutter_time_picker_spinner/flutter_time_picker_spinner.dart';
import 'package:safegaurd/screens/log_in_page.dart';
import 'package:safegaurd/components/buttons_navigate.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'new_device_page.dart';

class DeviceSelectionPage extends StatefulWidget {
  const DeviceSelectionPage({Key? key}) : super(key: key);
  static const String id = 'device_selection_page';

  @override
  State<DeviceSelectionPage> createState() => _DeviceSelectionPageState();
}

class _DeviceSelectionPageState extends State<DeviceSelectionPage> {
  final _auth = FirebaseAuth.instance;
  User? loggedInUser;

  final firestoreInstance = FirebaseFirestore.instance;
  final String devices = 'devices';
  List? _documentsIds;

  bool showSpinner = false;

  //bool _isSelected1 = false;
  //bool _isSelected2 = false;
  //DateTime _dateTime = DateTime.now();
  String? selectedValue;
  final bool checkOne = false;
  Color sDeviceAlways = Colors.white54;
  Color sDeviceTime = Colors.white54;
  FontWeight sDeviceAlwaysW = FontWeight.normal;
  FontWeight sDeviceTimeW = FontWeight.normal;

  @override
  void initState() {
    super.initState();
    getCurrentUser();
    getDevices();
  }

  void getCurrentUser() async {
    try {
      final user = await _auth.currentUser;
      if (user != null) {
        getDevices();
      };
    } catch (e) {
      print(e);
    }
  }


  Future<List<dynamic>> getDevices() async {
      var firebaseUser = FirebaseAuth.instance.currentUser?.email;
      print('firebaseUser: $firebaseUser');
      var query = await firestoreInstance
          .collection(devices)
          .where('email', isEqualTo: '$firebaseUser')
          .get();
     List<String> _documentsIds = query.docs.map((doc) => doc.id).toList();
      print('_documentsIds: $_documentsIds');

      return _documentsIds;
  }

  @override
  Widget build(BuildContext context) {
    print('_documentsIds: $_documentsIds');
    return Scaffold(
        appBar: AppBar(
          leading: null,
          actions: [
            IconButton(
                onPressed: () {
                  _auth.signOut();
                  Navigator.pop(context);
                },
                icon: Icon(Icons.close))
          ],
          title: const Text('Device Selection page'),
        ),
        body: ModalProgressHUD(
          inAsyncCall: showSpinner,
          child: Container(
              child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              const SizedBox(
                height: 40,
                child: Text(
                  'SAFEGAURD',
                  style: kAppTextStyle,
                ),
              ),
              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  Container(
                    width: 380,
                    padding: const EdgeInsets.symmetric(horizontal: 24.0),
                    decoration: BoxDecoration(
                        border: Border.all(
                            color: Colors.lightBlueAccent, width: 1.0),
                        borderRadius: kBorderRadius),
                    child: DropdownButtonHideUnderline(
                      child: FutureBuilder<List> (
                        future: getDevices(),
                        builder: (BuildContext context, AsyncSnapshot<List> snapshot){
                          if (!snapshot.hasData) {
                            return const Text('Waiting Devices',style: TextStyle(color: Colors.white54, fontSize: 25));
                          } else {
                            return DropdownButton(
                              hint: const Text(
                                'Safegaurd Devices',
                                style: TextStyle(color: Colors.white54, fontSize: 25),
                              ),
                              style:
                              const TextStyle(color: Colors.orange, fontSize: 25),
                              borderRadius: kBorderRadius,
                              iconSize: 40,
                              elevation: 16,
                              onChanged: (value) {
                                setState(() {
                                  selectedValue = value.toString();
                                  setState(() {
                                    selectedValue;
                                    print(selectedValue);
                                  });
                                });
                              },
                              value: selectedValue,
                              items: _documentsIds?.map((itemsList) {
                                return DropdownMenuItem<String>(
                                  value: itemsList,
                                  child: Text(itemsList),
                                );
                              }).toList(),
                            );
                          }
                        }
                      )
                    ),
                  )
                ],
              ),
              Row(
                children: [
                  Buttons_Navigate(
                    colour: Colors.teal,
                    title: 'Save Settings',
                    onPressed: () {},
                    width: 200,
                  ),
                ],
              ),
              Row(
                children: [
                  Buttons_Navigate(
                    colour: Colors.teal,
                    title: 'Claim new Device',
                    onPressed: () {
                      Navigator.pushNamed(context, NewDevicePage.id);
                    },
                    width: 200,
                  )
                ],
              ),
              Row(
                mainAxisAlignment: MainAxisAlignment.end,
                children: [
                  Buttons_Navigate(
                      colour: Colors.orange,
                      title: 'Back',
                      onPressed: () {
                        Navigator.pushNamed(context, LogInPage.id);
                      },
                      width: 40)
                ],
              )
            ],
          )),
        ));
  }



  • Related