Is there way to get a callback after StreamBuilder completely load? - flutter

I'm trying get a callback after my context build, i already tried with "WidgetsBinding.instance!.addPostFrameCallback", but not works because i have a StreamBuilder and the first load of snapshot data it is null.
I expected exists a callback of StreamBuilder after data completely load and build loaded, here is my code:
StreamBuilder(
stream: this.paymentInfoFormPresenter.key,
builder: (context, snapshot) {
final _formKey = snapshot.data;
if (_formKey == null) {
return Container();
}
return Text('example');
}
);
And i don't find anything about on internet... i hope someone can help me.

To resolve this issue, i needed change the "Text('example')" to an external widget, and added "WidgetsBinding.instance!.addPostFrameCallback" inside of this external widget

Related

Getx Controllers null values at first

i am working on flutter project Apply Getx and MVC Arcitecture but when i am getting stream from firestore first it got null values but when hot reload on that page values will goes in to place how to remove this Error, Almost in All type of modules I have to face this Error.
I am trying init State but Ui build first than function in Init State.
It is quite normal for StreamBuilders or FutureBuilders to call their builder function with null values.
The reason is that the build function may be called at any time, irrespective of the stream or future's state.
You should use the hasData property of the snapshot to check for valid data, and handle the case of null data, e.g. by returning a SizedBox widget.
StreamBuilder(
stream: yourStream,
builder: (context, snapshot) {
if (snapshot.hasData) {
return yourWidget();
} else {
return const SizedBox();
}
},
);

How to set the object variable permanently in Flutter?

I am trying to build an app with Flutter and Dart. Here, I want to retrieve data from my Firebase, and I was able to do so and put it in the replies variable in each Message object that I have as an array type in the Firebase by using a for loop. However, when I try to access the replies variable again, it becomes empty.
I tried using setState, but that just causes the replies variable to keep resetting. Why this is the case, and how can I fix it?
StreamBuilder<List<Message>> pickMessage(
Stream<List<Message>> list, BuildContext context) {
return StreamBuilder(
stream: list,
builder: (context, snapshot) {
if (snapshot.hasError) {
return const Text('Something went wrong!');
} else if (snapshot.hasData) {
final message = snapshot.data!;
for (var msg in message) {
FirebaseFirestore.instance.collection("messages").doc(msg.msgID).get().then((value){
msg.replies = value.get("replies");
});
}
If You Need Some Variable to Initialize Once Put in Init Function or In Builder Function, outside the Scope of StreamBuilder, hope it helps

How to listen for state changes inside a FutureBuilder widget and reflect the state change?

to demonstrate the problem, let me write down some code for a FutureBuilder.
FutureBuilder(future: _myFuture, builder: (context, snapshot) {
if(snapshot.hasData) {
// !!!! IMPORTANT !!!
// Pay attention to the _isFirstText variable below
return SizedBox(
child: _isFirstText ? Text(snapshot.data.firstText) : Text(snapshot.data.secondText),
);
}
if(snapshot.connectionState == ConnectionState.isWaiting) {
return Text('Waiting!');
}
return Text('Error');
}),
As I have mentioned in a comment in the above code, pay attention to the _isFirstText variable. Suppose that is a state variable. Inside the future builder, how do I get the correct return value that corresponds to the isFirstText state variable change.
I also came across this stack overflow post but could not get the code to work.
I also came across a widget called StatefulBuilder, but I can not figure out to where in my FutureBuilder I should use it.
Can someone please help?
If you want to listen to ongoing changes you can use a Streambuilder. Streams are not only for serverside changes but can also be used locally.
You can build a Stream yourself like this :
StreamController myStreamController = StreamController<int>();
To send a new event through this controller you can do
myStreamController.sink.add(newValue);
You can then listen to changes like this:
#override
Widget build(BuildContext context) {
return StreamBuilder<int>(
stream: myStreamController.stream,
builder: (context, snapshot) {
final value = snapshot.data;
return Text(value!.toString());
}
If you want to learn more check this Video: https://youtu.be/nQBpOIHE4eE
Let me know if this helped.
You can use ValueNotifier variables and use notifyListeners() to update a specific parts of your code Like this:
ValueListenableBuilder and use that ValueNotifier variable and listen to that.

Convert a Stream to a Future in Flutter

a Flutter beginner here so if my question is stupid don't mind it...
How can I convert a Stream to a Future?
I have a Stream that just calls the requested URL multiple times because it's a Stream. I want to be able to get the data and not the loading state... Because I always just get loading forever
Is there something like Future.fromStream() function somewhere and I'm missing it?
Can I achieve this?
I didn't provide any code because I think it's not needed if you need the code, I can edit the question
Stream has firstWhere method, this will return Future
_profileService.profileStream.firstWhere((element) => false);
Stream and Future are two different concepts.
As you are using, stream is keeping the data updated, and Future is just one time.
Example of using stream: Shopping Cart, listing of items
Example of using future: getUserDetails after login.
If you're using stream, then you can use streambuilder to build your UI
StreamBuilder<User>(
stream: userBloc.author, // your stream here
builder:
(BuildContext context, AsyncSnapshot<User> snapshot) {
if (snapshot.connectionState == ConnectionState.active && snapshot.hasData) {
// do your work here
} else {
return CircularprogressIndicator();
}
},
)

How to initialize and load data when moving to a screen in flutter?

I want to populate my lists by making API calls when moving to a screen in flutter. I tried calling the async function in the init state however it takes time to load the data of course, and that leads to a null error.
I tried using a future builder in my view. However, I want to make multiple API calls and I don't think that is possible with one future builder. And I would like to avoid having different future builders for each list.
Is there a neat way to do this?
Also is it advisable to load data and pass it on from the previous screen.. since I would like to avoid the loading time?
current code
FutureBuilder(
future: getAllData,
initialData: [],
builder: (context, snapshot) {
if (!snapshot.hasData || snapshot.data.isEmpty) return Center(child: CircularProgressIndicator(valueColor: new AlwaysStoppedAnimation<Color>(Colors.red),));
else {
return createNewTaskView(context, snapshot.data);
}
}),
init method
#override
void initState() {
this.getAllData = getSocieties();
}