Express.js - How to send alert from Express to Client using res.render? Not res.send
There are a lot of problems here. For one I'm not sure you understand how try catch blocks work. You have an unnecessary amount of ifs that aren't being handled too. Those problems aside, the answer to the question you asked is a websocket. From the looks of your code and question, I think what you're really looking for is how to send a response from an http get request in express. There are many ways to solve the problem you are asking to be solved. From the code I see above I don't think you have a good understanding of client/server models and It would be to your benefit to read up on how http works. I also can't answer your question because the code snippet you pasted does not provide enough context to answer your question. Most importantly though, alert is not a function in node. calling alert does nothing. In fact when you do res(alert("something")), if alert is defined in your global namespace (I hope it isn't), you are sending back undefined. There is such a thing as isomorphism, however, web api functions are exclusive to the client. I hope that helps.
Sending notification to clients in Node.JS
Like Dimitar wrote earlier, you could use socket.io to send messages from the server to the client and vice versa. This can be done as simple as that:
//Server sent message:
io.on('connection', (socket) => {
socket.emit('notificationToClient', 'Message'); //message sent from server to client
});
});
//Client receives the message:
const socket = io.connect('http://localhost:3000');
socket.on('notificationToClient', (data) => { //received message
console.log(data);
});
The websocket API is a little less confusing than socket.io but IMO, I'd go with socket.io since it already deals with a lot of the heavy lifting like re-connecting, custom namespaces, rooms etc. There are several fantastic udemy courses on socket.io.
See the socket.io documentation here: https://socket.io/docs/
Update 5/9/2020:
Michel - Since you asked about how to implement Socket.io in your code I'll give you an example of how I implemented this technology in my most recent project. I was working on a web app that connects to ELK Alarm systems and is able to arm/disarm these systems as well as receive sensor input (chime signals) at any remote location. The backend is Node.js and the UI is React.
//client side code
import React, { Component, Suspense } from 'react';
import panels from "./panels.js"
const socketConnection = io("http://localhost:5000"); //Socket.io
function App() {
function handleClick(panel) {
socketConnection.emit("panelData", panel); //Socket.io - sends the connection data for the ELK alarm panel to the express server
socketConnection.on('data', (data) => { //Socket.io - receives data from the server.
//does something with the data
})
}
}
//server side code
const express = require('express');
const elkClient = require('elk-client');
const app = express();
const server = app.listen('5000', () => {
console.log('------Server Running on 5000---------');
});
let io = new sio(server);
io.on("connection", (socket) => { //boilerplate code - establishes the "handshake" with the client.
socket.on("panelData", async (msg) => { //receives the ELK connection parameters from the client. See client side code
const client = new ElkClient({
connection: {
site: msg.name,
host: msg.host,
}
})
await client.connect();
client.on("message", (elkMessage) => { // This is NOT Socket.io - server is listening for emitted data from the alarm system - beam breaks, alarms, arm/disarm etc. [See event emitter][2]
if(elkMessage.messageType == 'A' && elkMessage.subMessageType == 'S') {
const armingStatusReport = {elkMessage};
socket.emit("data", armingStatusReport); //Socket.io - emits the received data to the client.
}
})
I tried to simplify the code above to hit the point. The server is using the connection parameters that it receives from the client to connect to a remote alarm system. The server then waits and listens for incoming data with client.on()(event emitter - not socket.io). As the data is received, I'm using Socket.io to send the received data back to the client with socket.emit(); Due to the nature of how alarm systems work, data is sent event driven so the fetch api wouldn't really fit the bill but socket.io (or websockets) does.
Let me know if I can help with anything else. With this recent project, I have spent the last few months EXTENSIVELY dealing with socket.io, including namespaces, rooms etc. I also had to create a real-time monitoring app for performance management for my server utilizing socket.io since I implemented clustering. Feel free to contact me anytime!
How to display an alert using client-side JavaScript after a post has happened on the server side?
You would need to add a .then()
method call to your handleFormSubmit
method, so:
fetch('http://127.0.0.1:3000/comment').then(() => {
alert('comment added');
})
fetch
returns a Promise
, and is an async
method call, so in your case, alert
is triggered after the fetch
call is made but not necessarily completed. The .then()
method is triggered once the Promise
is resolved, so in order to run code once this happens, you store it in the .then()
method.
Now in your specific use case, you want to handle successful calls and errored calls. But there is one other consideration - are you only using failed calls to determine whether a call is successful, or can the server's response signify an error? By default, fetch
doesn't convert the response to json
(assuming your data is being returned from the server as json
. . For this, you would need to do the following (assuming the server returns a success/fail response as well:
fetch('http://127.0.0.1:3000/comment').then((res) => {
return res.json();
}).then((res) => {
if (res === 'success') {
alert('comment added');
} else {
alert('An error has occurred when trying to add your comment');
}
}).catch((e) => {
alert('An error has occurred when trying to add your comment');
})
A few other points that I had missed originally, but from the conversation in the comment thread:
Since your API is exposed by the server as a POST
request, you need to add additional options to your fetch
request, changing the method to POST
, as well as adding the data that you want to send to the server. To do this, you can add the following:
let options = {
method: 'POST',
headers: {
"Content-Type": "application/json"
},
// where data is your form fields
body: JSON.stringify(data)
}
// Replace '...' with code from above or whatever functionality you
// need once Promise resolves
fetch('http://127.0.0.1:3000/comment', options).then(...)
For more on fetch
, check out https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
To get form data values, if there aren't too many, you can try this for each of the fields: let val = document.getElementById('someId').value
Lastly, the way your form is currently set up, once you hit submit, it will refresh by default. If you want to prevent that from happening, before the fetch
call, add event.preventDefault()
, where event
is the EventListener
that was triggered (your current method signature should be sufficient for this).
Access a route, send an error alert, and redirect
I dont recommend doing that (sending html in server side response)
Instead:
Send a json with a variable that will tell you in the client side to make an alert:
res.json({ success: false });
Ans then in the client side you can alert a message if !success and redirect.
how to use NodeJS pop up a alert window in browser
"after sever(Nodejs) received post message from front end?" show a pop up in the browser. This can not be done. I assume you want to show a popup in if the post request is success. Because you mention about Ajax, This is how it is done.
in your post router definition in the server do it as follows
router.post('/path', function(req, res){
//do something
res.jsonp({success : true})
});
something like this. finally you want to send something form the server to the client. after in the client side javascript file send the post request as follows.
$.ajax({
url:"/url/is/here",
method: "POST",
data : {
data : "what you want to send",
put : "them here"
},
cache : false,
success : function (data) {
// data is the object that you send form the server by
// res.jsonp();
// here data = {success : true}
// validate it
if(data['success']){
alert("message you want to show");
}
},
error : function () {
// some error handling part
alert("Oops! Something went wrong.");
}
});
Sending a notification to user using Node.js
What you are describing is "server push" where the server proactively notifies a user on their site of some activity or event. In the web browser world these days, there are basically two underlying technology options:
- webSocket (or some use socket.io, a more feature rich library built on top of webSocket)
- server sent events (SSE).
For webSocket or socket.io, the basic idea is that the web page connects back to the server with a webSocket or socket.io connection. That connection stays live (unlike a typical http connection that would connect, send a request, receive a response, then close the connection). So, with that live connection, the server is free to send the client (which is the web page in a user's browser), notifications at any time. The Javascript in the web page then listens for incoming data on the connection and, based on what data it receives, then uses Javascript to update the currently displayed web page to show something to the user.
For server sent events, you open an event source on the client-side and that also creates a lasting connection to the server, but this connection is one-way only (the server can send events to the client) and it's completely built on HTTP. This is a newer technology than webSocket, but is more limited in purpose.
In both of these cases, the server has to keep track of which connection belongs to which user so when something interesting happens on the server, it can know which connection to notify of the event.
Another solution occasionally used is client-side polling. In this case, the web page just regularly sends an ajax call to the server asking if there are any new events. Anything new yet? Anything new yet? Anything new yet? While this is conceptually a bit simpler, it's typically far less efficient unless the polling intervals are spaced far apart, say 10 or 15 minutes which limits the timeliness of any notifications. This is because most polling requests (particularly when done rapidly) return no data and are just wasted cycles on your server.
Related Topics
Multiply and Sum Input Values Created Dynamically in Jquery
Mutlple Owl Carousel in One Page With Different Setting
Bootstrap 4 Navbar-Toggler-Icon Does Not Appear
Fix: Js Recursive Function to Get the Nested (Multilevel) Child Objects as Array of Objects
React.Js - Input Losing Focus When Rerendering
Get Index on Click of a Mapped Array in React Js
How to Set Maximum Length in Input Type=Number
Sum of Numbers in an Array With JavaScript
Why Am I Getting Undefined as an Answer When Fetching Data from an API
How to Avoid Scientific Notation for Large Numbers in JavaScript
How to Loop Over Object Properties With Ngfor in Angular
How to Tell If a Dom Element Is Visible in the Current Viewport
Javascript, Track Iframes Redirecting Top Window
Getting Selected Values from Dropdown Inside Table
React-Select:Get Default Value in React-Select