Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flutter - How do I use await inside the streambuilder?

I want to use await inside streambuilder. However, if you use async inside, you get an error. On the code below !!!!!!!! That's the part I want to solve. Thank you very much if I can tell you how.

class _MemoStreamState extends State<MemoStream> {
final _fireStore = Firestore.instance;

@override
Widget build(BuildContext context) {
return StreamBuilder<QuerySnapshot>(
  stream: _fireStore
      .collection(widget.logInUsrEmail)
      .orderBy('id', descending: false)
      .snapshots(),
  builder: (context, AsyncSnapshot<QuerySnapshot> snapshot) {
    if (!snapshot.hasData) return LinearProgressIndicator();

    final memos = snapshot.data.documents;
    List<MemoMaterial> memoList = [];

    for (var memo in memos) {
      final memoDocumentID = memo.documentID;
      final memoTitle = await PlatformStringCryptor().decrypt(memo.data['title'], _key);  !!!!!!!!!!
      final memoUsrID = memo.data['usrID'];
      final memoUsrPW = memo.data['usrPW'];
      final memoText = memo.data['text'];
      final memoCreateTime = memo.data['createTime'];

      final memoMaterial = MemoMaterial(
        logInUsrEmail: widget.logInUsrEmail,
        doc: memoDocumentID,
        title: memoTitle,
        usrID: memoUsrID,
        usrPW: memoUsrPW,
        text: memoText,
        createTime: memoCreateTime,
      );
      memoList.add(memoMaterial);
    }

    return Expanded(
      child: new ListView.builder(
like image 941
CHOI YOOBIN Avatar asked Apr 28 '20 15:04

CHOI YOOBIN


People also ask

How do you await in Flutter?

We put await in front of an asynchronous function to make the subsequence lines waiting for that future's result. We put async before the function body to mark that the function support await . An async function will automatically wrap the return value in Future if it doesn't already.

How do I use StreamBuilder in Flutter?

To use StreamBuilder , you need to call the constructor below. Basically, you need to create a Stream and pass it as the stream argument. Then, you have to pass an AsyncWidgetBuilder which can be used to build the widget based on the snapshots of the Stream .

What is the difference between Future and async and await in Flutter?

"Future" means that we expect a string when the future is completed. Note: On async code, al the code before the await will run syncronously, when it find the first await it will wait for the value to completely return, as completed, with value or error!

How many types of stream builders are in Flutter?

There are two types of streams in Flutter: single subscription streams and broadcast streams. Single subscription streams are the default.


2 Answers

You should do something like this :

  Stream<List<MemoMaterial>> memosStream;

  Future<MemoMaterial> generateMemoMaterial(Memo memo) async {
    final memoTitle =
        await PlatformStringCryptor().decrypt(memo.data['title'], _key);

    return MemoMaterial(
      logInUsrEmail: widget.logInUsrEmail,
      doc: memo.documentID,
      title: memoTitle,
      usrID: memo.data['usrID'],
      usrPW: memo.data['usrPW'],
      text: memo.data['text'];,
      createTime: memo.data['createTime'],
    );
  }

  @override
  void initState() {
    memosStream = _fireStore
            .collection(widget.logInUsrEmail)
            .orderBy('id', descending: false)
            .snapshots()
            .asyncMap((memos) => Future.wait([for (var memo in memos) generateMemoMaterial(memo)]));
    super.initState();
  }
  @override
  Widget build(BuildContext context) {
  return StreamBuilder<List<MemoMaterial>>(
    stream: memosStream // Use memostream here

asyncMap() will "transform" every new set of Documents into a list of MemoMaterial, and emit this list into the stream when the action is performed.

Future.wait() allows to perform multiple async requests simultaneously.

like image 130
Augustin R Avatar answered Oct 06 '22 14:10

Augustin R


You can do it using FutureBuilder inside StreamBuilder in following way.

Stream<List<int>> callme() async* {
    yield [1, 2, 3, 4, 5, 6];
  }

  buildwidget() async {
    await Future.delayed(Duration(seconds: 1));
    return 1;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        child: StreamBuilder(
            stream: callme(),
            builder: (_, sna) {
              if (sna.hasData) {
                return FutureBuilder(
                  future: buildwidget(),
                  builder: (_, snap) {
                    if (snap.hasData) {
                      return ListView.builder(
                        itemCount: sna.data.length,
                        itemBuilder: (_, index) {
                          return Text("${sna.data[index]} and ${snap.data}");
                        },
                      );
                    } else {
                      return CircularProgressIndicator();
                    }
                  },
                );
              } else {
                return CircularProgressIndicator();
              }
            }),
      ),
    );
  }
like image 4
Viren V Varasadiya Avatar answered Oct 06 '22 13:10

Viren V Varasadiya