I'm using Express.JS and trying to display statistics of my work's HelpDesk system.
The HelpDesk software has it's own REST API. example:("servicedesk.co.uk:8080/sdpapi/request?INPUT_DATA=bla")
Currently, I am calling the API and returning the data I need. In my 'Index.js' I have:
(I'm using node-rest-client)
var express = require('express');
var router = express.Router();
var Client = require('node-rest-client').Client;
var callCount = 0;
/* GET home page. */
router.get('/', function (req, res, next) {
var client = new Client();
client.get("http://servicedesk.co.uk:8080/sdpapi/request?INPUT_DATA=bla", function (data, response) {
// parsed response body as js object
callCount = (data.operation.details.length);
res.render('index', { title: 'ServiceDesk Dashboard', appSupportCallCount: callCount });
});
});
This passes the data I want, to my 'index.hbs'.
What I want, is to somehow monitor the existing REST API, for any changes(i.e. when a new support ticket is raised in the helpdesk system). Then update the data being displayed on my 'index.hbs' - preferrably without the page actually reloading.
I've been looking into socket.io, long polling, etc. but cannot seem to find a way of accomplishing this.
If it cannot be completely real-time. Then I guess I can periodically, make the request to the API and then send the new response to my index.hbs - not sure how I'd do this though.
Thanks in advance for any help provided.
Related
I'm am learning node.js and therefore try to build a simple web app that shows the current news. The API that I am using offers several categories for the news.
So I create a route that takes the category as a param. My routes/index.js:
const router = require('express').Router();
const renderHome = require('../controllers/newsController');
const quotesCookie = require('./../middleware/quotesCookie');
router.get('/', quotesCookie, renderHome);
router.get('/:category', quotesCookie, renderHome);
module.exports = router;
My controllers/newsController.js looks like this:
const newsService = require('./../services/newsService');
const renderHome = async ( req, res ) => {
const category = req.params.category;
console.log(req.params);
const quote = res.quoteOfTheDay;
const { status, msg } = await newsService.topHeadlines(category);
res.render('home', {
title: 'News2Go',
author: quote.author,
quote: quote.quote,
articles: msg.articles
});
};
module.exports = renderHome;
When I for instance call http://localhost:3000/entertainment the console.log in the controller prints this to the console:
{ category: 'entertainment' }
{ category: 'sw.js' }
I have absolute no clue where the sw.js comes from... It appears a few milliseconds after the real category and ensures that topHeadlines is called twice.
Did someone know what this is? Did I miss something?
Apparently your web page has a script in it named sw.js. Because of that, the browser will request that with the URL http://localhost:3000/sw.js and your :category route will handle that request and log a category of sw.js.
Remember, ALL resources used on your site will be requested by the browser and will be seen by your Express server as incoming requests. Not just the top level page, but all scripts, images, fonts, CSS files, etc... used by your pages.
It's generally not a good idea to define a wide-open top level route handler like this:
router.get('/:category', ...)
Because that will grab ALL top level URLs and leave none for the rest of your site to use. It would probably make more sense to use a structure like this:
router.get('/category/:category', ...)
With a URL of http://localhost:3000/category/entertainment. Then, you can more clearly separate out the actual category requests from all the other requests in your site. Either that or you will have to move ALL other URLs used on your site to routes that come before this and/or use sub-directories in their page such as:
http://localhost:3000/scripts/sw.js
http://localhost:3000/styles/main.css
I am trying to send a variable from my client-side JavaScript file to my server-side app.js file. I know that you can get a value from something like a form input field using methods such as the one below (using Express):
var express = require('express');
var app = express();
var path = require('path');
let cityResponse;
app.post('/city', function(req,res) {
cityResponse = {
user_name: req.body.userName
}
res.sendFile(path.join(__dirname, '/client/city/index.html'));
});
But I would like to get a value not directly from the HTML, but from the JavaScript file that the HTML is attached to.
As well as this, I am currently using Socket.io to send the data from the server to the client, and vice versa, using a window.onload to let the server know when the page is ready:
index.js
window.onload = function() {
socket.emit('cityPageReady');
console.log("city page ready");
};
socket.on('cityPageInfo', function(cityResponse) {
console.log('city page info received');
console.log(cityResponse);
console.log(cityResponse.user_name);
userName = cityResponse.user_name;
document.getElementById("name").innerHTML = userName;
});
app.js
var city = io.of('/city').on('connection', (socket) => {
console.log('A user has connected!');
socket.on('cityPageReady', function() {
socket.emit('cityPageInfo', cityResponse);
console.log('city page ready recieved');
});
});
This works, but many people have said that this is overkill, or as one person put it, "using a hammer to kill a bee". Ideally, I'd like to use the optimal method. I do know that template engines can achieve this, but I do not want to have to rewrite all my HTML just to be able to send a single variable to the server.
To reiterate, my questions are:
How would I get a variable from the client-side JavaScript file (not the HTML)?
What is the best way to send these variables back over to client-side?
Any help would be greatly appreciated.
I'm developing a calendar application with Node.js, express.js and Sequelize.
The application is simple, you can create tasks in your calendar, but you can also assign some tasks to others users of the system
I need to create a notification system with socket.io, but I don't have experience with websockets. My big doubt is how can I make my server send a notification to the user that you assign the task?
My ports configurations is on a folder called bin/www, my express routes are defined on a file called server.js
Any Idea?
I want to introduce you to ready to use backend system that enables you to easily build modern web applications with cool functionalities:
Persisted data: store your data and perform advanced searches on it.
Real-time notifications: subscribe to fine-grained subsets of data.
User Management: login, logout and security rules are no more a burden.
With this, you can focus to your main application development.
You can look at Kuzzle, wich is one project I working on:
First, start the service:
http://docs.kuzzle.io/guide/getting-started/#running-kuzzle-automagically
Then in your calendar application you can the javascript sdk
At this point you can create a document:
const
Kuzzle = require('kuzzle-sdk'),
kuzzle = new Kuzzle('http://localhost:7512');
const filter = {
equals: {
user: 'username'
}
}
// Subscribe every changes in calendar collection containing a field `user` equals to `username`
kuzzle
.collection('calendar', 'myproject')
.subscribe(filter, function(error, result) {
// triggered each time a document is updated/created !
// Here you can display a message in your application for instance
console.log('message received from kuzzle:', result)
})
// Each time you have to create a new task in your calendar, you can create a document that represent your task and persist it with kuzzle
const task = {
date: '2017-07-19T16:07:21.520Z',
title: 'my new task',
user: 'username'
}
// Creating a document from another app will notify all subscribers
kuzzle
.collection('calendar', 'myproject')
.createDocument(task)
I think this can help you :)
Documents are served though socket.io or native websockets when available
Don't hesitate to ask question ;)
As far as I can understand you need to pass your socket.io instance to other files, right ?
var sio = require('socket.io');
var io = sio();
app.io = io;
And you simply attach it to your server in your bin/www file
var io = app.io
io.attach(server);
Or what else I like to do, is adding socket.io middleware for express
// Socket.io middleware
app.use((req, res, next) => {
req.io = io;
next();
});
So you can access it in some of your router files
req.io.emit('newMsg', {
success: true
});
I'm trying to achieve something what I think should be very simple to do, but all the tutorials and examples I find seem to be an overkill.
What I am doing:
I'm fetching weather info periodically, and I want to update the text on the website everytime its fetched without user having to refresh the browser.
Almost every tutorial on realtime data updating recommends using socket.io and I have given it a try, but I can't get it to do what I want and I'm starting to think that there should be an easier way and that socket.io might not be the best way to go about this. Any suggestions? How do I get simple line of text update on website without user having to refresh the page?
My weather script:
var express = require('express');
var app = express();
var server = require('http').Server(app);
var io = require('socket.io')(server);
function refreshWeather() {
var temperature = getTemperature();
io.sockets.emit('broadcast', {
temperature : temperature
});
}
My jade script:
doctype html
html
head
link(rel='stylesheet', href='/css/index.css')
title Dashboard
body
script(src='/socket.io/socket.io.js')
script.
var socket = io();
socket.on('broadcast', function (data) {
// UPDATE WEATHER HERE
});
.main-content
h1 Weather is: // I WANT THIS TO BE UPDATED
You could:
Get rid of socket.io.
Make an end point for retrieving the temperature.
Do some polling on the frontend.
Backend would look something like this:
var express = require('express');
var app = express();
var server = require('http').Server(app);
app.get('/weather', function (req, res) {
res.send(getTemperature())
});
Frontend would look something like this:
doctype html
html
head
link(rel='stylesheet', href='/css/index.css')
title Dashboard
body
.main-content
h1(id='weather') Weather is: // I WANT THIS TO BE UPDATED
script.
setInterval(function () {
fetch('/some/url', {
method: 'get'
}).then(function(response) {
// UPDATE WEATHER HERE
document.getElementById('weather').innerHTML = response
}).catch(function(err) {
// Error :(
});
}, 1000) // milliseconds
Code is totally untested, so please try not to copy and paste — adapt it instead. Also, if you're going to use the fetch API, you might want to use a polyfill, otherwise, just use plain ajax.
I am taking a look at Node.js and thinking about using it for building an API. From what I can tell, ExpressJS would be the web framework and is not what I'd be looking for to solve this.
So what would a web service look like? Would it simply be creating a server, talking to mongo and returning results? Also, what does routing look like? (I'd obviously want to 'design' the routes).
If Express would be your web framework, look at the express-resource (Github) middleware for routing an API. You define resources and it'll wire up REST-style routing for you with very little boilerplate.
app.resource('horses', require('./routes/horses'), { format: json })
Given the above, express-resource will hook up all the REST-style routes to actions you supply, returning JSON by default. In routes/horses.js, you export actions for that resource, along the lines of:
exports.index = function index (req, res) {
// GET http://yourdomain.com/horses
res.send( MyHorseModel.getAll() )
}
exports.show = function show (req, res) {
// GET http://yourdomain.com/horses/seabiscuit
res.send( MyHorseModel.get(req.params.horse) )
}
exports.create = function create (req, res) {
// PUT http://yourdomain.com/horses
if (app.user.canWrite) {
MyHorseModel.put(req.body, function (ok) { res.send(ok) })
}
}
// ... etc
You can respond with different representations:
exports.show = {
json: function (req, res) {
// GET http://yourdomain/horses/seabiscuit.json
}
, xml: function (req, res) {
// GET http://yourdomain/horses/seabiscuit.xml
}
}
Middlewares like express-resource can make life with Node and Express much easier, take a look through the examples on github to see if it'll do what you need.
Here is a stub that looks up a horse name from a Postgres database and returns the result as JSON. Clients would access would access the API by going to address such as http://yourdomain.com/api/horse/seabiscuit
app.get('/api/horse/:name', function(req, res){
pg.connect(conString, function(err, client) {
var horse = req.params.name;
var sql = "...";
client.query(sql, function(err, result) {
if (err) {
...
}
for (var i=0; i<result.rows.length; i++) {
// Customize data as needed
}
return res.send(JSON.stringify(result.rows));
});
});
});
Node is pretty low level. It's like C in JavaScript's clothing. Since it's comparable to C, there's pretty much a lot you can do with Node. Creating web servers is just one of them. You can create live chat servers using sockets, blogs, streaming etc. The possibilities are infinite. You are limited only by your imagination.
Routing is just a task where you take in commands (commonly via URL or headers) and do tasks based on those commands passed.
But even I have not yet scathed the surface of node. It's API is huge and getting bigger. Better try using some basic library like Express or Connect first since they pretty much abstract the basic requirement of building the server from code.