1

I'm newbie in flutter . I'm working on project where i used Futurebuilder to fetch data from server but I would like to change it now by StreamBuilder. what I should modify in this case .How i can move to StreamBuilder correctly ?

this is my code :

Widget build(BuildContext context) {
    Size size = MediaQuery.of(context).size;
    return SafeArea(     
        child: Center(
      child: Scaffold(     
          body: SingleChildScrollView(
              child: Form(
                  key: _formKey,
                  child: FutureBuilder(
                      future: future,
                      builder: (context, snapshot) {
                        switch (snapshot.connectionState) {
                          case ConnectionState.none:
                            return Text('no connection');
                          case ConnectionState.active:
                          case ConnectionState.waiting:
                            return Center(
                              child: CircularProgressIndicator(),
                            );
                            break;
                          case ConnectionState.done:
                            if (snapshot.hasError) {
                              return Text('error');
                            } else if (snapshot.hasData) {
                              return Column(
                                mainAxisAlignment:
                                    MainAxisAlignment.spaceEvenly,
                                children: [
                                  Container(
                                    padding: EdgeInsets.only(top: 16),
                                    width: MediaQuery.of(context).size.width,
                                    height:
                                        MediaQuery.of(context).size.height / 4,
                                    decoration: BoxDecoration(
                                        boxShadow: [
                                          BoxShadow(
                                              color: Colors.white60,
                                              blurRadius: 15.0,
                                              offset: Offset(0.0, 0.75))
                                        ],
                                        gradient: LinearGradient(
                                          begin: Alignment(0.5, 0.85),
                                          end: Alignment(0.48, -1.08),
                                          colors: [
                                            const Color(0xFF0B0C3A),
                                            const Color(0xFF010611),
                                          ],
                                          stops: [
                                            0.0,
                                            0.5,
                                          ],
                                        ),
                                        borderRadius: BorderRadius.only(
                                            bottomRight: Radius.circular(32),
                                            bottomLeft: Radius.circular(32))),
                                    child: Column(
                                      children: [
                                        Row(
                                          children: [
                                            SizedBox(
                                              width: 30,
                                            ),
                                            Column(
                                                crossAxisAlignment:
                                                    CrossAxisAlignment.start,
                                                children: [
                                                  Text(
                                                    "$name",
                                                    style: TextStyle(
                                                        color: Colors.white,
                                                        fontSize: 25,
                                                        fontWeight:
                                                            FontWeight.bold),
                                                  ),
                                                  SizedBox(
                                                    height: 10,
                                                  ),
                                                  Text(
                                                    "$phone",
                                                    style: TextStyle(
                                                      color: Colors.white60,
                                                      fontSize: 18,
                                        
                                        ),
                                        Row(
                                          mainAxisAlignment:
                                              MainAxisAlignment.end,
                                          children: [
                                            Container(
                                                margin: EdgeInsets.symmetric(
                                                    vertical: 10),
                                                width: size.width * 0.4,
                                                child: ElevatedButton(
                                                  onPressed: () {
                                                    if (_nameController.text ==
                                                            "" &&
                                                        _emailController.text ==
                                                            "" &&
                                                        _adressController
                                                                .text ==
                                                            "") {
                                                      setState(() =>
                                                          isButtonDisabled =
                                                              true);
                                                    } else {
                                                      editUserProfile();
                                                    }
                                                  },    
                                                  child: Text('Enregistrer'),
                                                  style:
                                                      ElevatedButton.styleFrom(
                                                    primary: Colors.transparent,
                                                    shape:
                                                        RoundedRectangleBorder(
                                                            borderRadius:
                                                                BorderRadius
                                                                    .circular(
                                                                        20),
                                                            side: BorderSide(
                                                                color: Colors
                                                                    .white)),
                                                  ),
                                                )),
                                            SizedBox(
                                              width: 20,
                                  Container(
                                    height: MediaQuery.of(context).size.height /
                                        1.5,
                                    child: Column(
                                      mainAxisAlignment:
                                          MainAxisAlignment.start,
                                      children: [
                                        Column(
                                          mainAxisAlignment:
                                              MainAxisAlignment.start,
                                          children: [
                                            Container(
                                              width: size.width * 0.94,
                                              child: Column(
                                                mainAxisAlignment:
                                                    MainAxisAlignment.start,
                                                children: [
                                                  Container(
                                                    padding: EdgeInsets.only(
                                                        left: 10,
                                                        right: 10,
                                                        bottom: 20,
                                                        top: 20),
                                                    child: Column(
                                                      mainAxisAlignment:
                                                          MainAxisAlignment
                                                              .start,
                                                      crossAxisAlignment:
                                                          CrossAxisAlignment
                                                              .start,
                                                      children: [
                                                        Row(
                                                          mainAxisAlignment:
                                                              MainAxisAlignment
                                                                  .spaceBetween,
                                                          children: [
                                                            Text(
                                                              'Votre nom :',
                                                              style: TextStyle(
                                                                  color: Color(
                                                                      0xFF4053FCF),
                                                                  fontSize: 16,
                                                                  fontWeight:
                                                                      FontWeight
                                                                          .w600),
                                                            ),
                                                            IconButton(
                                                                icon: Icon(
                                                                  CommunityMaterialIcons
                                                                      .pencil,
                                                                  color: Colors
                                                                      .grey,
                                                                ),

how i can move to StreamBuilder correctly ?
what i should modify ?

My screen :

enter image description here

lucky
  • 185
  • 5
  • 18

1 Answers1

0

Basically it's impossible directly because FutureBuilder takes Future type, whereas StreamBuilder takes Stream type.

The way Future works is like it awaits for the things(mostly Remote API calls) to be done, and then when it's done, it returns the value and that's the end. There is no more interaction. So it has single return value.

However, Stream returns or yields the value constantly until you stop or dispose it. So it could have infinite number of return values by time.

So basically if you want to use your Future in the StreamBuilder, it will not work.

I don't know what you exactly want so if you have further questions please let me know with comments but if you want to turn Future into Stream, you can use Stream.fromFuture(future). However it only yields one event and will be closed. So I think there is no point unless you have good reasons to use StreamBuilder though you only need one single value.

But if you need to stay tuned to the changes of the data that Future delivers, making Stream from scratch might be the answer.

Stream<Type> myStream() async* {
    while (true) 
    {
        final fetchedData = await yourFuture();
        yield fetchedData;
    }
}

The function above generates a Stream that keeps calling your Future and yielding the value of the Future until it's disposed.

Now you can use StreamBuilder with Stream you made. How to use StreamBuilder is quite simliar to that of FutureBuilder. I hope you refer to this documentation about StreamBuilder Class.

CrimsonFoot
  • 325
  • 3
  • 13
  • I updated my post . I would like to fetch data from SharedPrefences (locally) not from api . but at the same time maybe i should modify name for example or adress ... i think to change to streambuilder to solve this problem bu i think it is not the right way – lucky May 29 '21 at 11:55
  • How i can fetch data locally and at the same time i can modify data if i want ? @CelesKang – lucky May 29 '21 at 12:02
  • 1
    Basically 'fetch' is read and 'modify' is update right? So just read the data from local db like SharedPreference and update the data after. I don't know exactly what you want but you don't have to update the data in your local db every time the data gets modified by user interactions. Just fetch data from your local db, and store them in state, and when everything is done in that page, update the data in your local db before you pop or leave the page. – CrimsonFoot May 30 '21 at 02:28
  • excatlly how data updated on the screen without leave the page ? – lucky May 30 '21 at 06:39
  • Now my problem is the data will updated when i login next time @CelesKang – lucky May 30 '21 at 07:16
  • Call update method! You don't have to leave the page. In what moment exactly do you want to update the data and what's the problem if the data is changed when you sign in next time? – CrimsonFoot May 30 '21 at 09:09
  • the product owner want to see the new value without leaving the profile page – lucky May 30 '21 at 09:13
  • So the problem here is like you first fetch the data from local db, and they appear, and when you edit them by clicking the pencil icon button, you will update the value in your local db but they don't show in the present page right? – CrimsonFoot May 30 '21 at 09:23
  • yes ... exactly . for more infomation : https://stackoverflow.com/questions/67759132/how-update-sharedpreferences-value-every-time-flutter – lucky May 30 '21 at 09:27
  • Then could you show me the code for editing the value? `editUserProfile()` seems to be the one. Could you show me its implementation? – CrimsonFoot May 30 '21 at 09:38
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/233079/discussion-between-lucky-and-celeskang). – lucky May 30 '21 at 09:40
  • go to chat @celeskang please – lucky May 30 '21 at 09:41