Flutter GetX stream value not changing when text field value changes

586 views Asked by At

So, I'm trying to display a stream using a list view from a stream function, that takes an input from the text field.

Stream<List<UserModel>> queryByName(search) {
return FirebaseFirestore.instance
.collection("users")
.orderBy("firstName")
.startAt([search]).endAt([search + '\uf8ff'])
.limit(10).snapshots()
 .map(userListFromQuerySnapshot); }

..

Column(
      children: [
        Padding(
          padding: EdgeInsets.all(10),
          child: Obx(
            () => TextField(
              onChanged: (text) {
                _.search.value = text;
              },
              decoration: InputDecoration(hintText: 'Search keyword'),
            ),
          ),
        ),
        GetX<PalsViewController>(
          init: Get.put<PalsViewController>(PalsViewController()),
          builder: (PalsViewController palsViewController) {
            return Expanded(
              child: ListView.builder(
                  itemCount: palsViewController.viewPals.length,
                  itemBuilder: (_, index) {
                    return Column(
                      children: [
                        Padding(
                            padding: EdgeInsets.all(10),
                            child: Row(children: [
                              palsViewController.viewPals[index]
                                          .profileImageUrl !=
                                      ''
                                  ? CircleAvatar(
                                      radius: 20,
                                      backgroundImage: NetworkImage(
                                          palsViewController.viewPals[index]
                                              .profileImageUrl),
                                    )
                                  : Icon(Icons.person, size: 30),
                              SizedBox(width: 10),
                              Text(palsViewController
                                  .viewPals[index].firstName)
                            ])),
                        const Divider(
                          thickness: 1,
                        )
                      ],
                    );
                  }),
            );
          },
        )
      ],
    ),

So, here's the issue.. the bind stream receives only the initial input of the search string which is empty.. and it's not changing when the text field value changes.

RxList<UserModel> viewPals = RxList<UserModel>([]);

var search = ''.obs ;

@override
 void onInit() {
 super.onInit();
 viewPals.bindStream(UserService.instance.queryByName(search.value));
}
1

There are 1 answers

8
Maqsood On

Try using like this. hope it will help you resolve your bindStream issue.

Stream<List<UserModel>> queryByName(search) {
  return FirebaseFirestore.instance
      .collection("users")
      .orderBy("firstName")
      .startAt([search]).endAt([search + '\uf8ff'])
      .limit(10).snapshots().map((QuerySnapshot query) {
    List<UserModel> retVal = [];
    query.docs.forEach((element) {
      retVal.add(UserModel.fromDocumentSnapshot(element));
    });
    return retVal;
  });
}

and in your onInit() use like this.

UserService.instance.queryByName(search.value).listen((event) {
   viewPals.assignAll(event);
});

and use viewPals like this.

var viewPals = <UserModel>[].obs;

use this as model class

class UserModel {
  String id;
   String bannerImageUrl;
   String profileImageUrl;
   String lastName;
   String firstName;
   String phoneNumber;
  UserModel(
      { this.id,
       this.bannerImageUrl,
       this.profileImageUrl,
       this.lastName,
       this.firstName,
       this.phoneNumber});

  UserModel.fromDocumentSnapshot(DocumentSnapshot jsonMap) {
    try {
      id = jsonMap.id;
      bannerImageUrl = jsonMap.get('bannerImageUrl') != null ? jsonMap.get('bannerImageUrl').toString() : '';
      profileImageUrl = jsonMap.get('profileImageUrl') != null ? jsonMap.get('profileImageUrl') : '';
      lastName = jsonMap.get('lastName') != null ? jsonMap.get('lastName') : '';
      firstName = jsonMap.get('firstName') != null ? jsonMap.get('firstName') : '';
      phoneNumber = jsonMap.get('phoneNumber') != null ? jsonMap.get('phoneNumber') : '';
    } catch (e) {
      id = null;
      bannerImageUrl = '';
      profileImageUrl = '';
      lastName = '';
      firstName = 'null';
      phoneNumber = '';
      print(e);
    }
  }
}