I want to simply be able to store a value in a key in one route
/api/foo?redisKey="1" (set value for id=1)
then I want to get the value in another route.
/api/bar?redisKey="1" (get value for id=1)
However, redis is async so you have to wait for it to connect
client.on('connect', function() {
//perform redis operations
});
I'm not sure how to synchronize this in my router.
I am going to assume you're using redis for your client library.
In your express route file, you do not want to create the connection during each request. Instead you will instantiate your redis client outside of the express middleware function, and use it during requests.
Here's a sample app:
var redis = require("redis");
var client = redis.createClient();
var express = require('express')
var app = express()
// GET request
// example: curl "localhost:3000/api/foo?redisKey=1"
app.get('/api/foo', function (req, res) {
var redisKey = req.query.redisKey
client.get(redisKey, function (err, reply) {
if(err){ res.status(400).send(err.getMessage()); return; }
res.status(200).send(reply.toString())
});
})
// for setting, use POST request
// example: curl -X POST "localhost:3000/api/foo?redisKey=1&redisValue=helloWorld"
app.post('/api/foo', function(req, res){
var redisKey = req.query.redisKey,
redisValue = req.query.redisValue
// assuming value is also a string in URL query string
client.set(redisKey, redisValue, function (err, reply){
res.status(200).send(reply.toString())
});
})
app.listen(3000, function () {
console.log('Example app listening on port 3000!')
})
Related
I have created a SQL server with a table that has data in on a server I have local access to. I have also created an "API" on that same server to get the information from the SQL server so it can be read by my angular application.
At the moment, I can read the rows in the SQL server and have them displayed in my angular application, but, I want to be able to update the SQL table from my angular app (through the API).
This is my API (sqlserver.js):
var express = require('express');
var app = express();
var cors = require('cors');
app.use(cors())
app.get('/', function (req, res) {
var sql = require("msnodesqlv8");
// config for your database
var config = "server=servername;Database=dataBaseName;Trusted_Connection=Yes;Driver={SQL Server Native Client 11.0}"
const query = "SELECT * FROM tableName";
// connect to your database
sql.query(config, query, (err, rows) => {
res.send(rows)
});
});
var server = app.listen(3097, function () {
console.log('Server is running..');
});
I want to be able to use the query
const query = "SELECT * from tableName WHERE ID LIKE <inputFromAngular>"
But I am not sure how to get the parameter from angular into the sqlserver.js. (If I can do this then it will lead to updating the SQL Table using SET
In my angular app this is how I am calling the sqlserver.js to display the SQL table:
import { HttpClient } from '#angular/common/http';
constructor(
private httpService: HttpClient
) { }
this.httpService.get("http://servername:3097").subscribe(response => {
console.log(response)
this.sqlData = response;
})
I have tried using this.httpService.post() but I wasn't sure how to get the parameters in the API?
You will need to change you get method to send params from ui side and get params on backend side so add a server side method like
app.get('/:id', function (req, res) {
var sql = require("msnodesqlv8");
var id = req.params.id,
// config for your database
var config = "server=servername;Database=dataBaseName;Trusted_Connection=Yes;Driver={SQL Server Native Client 11.0}"
const query = "SELECT * FROM tableName WHERE ID LIKE "+id;
// connect to your database
sql.query(config, query, (err, rows) => {
res.send(rows)
});
});
then on angular side
this.httpService.get("http://servername:3097/"+yourid).subscribe(response => {
console.log(response)
this.sqlData = response;
})
Also I would suggest you to create a root like /yourapiname/:id instead of /:id and url on angular side should be "http://servername:3097/yourapiname"+yourid because your current root can result to confliction.
I'm new to Node and am trying to build a simple server in Node using Express. The requests are in the form of say /input00001/1/output00001. What I need to do is to parse this request and if the flag is 1 (middle value), I need to replace the file \home\inputfiles\input00001.txt with file \home\outputfiles\output00001.txt. How is it possible to do that?
Here is my simple server so far. I'm OK with not using the Express and pure NodeJs if that makes things easier.
const express = require('express');
const app = express();
const port = 8000;
app.get('/', (request, response) => {
response.send('Hello from Express!');
request.param
});
app.get('/*', (request, response) => {
response.send('Start!');
var url = request.originalUrl;
});
app.listen(port, (err) => {
if (err) {
return console.log('something bad happened', err);
}
console.log(`server is listening on ${port} for incoming messages`);
});
You should set up a route that expects these items as url parameters and then use those parameters to do what you want. For example if you're url is /input00001/1/output00001 then you could set up a route like this:
app.get('/:input/:flag/:output', (req, res) => {
var params = req.params
var input = params.input //input0001
var flag = params.flag // 1
var output = params.output //output0001
// now do what you need to with input, flag, and output
if(typeof flag!=='undefined' && flag==1){
var file_name_string = '\home\inputfiles\input00001.txt';
var res = file_name_string.replace("input", "output");
}
console.log(input, flag, output)
res.send("done")
})
I have an ExpressJS routing for my API and I want to call it from within NodeJS
var api = require('./routes/api')
app.use('/api', api);
and inside my ./routes/api.js file
var express = require('express');
var router = express.Router();
router.use('/update', require('./update'));
module.exports = router;
so if I want to call /api/update/something/:withParam from my front end its all find, but I need to call this from within another aspect of my NodeJS script without having to redefine the whole function again in 2nd location
I have tried using the HTTP module from inside but I just get a "ECONNREFUSED" error
http.get('/api/update/something/:withParam', function(res) {
console.log("Got response: " + res.statusCode);
res.resume();
}).on('error', function(e) {
console.log("Got error: " + e.message);
});
I understand the idea behind Express is to create routes, but how do I internally call them
The 'usual' or 'correct' way to handle this would be to have the function you want to call broken out by itself, detached from any route definitions. Perhaps in its own module, but not necessarily. Then just call it wherever you need it. Like so:
function updateSomething(thing) {
return myDb.save(thing);
}
// elsewhere:
router.put('/api/update/something/:withParam', function(req, res) {
updateSomething(req.params.withParam)
.then(function() { res.send(200, 'ok'); });
});
// another place:
function someOtherFunction() {
// other code...
updateSomething(...);
// ..
}
This is an easy way to do an internal redirect in Express 4:
The function that magic can do is: app._router.handle()
Testing: We make a request to home "/" and redirect it to otherPath "/other/path"
var app = express()
function otherPath(req, res, next) {
return res.send('ok')
}
function home(req, res, next) {
req.url = '/other/path'
/* Uncomment the next line if you want to change the method */
// req.method = 'POST'
return app._router.handle(req, res, next)
}
app.get('/other/path', otherPath)
app.get('/', home)
I've made a dedicated middleware for this : uest.
Available within req it allows you to req.uest another route (from a given route).
It forwards original cookies to subsequent requests, and keeps req.session in sync across requests, for ex:
app.post('/login', async (req, res, next) => {
const {username, password} = req.body
const {body: session} = await req.uest({
method: 'POST',
url: '/api/sessions',
body: {username, password}
}).catch(next)
console.log(`Welcome back ${session.user.firstname}!`
res.redirect('/profile')
})
It supports Promise, await and error-first callback.
See the README for more details
Separate your app and server files with the app being imported into the server file.
In the place you want to call your app internally, you can import you app as well as 'request' from 'supertest'. Then you can write
request(app).post('/someroute').send({
id: 'ecf8d501-5abe-46a9-984e-e081ac925def',
etc....
});`
This is another way.
const app = require('express')()
const axios = require('axios')
const log = console.log
const PORT = 3000
const URL = 'http://localhost:' + PORT
const apiPath = (path) => URL + path
app.get('/a', (req, res) => {
res.json('yoy')
})
app.get('/b', async (req, res) => {
let a = await axios.get(apiPath('/a'))
res.json(a.data)
})
app.listen(PORT)
Having this function in express that writes a JSON file on a folder
var savingtheJson=function(path, jsonObject, callback){
jsonfile.writeFile(file2, jsonO, callback);
}
I will like to know how can I access/read this file from the browser once is saved.
If I do this:
savingtheJson('/json/myfile.json', jsonObj, function(){
console.log("done it!");
});
When I go to the browser and I type:
http://localhost:8080/json/myfile.json
Of course I get an error from express "Cannot Get ...." cause I think is trying to resolve it like an specific request
How can I store this file into the static folder declared for this goal
(app.use(express.static(__dirname + '/public'))?
How can I access this file once is saved?
First you need to define which folder is going to be exposed as public, so that you can save your json file inside there.
You can use the built-in middleware express.static for this purpose.
Below in the example I have created a endpoint called /users?name=wilson&age=32 which receives query data in order grab user's information as name and age for then you can save it as file named person.json.
So after you consume the above endpoint mentioned, you will be able to consume your file with something like http://localhost:4040/person.json successfully.
var express = require('express');
var app = express();
var port = 4040;
var fs = require('fs');
app.use(express.static('public'));
app.get('/users', function(req, res) {
var name = req.query.name;
var age = req.query.age;
var person = {
name: name,
age: age
};
savePersonToPublicFolder(person, function(err) {
if (err) {
res.status(404).send('User not saved');
return;
}
res.send('User saved');
});
});
function savePersonToPublicFolder(person, callback) {
fs.writeFile('./public/person.json', JSON.stringify(person), callback);
}
app.listen(port, function() {
console.log('server up and running at port: %s', port);
});
How would I access socket in the global scope based on my following NodeJS code
io.on('connection', function (socket) {
console.log('connection '+socket)
socket.on("data",function(d){console.log('data from flash: ',d);});
socket.emit("message","wtfwtwftwftwf hello from server");
socket.on('disconnect', function (socket) {
console.log("disconnect");
});
});
I need to access socket from within the following app.post method
var express = require('express'),
multer = require('multer');
var app = express();
//auto save file to uploads folder
app.use(multer({ dest: './uploads/'}))
app.post('/', function (req, res) {
console.log(req.body); //contains the variables
console.log(req.files); //contains the file references
res.send('Thank you for uploading!');
});
app.listen(8080);
Haven't tested yet but going to try a simple getter function first
io.on('connection', function (socket) {
console.log('connection '+socket)
socket.on("data",function(d){console.log('data from flash: ',d);});
socket.emit("message","wtfwtwftwftwf hello from server");
return{
getSocket: function(){
return socket;
}
};
socket.on('disconnect', function (socket) {
console.log("disconnect");
});
});
io.getSocket() ??
Express's app and Socket.io have nothing to do with one another.
So fundamentally, you can't use socket inside app.post.
You need to identify the client. You can use Passport which has a Socket.io plugin that essentially bridges the app.post/get's req.user to socket.request.user.
Note: It doesn't have to be an authenticated client with user that's fetched from database, just a client with a temporary user stored in memory would do. Something like this:
app.use(function(req, res, next) {
if (!req.user) { // if a user doesn't exist, create one
var id = crypto.randomBytes(10).toString('hex');
var user = { id: id };
req.logIn(user);
res.redirect(req.lastpage || '/');
return;
}
next();
});
var Users = {};
passport.serialize(function(user) {
Users[user.id] = user;
done(null, user);
});
passport.deserialize(function(id) {
var user = Users[id];
done(null, user);
});
Then you can attach the client's socket ID to its user session.
io.on('connection', function (socket) {
socket.request.user.socketid = socket.id
});
And then instead of socket.emit use io.emit in app.post using the socketid
app.post('/', function (req, res) {
io.to(req.user.socketid).emit('whatever');
});
Note: io.to() is used to emit to a room, but every socket is by default joined to the same room named as its socket.id, so it'll work.
Javascript and socketIO experts > please tell me why this simple solution shouldn't work. It seems to...
1 Define a global pointer
var _this=this;
2 In my socketIO handler make a reference to the socket object
_this.socket=socket;
3 And finally within app.post, access the socket like thus
_this.socket.emit(....