Home > Blockchain >  Check if String variable is null in Flutter
Check if String variable is null in Flutter

Time:05-17

I am unable to understand this.

I have defined a few String variables at the start as such

enter image description here

I also have this below which assigns the keyed in value to the specific variable (eg _room). enter image description here

However, I wanted to check if what I keyed into the TextFormField was actually being saved to the specific variable, and hence tried adding a line print (_variable) in my onSaved function, but saw nothing in the Debug Console as I typed stuff - This is my problem #1.

I then decided to add a Text Field inside my main widget which creates the UI to show the typed in text on screen. However I am facing an issue with null safety. You can see below enter image description here

I have tried using if/else statements, terenary operators, and even this .isEmpty. .isEmpty does not work as it only checks if it is an empty string, but fails if the variable is actually null. After trying these different methods I still face various kinds of errors. What would be the proper way to do this?

My whole code is below:

import 'package:flutter/material.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:path/path.dart' as path;

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

  @override
  State<BookRoom> createState() => _SelectRoomState();
}

class _SelectRoomState extends State<BookRoom> {
  final storage = FirebaseStorage.instance;
  final storageRef = FirebaseStorage.instance.ref();

  //Form Key for the Form
  final GlobalKey<FormState> _bookingFormKey = GlobalKey<FormState>();

  double? _deviceHeight, _deviceWidth;
  String? _description, _room, _datetime, _name, _unit, _purpose;

  @override
  Widget build(BuildContext context) {
    _deviceHeight = MediaQuery.of(context).size.height;
    _deviceWidth = MediaQuery.of(context).size.width;
    return Scaffold(
      body: Container(
        padding: EdgeInsets.symmetric(
            horizontal: _deviceWidth! * 0.05, vertical: _deviceHeight! * 0.05),
        child: SingleChildScrollView(
          child: _allDetails(),
        ),
      ),
    );
  }

  Widget _allDetails() {
    return Container(
      child: Form(
        key: _bookingFormKey,
        child: Column(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          mainAxisSize: MainAxisSize.max,
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            _selectionWidget("Select Room", _room),
            _selectionWidget("Select Date/Time", _datetime),
            _selectionWidget("Name of personnel booking", _name),
            _selectionWidget("Unit", _unit),
            _selectionWidget("Purpose", _purpose),
            _room.isEmpty ? Text("yes") : Text("no"),
          ],
        ),
      ),
    );
  }

  Widget _selectionWidget(description, _variable) {
    return Container(
      height: _deviceHeight! * 0.1,
      child: TextFormField(
        decoration: InputDecoration(
          labelText: description,
          border: const OutlineInputBorder(),
          errorBorder: const OutlineInputBorder(
            borderSide: BorderSide(color: Colors.red, width: 5),
          ),
        ),
        onSaved: (_value) {
          setState(
            () {
              _value = _variable;
            },
          );
        },
      ),
    );
  }
}

CodePudding user response:

Cause your _room is nullable String?, you can't call isEmpty directly. You need to make sure _room is not null or grand defalut value to it in case it null.

In Flutter we can use ? to mark it can be null.

Example:

// _room.isEmpty ? Text("yes") : Text("no")
-> (_room?.isEmpty ?? false) ? Text("yes") : Text("no") // use default value
-> if(_room != null) _room.isEmpty ? Text("yes") : Text("no") // use null check

CodePudding user response:

First of, you have this the wrong way around:

_value = _variable;

Here you are assigning the variable to the value.

But even if you switch this it won't work.

You have a misunderstanding about how passing parameters work.

The _parameter is not the same variable as the one you passed. you can't change the original like that.

Consider this code

void test(String b) {
  b = "b";
}

val a = "a";

test(a);

print(a);

you will see that a is still "a" and not "b".

It only changes the b in the scope of that function. The same problem is in your own code.

Also, onSaved is not called automaticaly, you might want to use onChanged instead. I rewrote your code a bit to something more functional, although it's probably also not the best solution:

final Map<String, String?> _fields = {
  "description" : null,
  "room" : null,
  "datetime" : null,
  "name" : null,
  "unit" : null,
  "purpose" : null,
};

@override
Widget build(BuildContext context) {
  _deviceHeight = MediaQuery.of(context).size.height;
  _deviceWidth = MediaQuery.of(context).size.width;
  return Scaffold(
    body: Container(
      padding: EdgeInsets.symmetric(
          horizontal: _deviceWidth! * 0.05, vertical: _deviceHeight! * 0.05),
      child: SingleChildScrollView(
        child: _allDetails(),
      ),
    ),
  );
}

Widget _allDetails() {
  return Container(
    child: Form(
      key: _bookingFormKey,
      child: Column(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        mainAxisSize: MainAxisSize.max,
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          _selectionWidget("Select Room", "room"),
          _selectionWidget("Select Date/Time", "datetime"),
          _selectionWidget("Name of personnel booking", "name"),
          _selectionWidget("Unit", "unit"),
          _selectionWidget("Purpose", "purpose"),
          (_fields["room"] ?? "").isEmpty ? Text("yes") : Text("no"),
        ],
      ),
    ),
  );
}

Widget _selectionWidget(description, variable) {
  return Container(
    height: _deviceHeight! * 0.1,
    child: TextFormField(
      decoration: InputDecoration(
        labelText: description,
        border: const OutlineInputBorder(),
        errorBorder: const OutlineInputBorder(
          borderSide: BorderSide(color: Colors.red, width: 5),
        ),
      ),
      onChanged: (value) {
        print(value);
        setState(
          () {
            _fields[variable] = value;
          },
        );
      },
    ),
  );
}
  • Related