6

I am using multer for file uploading. On the server I have this:

stream.on('finish', () => {                                                                              
  console.log('finished')                                                                                
  next()
})

What would be the best way (with what command) to notify the frontend that 'finished' has happened? I want to know this in order to have a loading bar.

konyv12
  • 716
  • 2
  • 8
  • 23

4 Answers4

5

That's what websockets are for. The server can send data to the client, and vice-versa. Check out socket.io.

Server : socket.emit("upload finished")

Client : socket.on("upload finished", function...)

Jeremy Thille
  • 26,047
  • 12
  • 43
  • 63
2

While Jeremy Thille 's answer works well, beware of broadcasting event to all.

Socket.emit() simply broadcasts message to all connected clients.

So you need to store the client id of the uploader and notify the progress only to that client and not all. Refer this.

vinoth h
  • 511
  • 3
  • 11
1

You can use sockets for this type of communication. socket.io is a node package for web sockets. In the server you have

socket.emit('done')

whereas in the client side you can attach to the emit to receive new data

socket.on('done', function (data) {
    // Do something with data
}); 
Ivan Mladenov
  • 1,787
  • 12
  • 16
1

Well, I know I am 5 years 7 months late but still I want to share my opinion. Socket is a really good approach but another way can also be SSE(Server Sent Events) to automatically notify the frontend via HTTP but you can notify the frontend using only text message .

For FrontEnd:

  1. First you have to create eventsource object.
let sse = new EventSource(
       "URL for backend",
        { withCredentials: true }
      )

here credential is for the cookie to pass.

2.Now add eventListeners to get the result from backend.

see.onmessage = (e)=>{
let data = JSON.parse(e.data)
//now do whatever you want with the data
}

For Backend:

const express = require("express");
const bodyParser = require("body-parser");
const cors = require("cors");
const app = express();
const PORT = 5000;
let clients = [];

const event = (req, res) => {
 
  const headers = {
    'Content-Type': 'text/event-stream',
    'Connection': 'keep-alive',
    'Cache-Control': 'no-cache',
  }
  
  res.writeHead(200, headers)
  let message = { event_name: 'ONGOING' }

  const data = `data: ${JSON.stringify(facts)}\n\n`

  res.write(data)
  const clientId = Date.now()

  const newClient: Client = {
    id: clientId,
    response: res,
  }

  clients.push(newClient)

  req.on('close', () => {
    console.log(`${clientId} Connection closed`)
    clients = clients.filter((clients: Client) => clients.id !== clientId)
  })
};
const notifyEvent = ()=>{
 let newMessage = { event_name: 'FINISHED' }

  const data = `data: ${JSON.stringify(newMessage)}\n\n`
  
  // Send a message to each client
  clients.forEach((client) => client.response.write(data))
}
//Here goes your part
stream.on('finish', () => {                                                                              
  console.log('finished')
  return notifyEvent()                                                                         
  next()
})
app.get("/event", event);

app.listen(PORT, () => {
  console.log(`App listening on port ${PORT}`);
});

So this is basically the whole thing. I am attaching a link which helped me to understand the SSE. https://www.digitalocean.com/community/tutorials/nodejs-server-sent-events-build-realtime-app