'send previous messages in group chat

I work at a chat application. I want to store messages in an object like this :

{
  'room1': ['msg1', 'msg2', ...]
  'room2': ['msg3', 'msg4', ...]
  ...
}

I defined a variable in my socket.io server roomMessages the problem is when I want to add a message in a specific room using roomMessages[room].push(data); it shows me this error: TypeError: Cannot read properties of undefined (reading 'push') this is my socket.io code:

const roomMessages = {};

roomsNamespace.use((socket, next) => {
  const token = socket.handshake.query.token;
  console.log(token);
  if (!token) return next(new Error("not auth"));
  next();
});

roomsNamespace.on("connection", (socket) => {
  const token = socket.handshake.query.token;
  const apiService = new ApiService(process.env.BE_URL, token);
  const room = socket.handshake.query.room;
  socket.on("join-room", async () => {
    socket.join(room);
    await apiService.joinRoom(room);
    const usersInThisRoom = await apiService.getUsersInRoom(room);
    roomsNamespace.in(room).emit("all-users", usersInThisRoom);
    socket.emit("room-messages", roomMessages[room]);
  });
  socket.on("chat-message", (data) => {
    // console.log(data);
    if (roomMessages[room]) roomMessages[room].push(data);
    roomsNamespace.in(room).emit("chat-message", data);
  });

basically, I want to send previous messages when user joins the chat How to fix this error?



Solution 1:[1]

you can do something like this

const roomMessages = {};

const getMessages = (room) => roomMessages[room] || []
const addMessage = (room, message) => {
  roomMessages[room] = [...getMessages(room), message]
}



roomsNamespace.use((socket, next) => {
  const token = socket.handshake.query.token;
  console.log(token);
  if (!token) return next(new Error("not auth"));
  next();
});

roomsNamespace.on("connection", (socket) => {
  const token = socket.handshake.query.token;
  const apiService = new ApiService(process.env.BE_URL, token);
  const room = socket.handshake.query.room;
  socket.on("join-room", async () => {
    socket.join(room);
    await apiService.joinRoom(room);
    const usersInThisRoom = await apiService.getUsersInRoom(room);
    roomsNamespace.in(room).emit("all-users", usersInThisRoom);
    socket.emit("room-messages", getMessages(room));
  });
  socket.on("chat-message", (data) => {
    // console.log(data);
    addMessage(room, data)
    roomsNamespace.in(room).emit("chat-message", data);
  });


in this way if you want later you can change your implementation of messageRepository storing data in redis or wherever you want

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 R4ncid