1

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),
                    )
                  ],
                ),
              )
            ],
          ),
        ),
      ),
    );
  }
}
7
  • element.isSeen = true ??? Commented Dec 2, 2022 at 7:06
  • @AnteBule I tested it. There is an error in isSeen and says: The setter 'isSeen' isn't defined for the type 'Widget'. Commented Dec 2, 2022 at 7:08
  • Try element is OwnMessageCard instead of element == OwnMessageCard Commented Dec 2, 2022 at 7:10
  • @AnteBule It's saying 'isSeen' can't be used as a setter because it's final. Commented Dec 2, 2022 at 7:11
  • Remove final on isSeen property in your OwnMessageCard class Commented Dec 2, 2022 at 7:12

1 Answer 1

2

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;
        });
    });
    
    
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.