Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
325 views
in Technique[技术] by (71.8m points)

dart - flutter context become null if list is not empty

I have a form to create/update activity which is a stateful widget like this:


class ActivityForm extends StatefulWidget {
  final Activity activity;
  final bool isEdit;

  const ActivityForm({Key key, this.activity, this.isEdit}) : super(key: key);

  @override
  _ActivityFormState createState() => _ActivityFormState();
}

class _ActivityFormState extends State<ActivityForm> {
  final _formKey = GlobalKey<FormState>();
  List<int> activityDetailIdToBeDeleted;

  ...
  void submitHandler() async {
    setState(() {
      _isLoading = true;
    });

    // Mapping input field to activity model
    Activity activity = Activity(
        id: widget.activity.id,
        tanggal: _tanggalController.text,
        uraianKegiatan: _uraianKegiatanController.text,
        pic: _picController.text,
        jumlahTim: int.parse(_jumlahTimController.text),
        kendala: _kendalaController.text,
        penyelesaian: _penyelesaianController.text,
        approverUserId: selectedApprovalUser,
        rincianPekerjaan: rincianPekerjaanList,
        status: 'PENDING');

    if (widget.isEdit) {
      await Provider.of<ActivityProvider>(context, listen: false)
          .updateActivity(activity, activityDetailIdToBeDeleted);
    } else {
      await Provider.of<ActivityProvider>(context, listen: false)
          .createActivity(activity);
    }

    Navigator.pop(context);
  }

in my form there are some detail list of activities. When i press delete it adds the id of the activity detail to the list of "to be deleted" :

IconButton(
  icon: Icon(Icons.delete),
  onPressed: () => removeRincianPekerjaan(
  activityDetail.description),),

here's the function:

void removeRincianPekerjaan(desc) {
    if (widget.isEdit) {
      int detailId = rincianPekerjaanList
          .where((element) => element.description == desc)
          .first
          .id;
      if (!activityDetailIdToBeDeleted.contains(detailId))
        activityDetailIdToBeDeleted.add(detailId);
      print(activityDetailIdToBeDeleted);
    }

    setState(() {
      rincianPekerjaanList
          .removeWhere((element) => element.description == desc);
    });
  }

that list of ids will be sent to provider which looks like this:

Future<bool> updateActivity(
      Activity activity, List<int> activityDetailToBeDeleted) async {
    final response = await ActivityService()
        .updateActivity(activity.id.toString(), activity.toMap());

    if (response != null) {
      // Update Success.
      if (response.statusCode == 200) {
        var body = json.decode(response.body);
        removeActivityToList(activity);
        activity = Activity.fromMap(body['activity']);
        addActivityToList(activity);

        if (activityDetailToBeDeleted.isNotEmpty) {
          print("to be deleted is not empty.");
          print("ID to be deleted: ${activityDetailToBeDeleted.join(",")}");
          final res = await ActivityService()
              .deleteActivityDetail(activityDetailToBeDeleted.join(","));
          if (res.statusCode == 204) {
            print('ID DELETED.');
            return true;
          }
        }

        return true;
      }
      // Error unauthorized / token expired
      else if (response.statusCode == 401) {
        var reauth = await AuthProvider().refreshToken();

        if (reauth) {
          return await createActivity(activity);
        } else {
          return Future.error('unauthorized');
        }
      }

      return Future.error('server error');
    }

    return Future.error('connection failed');
  }

the problem is if the list is empty, or i didn't add the id to the list, builder context is not null but if i add an id to the list "to be deleted", the Navigator.pop(context) will throw an error because context is null. I don't understand why it becomes null.

full code in here

question from:https://stackoverflow.com/questions/65558281/flutter-context-become-null-if-list-is-not-empty

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Your [context] must came from the build() method. Like this.

void submitHandler(BuildContext context) async {
    setState(() {
      _isLoading = true;
    });

    // Mapping input field to activity model
    Activity activity = Activity(
        id: widget.activity.id,
        tanggal: _tanggalController.text,
        uraianKegiatan: _uraianKegiatanController.text,
        pic: _picController.text,
        jumlahTim: int.parse(_jumlahTimController.text),
        kendala: _kendalaController.text,
        penyelesaian: _penyelesaianController.text,
        approverUserId: selectedApprovalUser,
        rincianPekerjaan: rincianPekerjaanList,
        status: 'PENDING');

    if (widget.isEdit) {
      await Provider.of<ActivityProvider>(context, listen: false)
          .updateActivity(activity, activityDetailIdToBeDeleted);
    } else {
      await Provider.of<ActivityProvider>(context, listen: false)
          .createActivity(activity);
    }
    SchedulerBinding.instance.addPostFrameCallback((_) {
        Navigator.pop(context);
    });
  }

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...