How to send a redis object from app.js to html <div>? - express

I am building a quick Express JS application. I have sent data to Redis from another application.
I did an LPUSH. I was able to do this:
client.lrange('stash', 0, 10, function(err, reply) {
console.log(reply);
});
My goal is to, instead of doing a console.log("..."), I want to send it to a in my index.html.
Any ideas on how to do this?
EDIT: Here is my app.js file:
var express = require('express');
var redis = require('redis');
var app = express();
app.use(express.static('public')); //used to get image
app.engine('html', require('ejs').renderFile); //ejs, not handlebars
function index(req,res, next) {
testController.index(req, res, next);
}
app.get('/', function(req, res){
res.render('index.html');
});
app.get('*', function(req, res){
res.render('404.html');
});
//redis stuff
var client = redis.createClient();
client.on('connect', function() {
console.log('connected');
});
client.lrange('stash', 0, 10, function(err, reply) {
console.log(reply); //instead of this, let's place that into a div
});
//end redis
app.listen(3000, function(){
console.log('My example app is now running! (3000)')
});

from my understanding you could use ejs to plug in data directly into your html. The problem of course is that I don't know how client.lrange works but I know that express reads middleware top to bottom. If lrange is pulling data you need from the db you can save the data to a global var data and on a call to the endpoint of the html you want updated; render it with ejs.
create a place holder for the data
var data;
pull the data from server and save globally
client.lrange('stash', 0, 10, function(err, reply) {
data = reply;
});
render html page with ejs using ejs tags
app.get('/', function(req, res) {
res.render('index.html', {reddisData: data});
});
plug it into your html
<a>
<%= reddisData %>
</a>
all together
var express = require('express');
var path = require('path');
app = express()
app.engine('html', require('ejs').renderFile);
app.set('html', 'ejs');
var data;
client.lrange('stash', 0, 10, function(err, reply) {
data = reply;
});
app.get('/', function(req, res) {
res.render('index.html', {reddisData: data});
});
Hope this helps, if it doesn't work for you the idea is what counts. Look into using ejs to resolve your problem.

Related

Load post response into existing html page

all:
I have an API call using express and I'm wanting the data to load into an existing paragraph tag on the html page with the form, but currently it loads into a new html page using res.send(). Have checked the express documentation and cannot find anything. Any ideas how I can do this? Here is the code:
const express = require('express');
const app = new express();
const port = 3000;
const request = require('request');
app.use(express.urlencoded({extended: true}));
app.get("/", (req, res) => {
res.sendFile(`${__dirname}/index.html`);
})
app.post("/", (req, res)=>{
let crypto = req.body.crypto;
let fiat = req.body.fiat;
request(`https://apiv2.bitcoinaverage.com/indices/global/ticker/${crypto}${fiat}`, function (error, response, body) {
let data = JSON.parse(body);
let price = data.last;
res.write(`<h1>${price}</h1>`);
});
})
app.listen(port, ()=>{
console.log('Listening on port 3000');
})
Thank you all so much,
Kevin

routes in exported router not available in app

I'm trying to export a router 'Accounts' to use in my app. The 'Accounts' router has the paths '/login' (POST), '/register'(POST), 'login' (GET), and '/logout' (POST). In my index app I am using the router with the path '/account'. So the paths should be:
/account/login (POST)
/account/login (GET)
/account/register(POST)
/account/logout (GET)
But when I call these paths they aren't found by the app:
How do I get the paths in the 'accounts.js' router to work in the 'index.js' app?
My file structure is like this:
my account.js file looks like this:
const express = require('express');
const passport = require('passport');
const Account = require('../models/Account');
const Branch = require('../models/Branch')
const router = express.Router({mergeParams: true});
const registerAccount = (req, res, next) => {
//register the account
};
const createUser = (req,res) => {
//create a user in another db
}
router.post('/register',
[registerAccount, createUser]);
router.get('/login', function(req, res) {
res.json(user);
});
router.post('/login', passport.authenticate('local', { successRedirect: '/',
failureRedirect: 'account/login' }));
router.get('/logout', function(req, res) {
req.logout();
res.redirect('/');
});
});
module.exports=router;
and my index.js looks like this:
// index.js
var express = require("express");
var bodyParser = require("body-parser");
var jwt = require("jwt-simple");
var auth = require("../auth/auth.js")();
var users = require("./users.js");
var cfg = require("../config.js");
const accountController = require('./account');
var app = express();
app.use(bodyParser.json());
app.use(auth.initialize());
app.use('/account',accountController);
app.get("/", function(req, res) {
res.json({
status: "My API is alive!"
});
});
app.post("/token", function(req, res) {
//some token stuff that doesn't matter here
});
module.exports = app;
For starters, you don't pass an array to a router.post(), so change this:
router.post('/register', [registerAccount, createUser]);
to this:
router.post('/register', registerAccount, createUser);
And make sure that registerAccount calls next() when it's done and wants createUser() to get called.
In the doc, for this syntax:
app.post(path, callback [, callback ...])
the brackets in [, callback] mean that parameter is optional. The brackets are not supposed to be used.

Express - How to dispatch the same path to different router file?

