`my problem is when i pop this screen then come back , i can’t access to ref.read and and exception Bad state: Cannot use "ref" after the widget was disposed
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:learn_with_lina/providers/messages_provider.dart';
class _CallScreenState extends ConsumerState<CallScreen> {
void initState() {
print("start call Screen");
super.initState();
initSpeechToText();
}
MessageModel addMessageToList(
{required String text, required bool received, required bool isLoading}) {
final messageModel =
MessageModel(text: text, received: received, isLoading: isLoading);
ref.read(messagesProvider.notifier).addMessage(messageModel);
return messageModel;
}
void updateMessageInList(
{required MessageModel messageModel,
required String text,
required bool isLoading,
required bool error}) {
ref
.read(messagesProvider.notifier)
.updateMessage(messageModel, text, isLoading, error);
}
void sendMessage(String text) async {
if (!mounted) return;
// add the message of user to the list of messages
addMessageToList(text: text, received: false, isLoading: false);
setState(() {
isLoadingSendMessage = true;
});
// get old messages
final oldMessages = ref.read(messagesProvider);
// add Loader to the List view
final assistantMessage = addMessageToList(
text: '', received: true, isLoading: isLoadingSendMessage);
// call chat gpt
final answer = await ChatGptApi.getChatGptAnswer(text, oldMessages);
setState(() {
isLoadingSendMessage = false;
});
if (answer.trim().isNotEmpty) {
bool error = false;
if (answer.trim() == 'An internal error occurred') {
error = true;
}
updateMessageInList(
messageModel: assistantMessage,
text: answer.trim(),
isLoading: isLoadingSendMessage,
error: error);
systemSpeak(answer);
}
}
i tried to check if(!mounted) but in this cas the mounted value is always false after comme back to this screen
2
Answers
That makes sense, you popped the route and come back pushing it again, so the previous one is not mounted anymore. This seems more a problem of understanding the lifecycle of the widgets and widget tree more than Riverpod but if you really insist of using that callback method after being disposed you could just save a reference to your provider as a variable and use it:
Still take this with cautios, and try to cahnge your logic inside your provider (which seems more logical) so you can send messages even when your widget is disposed
If you have a call to
ref
insideinitSpeechToText
, then you can’t call it directly in theinitState
. You have to put it inside this callback: