I create a map object and write down the id at the key, the username as the value, everything works fine on the server side, the collection is output to the console, but when I pass it to the client side, it is either not transferred correctly or does not work at all. Everything worked fine with the array. Server:
socket.on('connect user', (userName) => {
//users.push(userName.userConnect);
users.set(id , userName.userConnect); // map users
console.log(users);
io.emit("users", users); // passing the collection
Client:
const addUserToModalWindow = () => {
const contentWindow = document.querySelector(".usersList");
socket.on('users', (users) => {
for (let user of users) {
console.log(user);
}
});
};
Writes an error: users is not iterable.
CodePudding user response:
The problem is because of the library you're using, 
CodePudding user response:
You're trying pass JavaScript objects through TCP socket (http, web-socket). TCP sockets are not language specific and cannot deal with native js objects. But they can work with strings and binary data.
But socket.io library is pretty smart and can figure out you're passing an object. It will run JSON.stringify on your value (will convert to string) then send it through the network and on the client side will convert it back to the object with JSON.parse.
Everything would work if simple objects would be used. But in this case ES6 Map is used. When JSON.stringify is used on map it will always be converted to empty object. Like this:
Server
const map = new Map();
map.set(1, { name: "Joh Doe" });
JSON.stringify(map); // '{}'
Client
JSON.parse(map); // {}
Then on client side you try to for of loop on empty object. This kind of loop will work on ES6 Map but not on object.
for (const v of {}) console.log(v) // is not iterable Error
for (const v of new Map()) console.log(v) // works fine
The solution to this problem is pretty simple: Don't try send ES6 Map. Use plain object instead.
Instead of this:
const users = new Map();
users.set(1, { name: "Joh Doe" });
Use this:
const users = {};
users[1] = { name: "Joh Doe" };
Client side:
socket.on('users', (users) => {
for (let user of Object.values(users)) {
console.log(user);
}
});

