we_mor
we_mor

Reputation: 528

Flutter Function returns empty list using Firebase

I'm using Flutter web and firebase realtime database. In my databse I have some questions, structured as maps, and I'm trying to display them in my app.

For each question, I create a widget, I add it inside a list and then I append the list to a Column() widget.

The Column() widget is the following (view_question.dart file):

Column(
  children: Question().view(),
),

As you can see, I use the method view() from a class I created named Question().

The view() method returns a list of widgets.

Before I show you the .view() method, I need to mention that outside of the Question class I have initialized the following:

List<Widget> widgets = List();

Below you can see the .view() method from the Question class (Question.dart file):

List<Widget> view() {
    
    Database db = database();
    DatabaseReference ref = db.ref('questions/');

    ref.orderByKey().once("value").then((e) {
      DataSnapshot datasnapshot = e.snapshot;
      datasnapshot.val().forEach((key, values) {
        
        widgets.add(QuestionWidget(values));
        print(widgets);
        
      });
    });
    print(widgets);
    return widgets;

I'm getting my questions' data from my database, then for each question I'm creating a QuestionWidget() widget, where I pass inside it the respective data and I add it to the widgets list. Afterwards, I print() the widgets list, so I can monitor the whole process.

As you also can see, I've added a print(widgets) just before the return statement.

This is the prints' output in my console

enter image description here

From that, what I understand is that the function returns an empty list and then I retrieve my data from the database and add them to the list.

So I'm asking, how can I add my data to the list, and when this process has finished, return the list and append it to the Column() widget? Should I add a delay to the return statement? What am I missing?

Thank you for your time

Upvotes: 0

Views: 664

Answers (2)

Rajitha Udayanga
Rajitha Udayanga

Reputation: 1732

    // return type is like this
    Future<List<Widget>> view() {
    
    Database db = database();
    DatabaseReference ref = db.ref('questions/');

    // return this
    return ref.orderByKey().once("value").then((e) {
      DataSnapshot datasnapshot = e.snapshot;

      datasnapshot.val().forEach((key, values) {
        widgets.add(QuestionWidget(values));
      });
      
      // return widgets after added all values
      return widgets;
    });
    

Upvotes: 1

Frank van Puffelen
Frank van Puffelen

Reputation: 598951

Data is loaded from Firebase asynchronously. By the time your return widgets runs, the widgets.add(QuestionWidget(values)) hasn't been called yet. If you check the debug output of your app, the print statements you have should show that.

For this reason you should set the widgets in the state once they're loaded. That will then trigger a repaint of the UI, which can pick them up from the state. Alternatively you can use a FutureBuilder to handle this process.

See:

Upvotes: 1

Related Questions