I'm making an app the will let different users see the different root page. Let's say there are two groups: admin and viewer. What I want to do is like:
var admin = require('./routes/admin');
var viewer = require('./routes/viewer');
app.get('/', function(req,res,...) {
if (req is admin) app.use('/', admin);
else app.use('/', viewer);
});
Is this possible, or I should redirect them to different paths? Thanks!
This needs to be done by redirecting a route to other route according to the requirement.
This can be done using below code:
var express = require('express');
var app = new express();
app.get('/', function(req, res, next) {
if(true) { //group check
res.redirect('admin');
} else {
res.redirect('viewer')
}
});
app.use('/admin', function(req, res, next) {
res.send('admin')
});
app.use('/viewer', function(req, res, next) {
res.send('viewer')
});
app.listen(3000);

socket emit an event on http PUT

I am using expressjs, nedb, and socket.io. Various (non-browser) clients are able to PUT new values into the db successfully. When that happens, I want a message emitted to all browsers connected to the server. I have the following code which is currently not sending a message back to the browser.
// on the server
//***************************************************************
// reachable to the world at http://server/foo
// clients can PUT data into the db
app.put('/foo', jsonParser, function(req, res, next) {
if (!req.body) return res.sendStatus(400);
db.insert(req.body, function (err, newDoc) {
io.sockets.emit('PUT a new value', { added: newDoc._id });
res.send('Success! Find it again with id: ' + newDoc._id);
});
});
// reachable to the world at http://server/
// browser shows a dashboard of events
app.get('/', function(req, res, next) {
// code to serve the dashboard here
});
io.sockets.on('connection', function (socket) {
socket.on('foo', function (data) {
io.sockets.emit('PUT a new value', data);
})
});
// in the browser
//***************************************************************
var socket = io.connect('/');
socket.on('PUT a new value', function (data) {
console.log(data);
});
Data get inserted into the db successfully from different non-browser clients, but the connected browser doesn't receive an update.
What am I doing wrong?
I found a solution which I don't like at all but it works. We can add io object to req or to res in the middleware like that:
app.use(function (req, res, next) {
req.io = io;
next();
});
before app.use('/', routes) and then in our router module we "import" the io object:
app.put('/foo', jsonParser, function(req, res, next) {
if (!req.body) return res.sendStatus(400);
db.insert(req.body, function (err, newDoc) {
var io = req.io; // HERE !!!
io.sockets.emit('PUT a new value', { added: newDoc._id });
res.send('Success! Find it again with id: ' + newDoc._id);
});
});
I know, I know... let's find something else :-)
I have the following app structure generated by express generator. I start the app with $ DEBUG=foo:* npm start
.
|____app.js
|____bin
| |____www
|____data
|____LICENSE
|____node_modules
|____package.json
|____public
| |____stylesheets
| |____javascripts
| |____images
|____README.md
|____routes
| |____index.js
| |____readings.js
| |____sensors.js
| |____users.js
|____views
| |____error.hjs
| |____index.hjs
In app.js
var express = require('express');
var app = express();
var io = require('socket.io')();
app.io = io;
// notice the `(io)` for the routes that need to be socket-aware
var routes = require('./routes/index');
var users = require('./routes/users');
var sensors = require('./routes/sensors');
var readings = require('./routes/readings')(io);
…
// start listening with socket.io
app.io.on('connection', function(socket){
console.log('a user connected');
});
module.exports = app;
Then in ./routes/readings.js
var express = require('express');
var app = express();
var router = express.Router();
module.exports = function(io) {
router.put('/', jsonParser, function(req, res, next) {
if (!req.body) return res.sendStatus(400);
db.insert(req.body, function (err, newDoc) {
io.emit("reading", {id: newDoc._id});
res.send('Success PUTting data! id: ' + newDoc._id);
});
});
return router;
}
Finally, in the index.hjs template for the client-side
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io();
socket.on('reading', function (data) {
console.log(data);
});
</script>
The above works. When data are inserted into the db via an http PUT (see readings.js), an event is emitted by io.emit('reading', data) and the browser receives that event and shows it in the console with socket.on('reading', function (data) { … });

Where should I put the middleware if a sub router module used in Express.js

All:
When I learn how to upload file with Express.js, there is a middleware called multer ( https://github.com/expressjs/multer ), and from its Usage example:
var express = require('express')
var multer = require('multer')
var upload = multer({ dest: 'uploads/' })
var app = express()
app.post('/profile', upload.single('avatar'), function (req, res, next) {
// req.file is the `avatar` file
// req.body will hold the text fields, if there were any
})
app.post('/photos/upload', upload.array('photos', 12), function (req, res, next) {
// req.files is array of `photos` files
// req.body will contain the text fields, if there were any
})
var cpUpload = upload.fields([{ name: 'avatar', maxCount: 1 }, { name: 'gallery', maxCount: 8 }])
app.post('/cool-profile', cpUpload, function (req, res, next) {
// req.files is an object (String -> Array) where fieldname is the key, and the value is array of files
//
// e.g.
// req.files['avatar'][0] -> File
// req.files['gallery'] -> Array
//
// req.body will contain the text fields, if there were any
})
The middleware object directly used in app.js, I wonder if I use sub router like:
app.js
var routes = require('./routes/index');
app.use("/", routes);
index.js
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index', { title: 'Express' });
});
router.post('/upload', function(req, res, next) {
debugger;
console.log(req.body.upld);
console.log(req.file);
res.send("");
});
module.exports = router;
I wonder where should I put that upload middleware? Should I put that var upload = multer({ dest: 'uploads/' }) in each file use it? If so, will this cause several uploads folders generated in different folders based on the router file located?
Thanks