Reputation: 5942
I created a http method in Flutter like below:
Future<void> addProduct(Product product) {
const url = 'https://flutter-shop-3de16.firebaseio.com/products';
return http
.post(
url,
body: json.encode({
'title': product.title,
'description': product.description,
'imageUrl': product.imageUrl,
'price': product.price,
'isFavorite': product.isFavorite,
}),
)
.then((response) {
...
notifyListeners();
}).catchError((error) {
print(error);
throw error;
});
}
I know that my url
is wrong because i want to get error.
In .catchError i throw an error and in the main page by provider i used addProduct
like this:
Provider.of<Products>(context, listen: false)
.addProduct(_editedProduct)
.catchError((error) {
return showDialog(
context: context,
builder: (ctx) => AlertDialog(
title: Text('An error occurred!'),
content: Text('Something went wrong.'),
actions: <Widget>[
FlatButton(
child: Text('Okay'),
onPressed: () {
Navigator.of(ctx).pop();
},
)
],
),
);
}).then((_) {
print('after catch accoured');
setState(() {
_isLoading = false;
});
Navigator.of(context).pop();
});
}
}
I catchError
i got error and i show an alert dialog.After tap on Okay
button i want to execute then
block so i returned showDialog
because it return a future.
But i do not know why
.then((_) {
print('after catch accoured');
setState(() {
_isLoading = false;
});
Navigator.of(context).pop();
});
}
No to run after alert dialog is closed?
Upvotes: 1
Views: 1484
Reputation: 1153
return showDialog<Null>()
instead of return showDialog()
throw error
when using json.decode()
inside products providerUpvotes: 3
Reputation: 9
return showDialog(
context: context,
builder: (ctx) => AlertDialog(
title: Text('An error occurred!'),
content: Text('Something went wrong.'),
actions: <Widget>[
FlatButton(
child: Text('Okay'),
onPressed: () {
Navigator.of(ctx).pop();
},
)
],
),
).then((value) => null);
the above then((value) => null );
will solve your problem, it would help you i think.
Upvotes: 0
Reputation: 1
Below code should solve your issue. moving then statement after show dialog would make it work again.
Provider.of<Products>(context, listen: false)
.addProduct(_editedProduct)
.catchError((error) {
return showDialog(
context: context,
builder: (ctx) =>
AlertDialog(
title: Text('An error occurred!'),
content: Text('Something went wrong.'),
actions: <Widget>[
FlatButton(
child: Text('Okay'),
onPressed: () {
Navigator.of(ctx).pop();
},
)
],
),
).then((_) {
print('after catch accoured');
setState(() {
isLoading = false;
});
Navigator.of(context).pop();
});;
});
Upvotes: -1
Reputation: 408
The then
block will run after the main Future; it won't run after catchError
. If you want to run a piece of code after catchError
, use a whenComplete
block.
Provider.of<Products>(context, listen: false)
.addProduct(_editedProduct)
.catchError((error) {
return showDialog(
context: context,
builder: (ctx) => AlertDialog(
title: Text('An error occurred!'),
content: Text('Something went wrong.'),
actions: <Widget>[
FlatButton(
child: Text('Okay'),
onPressed: () {
Navigator.of(ctx).pop();
},
)
],
),
);
}).whenComplete(() { // This will run after execution
print('after catch accoured');
setState(() {
_isLoading = false;
});
Navigator.of(context).pop();
});
}
}
Upvotes: -1