Home > database >  .catchError() does not throwing the exception in flutter
.catchError() does not throwing the exception in flutter

Time:12-20

I am working on a shopping app where I need to save the user input data to server. While sending the data, I want to handle exceptions, if any. But, .catchError() block is not working.

the code:

void _saveForm() {
    final isValid = _form.currentState!.validate();
    if (!isValid) {
      return;
    }
    _form.currentState!.save();
    setState(() {
      _isLoading = true;
    });
    if (ModalRoute.of(context)!.settings.arguments as String == "add") {
      Provider.of<Products>(context, listen: false)
          .addProduct(_editedProduct)
          .catchError((error) {
        return showDialog(
            context: context,
            builder: (ctx) => AlertDialog(
                  title: Text("Somethiinng went wrong"),
                  content: Text(error.toString()),
                  actions: <Widget>[
                    FloatingActionButton(
                      onPressed: () {
                        Navigator.of(context).pop();
                      },
                      child: Text("Okay"),
                    )
                  ],
                ));
      }).then((_) {
        setState(() {
          _isLoading = false;
        });
      });
      Navigator.of(context).pop();
    } else {
      Provider.of<Products>(context, listen: false).updateProduct(
          ModalRoute.of(context)!.settings.arguments as String, _editedProduct);
      Navigator.of(context).pop();
    }
}

It is the provider file where I am sending data and intentionally removed .json after the link which causes the exception.

Future<void> addProduct(Product product) {
    final url = Uri.parse(
        'https://food-fancy-default-rtdb.firebaseio.com/products');// removed .json after products
    return http
        .post(url,
            body: json.encode({
              "title": product.title,
              "price": product.price,
              "description": product.description,
              "imageUrl": product.imageUrl,
              "isFavorite": product.isFavorite
            }))
        .then((response) {
      final _newProduct = Product(
          id: json.decode(response.body)["name"],
          title: product.title,
          description: product.description,
          price: product.price,
          imageUrl: product.imageUrl);
      _items.insert(0, _newProduct);
      print(json.decode(response.body));
      notifyListeners();
    }).catchError((error) {
      throw error;
    });
}

Error message:

> E/flutter (11843): [ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: This widget has been unmounted, so the State no longer has a context (and should be considered defunct).
>
> E/flutter (11843): Consider canceling any active work during "dispose" or using the "mounted" getter to determine if the State is still active.

I have tried

Navigator.pop()
Navigator.of(context, rootNavigator: true).pop()

CodePudding user response:

this ModalRoute.of(context)!.settings.arguments as String is not correct because the ModalRoute.of(context)!.settings.arguments is a map and you can't cast it to a String so what you need to do is to access the keys inside of it, for instance if you're sending a key called 'add' with the value true you need to acces it like this:

Map<String, dynamic>? _data = ModalRoute.of(context)!.settings.arguments as Map<String, dynamic>?;
      _result = _data!['add'];

and the result should be true now.

CodePudding user response:

The problem solved if I use try catch. blocks in async

the code:

void _saveForm() async {
final isValid = _form.currentState!.validate();

if (!isValid) {
  return;
}
_form.currentState!.save();
setState(() {
  _isLoading = true;
});
if (ModalRoute.of(context)!.settings.arguments as String == "add") {
  try {
    await Provider.of<Products>(context, listen: false)
        .addProduct(_editedProduct);
  } catch (error) {
    await showDialog(
        // returning the result of showDialogg()
        context: context,
        builder: (ctx) => AlertDialog(
              title: const Text("Somethiinng went wrong"),
              content: Text(error.toString()),
              actions: <Widget>[
                ElevatedButton(
                  child: const Text("Okay"),
                  onPressed: () {
                    Navigator.of(ctx).pop();
                  },
                )
              ],
            ));
  } finally {
    setState(() {
      _isLoading = false;
    });
    Navigator.of(context).pop();
  }
} else {
  Provider.of<Products>(context, listen: false).updateProduct(
      ModalRoute.of(context)!.settings.arguments as String, _editedProduct);
  Navigator.of(context).pop();
}

}`

  • Related