Flutter/Dart "Cannot modify an unmodifiable list" occurs when trying to sort a list that is the snapshot of a stream of lists
Asked Answered
S

2

10

This is the code inside the builder method of the Streambuilder that causes the issue:

List<User> users = snapshot.data;
users.sort((user1, user2) => (user1.distanceInKm ?? 1000).compareTo(user2.distanceInKm ?? 1000));

If I use the following stream for the Streambuilder the above sorting works:

static Stream<List<User>> getUsersStreamWithDistance(
      {@required User loggedInUser}) {
    try {
      var userSnapshots = _fireStore.collection('users').snapshots().map(
          (snap) => snap.documents
                  .map((doc) => User.fromMap(map: doc.data))
                  .where((user) => user.email != loggedInUser.email)
                  .map((user) {
                user.updateDistanceToOtherUser(otherUser: loggedInUser);
                return user;
              }).toList());
      return userSnapshots;
    } catch (e) {
      print(e);
      return null;
    }
  }

But not when I use the following stream, which is the one I need (ZipStream is from rxdart package):

static Stream<List<User>> getSpecifiedUsersStreamWithDistance(
      {@required User loggedInUser, @required List<String> uids}) {
    try {
      List<Stream<User>> listOfStreams = [];
      for (var uid in uids) {
        Stream<User> streamToAdd = _fireStore
            .collection('users')
            .where('email', isEqualTo: uid)
            .snapshots()
            .map((snap) => snap.documents
                    .map((doc) => User.fromMap(map: doc.data))
                    .map((user) {
                  user.updateDistanceToOtherUser(otherUser: loggedInUser);
                  return user;
                }).toList()[0]);
        listOfStreams.add(streamToAdd);
      }

      Stream<List<User>> usersStream = ZipStream.list(listOfStreams);

      return usersStream;
    } catch (e) {
      print(e);
      return null;
    }
  }
Songster answered 21/12, 2019 at 19:8 Comment(0)
K
18

Its because, ZipStream.list() creates a new Stream of List.unmodifiable() list.

List<User> users = List.from(snapshot.data); // to convert it editable list
users.sort((user1, user2) => (user1.distanceInKm ?? 1000).compareTo(user2.distanceInKm ?? 1000));
Kimes answered 21/12, 2019 at 20:40 Comment(1)
You are a legend..It Worked 👌Chatwin
A
0

An unmodifiable list cannot have its length or elements changed.

Check out the docs: Flutter Unmodifiable and List.from().

You can try cloning the list.

    final List<SnapshotModel> clonedSnapshot = [...snapshotList];

    // Try wrapping your snapshot with List.from()
    final List<SnapshotModel> clonedSnapshotV2 = List.from(snaspshot.map().toList());
Apocrypha answered 7/9 at 6:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.