Home > OS >  Changing a property of all objects in an array in Flutter
Changing a property of all objects in an array in Flutter

Time:12-02

I have an array that stores objects of two types. These two types are OwnMessageCard and ReplyCard. I use Socket.IO in my project.

late IO.Socket _socket;
var myMessagesList = < Widget > [];
_connectSocket() async {
    final prefs = await SharedPreferences.getInstance();
    myUsername = prefs.getString('myUsername') !;

    _socket.onConnect((data) => print('Connection established'));
    _socket.onConnectError((data) => print('Connection error: $data'));
    _socket.onDisconnect((data) => print('Socket disconnected.'));
    _socket.on(myUsername, (data) {
        setState(() {
            myMessagesList.add(ReplyCard(
                senderMessage: data['message'].toString(),
                sentAt: data['sentAt'].toString(),
            ));
        });
        _socket.emit('seen', {
            'sender': myUsername,
            'target': targetUsername
        });
    });
    _socket.on("$myUsername/seen", (data) {
        setState(() {
            myMessagesList.forEach((element) {
                if (element == OwnMessageCard) {
                    //Some codes here to change 'isSeen' property to 'true'

                }
            });
        });
    });
}

I want to set isSeen property of all OwnMessageCard object to true when a message comes from _socket.on("$myUsername/seen", (data){}. OwnMessageCard has two properties of myMessage and isSeen. How can I do that?

Update: OwnMessageCard class:

class OwnMessageCard extends StatelessWidget {
  OwnMessageCard({super.key, required this.myMessage, required this.isSeen});
  final String myMessage;
  bool isSeen;

  @override
  Widget build(BuildContext context) {
    final currentTime = DateTime.now();
    return Align(
      alignment: Alignment.centerRight,
      child: ConstrainedBox(
        constraints: BoxConstraints(
            maxWidth: MediaQuery.of(context).size.width - 45, minWidth: 180),
        child: Card(
          elevation: 1,
          shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
          color: ownMessageBackColor,
          margin: const EdgeInsets.symmetric(horizontal: 15, vertical: 5),
          child: Stack(
            children: [
              Padding(
                padding: const EdgeInsets.only(
                    left: 25, right: 10, top: 5, bottom: 25),
                child: Text(
                  myMessage,
                  style: const TextStyle(fontSize: 18, fontFamily: 'FMitra'),
                ),
              ),
              Positioned(
                bottom: 4,
                right: 10,
                child: Row(
                  children: [
                    Icon(
                      Icons.done_all,
                      size: 20,
                      color: isSeen ? Colors.blue : Colors.grey,
                    ),
                    const SizedBox(
                      width: 5,
                    ),
                    Text(
                      "${currentTime.hour}:${currentTime.minute} | ${currentTime.year}-${currentTime.month}-${currentTime.day}",
                      style: TextStyle(fontSize: 12, color: Colors.grey),
                    )
                  ],
                ),
              )
            ],
          ),
        ),
      ),
    );
  }
}

CodePudding user response:

First of all you can't compare variable with type by == , you need to use is, second you can change your data like this, I assume this is your class model:

class OwnMessageCard {
  final bool isSeen;
  final String message;

  OwnMessageCard({
    required this.isSeen,
    required this.message,
  });
}

and you can change your data like this:

_socket.on("$myUsername/seen", (data) {
        var newList = myMessagesList.map((e) => e is OwnMessageCard ? OwnMessageCard(isSeen: true,message: e.message ) : e)
            .toList();

        setState(() {
            myMessagesList = newList;
        });
    });
    
    
  • Related