Pass data through different sockets by ID’s in change stream


I’m trying to improve my use of sockets and change streams with mongoDB,
I have two streams checking two different documents (Posts & Comments), once a user comments on a post, commentId (FK) is assigned in the Post Modal in the comments array. I’d to like to somehow add data from the comments socket to my post socket by matching postId’s, so that once the getPost() controller is called the data is populated and up to date and in the client side the post socket is being called when any changes occur.

Server.js (Change Streams with socket.emit)

const db = mongoose.connection;
db.once('open', () => {
    //post changes
    console.log(chalk.blueBright("Setting change streams"));
    db.collection('posts').watch()
    .on('change', change => {
        if(change.operationType === 'insert'){
            console.log(chalk.yellowBright('INSERTED'))
            io.emit('posts', change.fullDocument);
            console.log(change.fullDocument)
        }
    });
    db.collection('posts').watch({ fullDocument: 'updateLookup' })
    .on('change', change => {
        if(change.operationType === 'update'){
            console.log(chalk.yellowBright('UPDATED'));
            io.emit('posts', change.fullDocument);
            console.log(change.fullDocument)
        }
    })

    //comments changes
    db.collection('comments').watch()
    .on('change', change => {
        if(change.operationType === 'insert'){
            console.log(chalk.yellowBright('INSERTED'))
            io.emit('comments', change.fullDocument);
            console.log(change.fullDocument)
        }
    });
    //comments changes
    db.collection('comments').watch()
    .on('change', change => {
        if(change.operationType === 'insert'){
            console.log(chalk.yellowBright('INSERTED'))
            io.emit('comments', change.fullDocument);
            console.log(change.fullDocument)
        }
    });
    db.collection('comments').watch({ fullDocument: 'updateLookup' })
    .on('change', change => {
        if(change.operationType === 'update'){
            console.log(chalk.yellowBright('UPDATED'));
            io.emit('comments', change.fullDocument);
            console.log(change.fullDocument)
        }
    })
}); 

Client-Side

//Check socket changes
    useEffect(() => {
      const handler = (item) => {
        setPosts((oldPosts) => {
          const findItem = oldPosts.find((post) => post._id === item.comments.postId);
          if (findItem) {
            return oldPosts.map((post) => (post._id === item.comments.postId ? item : post));
          } else {
            return [item, ...oldPosts];
          }
        });

        
      };
      socket.on("posts", handler);
      return () => socket.off("posts", handler);
       //eslint-disable-next-line react-hooks/exhaustive-deps
    }, []);

Then in the client side we’re just making use of useEffect to check for any changes. Note that getPosts() controller is only being in use when the page is refreshed, thus it’s not being populated when changes occur, thus is why I’d like to add data from the one socket to the other, before being called from the client side, is this possible?

Source: React – Stack Overflow

November 4, 2021
Category : News
Tags: changestream | mongodb | node.js | reactjs | sockets

Leave a Reply

Your email address will not be published. Required fields are marked *

Sitemap | Terms | Privacy | Cookies | Advertising

Senior Software Developer

Creator of @LzoMedia I am a backend software developer based in London who likes beautiful code and has an adherence to standards & love's open-source.