Mohd Sabban
Mohd Sabban

Reputation: 192

How to send a response in Express

I am using express and MongoDB and want some real-time updates whenever any change happens in my DB. I use MongoDB change stream. But when I put my change function inside the route it only sends a response when I hit my route, and when I put the change function outside of the route I am unable to send a response.

So my problem how to send a response when any change happens in my collection.

const testSchema = new Schema({
  name: { type: String, required: true },
  email: { type: String, required: true },
});

const model = mongoose.model('test', testSchema);

//change 
model.watch().on('change', (data) => {
  console.log(data);
});

router.put('/update', async (req, res) => {
  const data = req.body;
  const info = await model.updateOne(data);
  res.send(info);
});

Upvotes: 1

Views: 451

Answers (2)

Dani
Dani

Reputation: 913

Solution: server-sent events

While you can also solve your issue using websockets, server-sent events are simpler to implement. See this answer

const mongoose = require("mongoose");
const express = require("express");
const app = express();
const testSchema = new Schema({
  name: { type: String, required: true },
  email: { type: String, required: true },
});

const model = mongoose.model("test", testSchema);

model.watch().on("change", (data) => {
  console.log(data);
});

app.put("/update", async (req, res) => {
  const data = req.body;
  const info = await model.updateOne(data);
  res.send(info);
});

app.get("/changes", async (req, res) => {
  res.writeHead(200, {
    "Content-Type": "text/event-stream",
    "Cache-control": "no-cache",
    "Access-Control-Allow-Origin": "*",
  });
  const changeHandler = (data) => {
    res.write(`data: ${JSON.stringify(data)}\n\n`);
  };
  model.watch().on("change", changeHandler);
  res.on("close", () => {
    model.watch().removeListener("change", changeHandler);
    res.end();
  });
});
app.listen(4000);

And the html:

<!DOCTYPE html>
<html>
  <body>
    <script>
      const eventSource = new EventSource("http://localhost:4000/changes");
      eventSource.onmessage = (e) => {
        console.log(e);
      };

      eventSource.onerror = (e) => {
        console.log("EventSource failed.");
      };
    </script>
  </body>
</html>

Upvotes: 1

Qudusayo
Qudusayo

Reputation: 1159

Whats you're trying to achieve relies on Web socket.
Sockets are the way in which you can make applications communicate across network.

Your browser uses socket programming. It establishes a connection with the server on port 80(only for HTTP requests) and gets data from the server and displays it according to the markup.

If you had played any online games like, Counter-Strike for example, where you had been a host then you would have understood its usage. You establish yourself as a host with certain port allocated to communicate. The game then passes data using that socket to other computers.

You'll have to learn and understand SocketIO to achieve this.

Most of the lessons out there are being explained how it can be used for chat applications. But if you understand it better, you'll be able to build anything upon socket.

Upvotes: 2

Related Questions