Handling POST and GET requests in Express - express

First time using express here.
I have the following in my app.js file:
const express = require("express");
const mysql = require("mysql");
const app = express();
const PORT = process.env.PORT || 8000;
const connection = mysql.createConnection({
host: "localhost",
user: "admin",
password: "password",
database: "mydb",
});
app.use(express.static(__dirname + "/express"));
app.use(express.urlencoded()); // have also tried with "extended: true" and "extended: false"
app.use(express.json());
// GET
app.get("/getAllUserActivity", (req, res) => {
const order = req.query.order || "id";
const page = req.query.page || 0;
const limit = req.query.limit || 100;
connection.connect((err) => {
if (err) throw err;
connection.query(
"SELECT id, username, counter FROM users ORDER BY ? LIMIT ?,?",
[order, page, limit],
(err, results, fields) => {
if (err) throw err;
res.send(results);
}
);
});
});
// POST
app.post("/updateUserActivity", (req, res) => {
const userId = req.body.userId;
const username = req.body.username;
const counter = req.body.counter;
connection.connect((err) => {
if (err) throw err;
connection.query(
"INSERT INTO users (id, username, counter) VALUES (?, ?) ON DUPLICATE KEY UPDATE counter = counter + ?",
[userId, username, counter],
(err, results, fields) => {
if (err) throw err;
res.send(results);
}
);
});
});
My POST requests have the header "Content-Type": "application/x-www-form-urlencoded".
The issue I am facing is two-fold:
The GET request fails every other time. First time it returns the expected data, but the second time I get Incomplete response received from application - repeat.
I can only get either the POST or the GET request to work - depending on how I setup the middleware. How can I have both GET and POST here?
Old php user here, trying to figure out Express. Thanks!

Replace all if (err) throw err; with sending an actual error response back to the client. You MUST always send some form of response to every incoming request. It is a shame that many pieces of demo code show that if (err) throw err; because inside an asynchronous callback, that is pretty much never the correct code.
Then (though I don't know the specific details of your database) you will need to release/close your database connections after using them so they do not leak. Or, you can use a pooled set of connections where they are automatically returned to the pool after doing a query.

Related

"Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client" after adding "return"

So I have a router to post data and it gives an error Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client. I reviewed previously asked questions about the same error and all of them suggesting to put return in front of response. But in my situation, it is already the case.
This is the router in blogs.js that gives the error:
blogRouter.post('/', async (req, res) => {
const body = req.body;
const token = req.token;
const decodedToken = jwt.verify(token, process.env.SECRET);
if ((!token || !decodedToken)) {
res.status(401).json({ error: 'unauthorized: token missing or invalid' });
return;
} else if (!body.title || !body.url) {
res.status(400).json({error: 'Missing data'});
return;
}
const user = await User.findById(decodedToken.id);
const blog = new Blog({
title: body.title,
author: body.author,
url: body.url,
user: user._id,
likes: body.likes ? body.likes : 0
});
const result = await blog.save();
user.blogs = user.blogs.concat(blog);
await user.save();
return res.status(201).json(result);
});
My error handler middleware is throwing HTTP 404. I have checked the endpoint both in the request and in the middleware.
This is my middleware if that can help
What is causing the issue here? Any help will be appreciated!
I figured that our. In my middleware where I extract token I had:
const tokenExtractor = (req, res, next) => {
const authorization = req.get('authorization');
console.log(authorization);
if (authorization && authorization.toLowerCase().startsWith('bearer ')) {
req.token = authorization.substring(7);
next() // remove this!
}
next();
};
next() should not have been called for two times but only when given task (in this case if block of my code) would not have resolved. So I removed next() in my if block as it resolves the task.
Next time, I will do better debugging before posting it there.

How to fix [Error: Network Error] calling localhost api using react native and express js

I'am currently studying React native and Express JS for my server side. So now I do practicing calling api from express js to react native and I use axios to call http request. My problem is in my cmd it shows that [Error: Network Error]. To be more specific I will show you guys my sample work both server.js and components and sample screenshot Error on my cmd.
[Error: Network Error]
Server JS:
const express = require('express');
var cors = require('cors')
const bodyParser = require('body-parser');
const mysql = require('mysql');
const connection = mysql.createPool({
host : '192.168.61.1',
user : 'root',
password : '',
database : 'sample_db'
});
if(connection) {
console.log(connection);
}
// Starting our app.
const app = express();
var cors = require('cors');
app.use(cors());
// Creating a GET route that returns data from the 'mobile' table.
app.get('/api/readings', function (req, res) {
// Connecting to the database.
connection.getConnection(function (err, connection) {
// Executing the MySQL query (select all data from the 'mobile' table).
connection.query('SELECT * FROM tbl_mobile', function (error, results, fields) {
// If some error occurs, we throw an error.
if (error) throw error;
// Getting the 'response' from the database and sending it to our route. This is were the data is.
res.send(results)
});
});
});
// get the specific meter
app.get('/api/readings/:id', function (req, res) {
// Connecting to the database.
connection.getConnection(function (err, connection) {
// Executing the MySQL query (select all data from the 'mobile' table).
connection.query('SELECT * FROM tbl_mobile WHERE id = ?',req.params.id, function (error, results, fields) {
// If some error occurs, we throw an error.
if (error) throw error;
// Getting the 'response' from the database and sending it to our route. This is were the data is.
res.send(results)
});
});
});
// Starting our server.
app.listen(3000, () => {
console.log('http://192.168.61.1/api/readings');
});
Axios:
axios.get('http://192.168.61.1:3000/api/readings')
.then(function (response) {
// handle success
console.log(response);
})
.catch(function (error) {
// handle error
console.log(error);
})
.then(function () {
// always executed
});
Response:

Nuxtjs - Authentication

I wrote a sign up functionality in nuxtjs. It saves a new user in my database. However, there seems to be a problem with generating a token afterwards, to log in the user.
The register action gets called by a method in the register component. It returns the error response in the catch block. It seems to fail after the token is generated on the server.
Action in the store
async register ({ commit }, { name, slug, email, password }) {
try {
const { data } = await this.$axios.post('/users', { name, slug, email, password })
commit('SET_USER', data)
} catch (err) {
commit('base/SET_ERROR', err.response, { root: true })
throw err
}
}
Post function on the nodejs server
router.post('/users', async (req, res) => {
try {
const body = _.pick(req.body, ['name', 'slug', 'email', 'password']);
const user = new User(body);
await user.save();
const token = await user.generateAuthToken(); // execution seems to fail on this line
console.log(token); // never gets called
req.session['token'] = 'Bearer ' + token;
req.session['user'] = user;
res.header('Authorization', 'Bearer ' + token).send(user);
} catch (err) {
res.status(400).json({ message: "Der Account konnte leider nicht erstellt werden" });
}
});
GenerateAuthToken function in mongo model User
UserSchema.methods.generateAuthToken = function () {
var user = this;
var access = 'auth';
var token = jwt.sign({_id: user._id.toHexString(), access}, process.env.JWT_SECRET).toString();
user.tokens.push({access, token});
return user.save().then(() => {
return token;
});
};
Error message
I would be tremendously thankful for any kind of help!
Maybe it doesn't help too much, but I would try to create a dummy token and try to make everything works with it. One of my debugging techniques is to isolate every single part of my code and be sure that everything works piece for piece, maybe that technique is slow but most of the time it works.
If everything works, I would continue debugging the generateAuthToken function.
If your console log never gets called, then the error could be in the function.
I hope it helps a little and sorry I don't know too much about MongoDB but everything seems to be ok.

Not getting any response for save

Whenever I request on 8081/list_user there is no response. When I open localhost:8081 I get a response but not for localhost:8081/list_user.Both files are in the same folder is there any issues with that.Please check this issue what's problem in that.
// grab the things we need schema.js file
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
// create a schema
var userSchema = new Schema({
name: String,
});
// the schema is useless so far
// we need to create a model using it
var User = mongoose.model('User', userSchema);
// make this available to our users in our Node applications
console.log("Schema")
module.exports = User;
////////////Next file
var express = require('express');
var app = express();
var User = require('./schema');
// This responds with "Hello World" on the homepage
app.get('/', function (req, res) {
console.log("Got a GET request for the homepage",User);
res.send('Hello GET');
})
// This responds a POST request for the homepage
app.post('/', function (req, res) {
console.log("Got a POST request for the homepage");
res.send('Hello POST');
})
// This responds a DELETE request for the /del_user page.
app.delete('/del_user', function (req, res) {
console.log("Got a DELETE request for /del_user");
res.send('Hello DELETE');
})
// This responds a GET request for the /list_user page.
app.get('/list_user', function (req, res) {
console.log("Got a GET request for /list_user");
var newUser = User({
name: 'Peter Quill',
});
// save the user
newUser.save(function(err) {
if (err) throw err;
res.send('User created!');
console.log('User created!');
});
})
// This responds a GET request for abcd, abxcd, ab123cd, and so on
app.get('/find', function(req, res) {
User.find({}, function(err, users) {
if (err) throw err;
// object of all the users
console.log(users);
res.send(users)
});
})
var server = app.listen(8081, function () {
var host = server.address().address
var port = server.address().port
console.log("Example app listening at http://%s:%s", host, port)
})
When I tested .save function the way it was I couldn't even get an error message. What I did was add a connection with my local database (at schema file) to test properly.
mongoose.connect('mongodb://localhost/test');
In order to do this, first you have to certify that you have a local mongodb server running (or you could just connect to an online server), mongoose.connect receives my connection string as parameter ("test" is the database name, if it doesn't exist it will be created automatically). Last thing I did was add new when I create an user.
var newUser = new User({
name: 'teste',
});

res.json() won't work when trying to display data

I am using Nodejs, express, and postgresql to create a rest api. This is my first time doing any of this so I apologize for the noobness. I have been just testing this out and seemed to be about to get retrieve information from a database locally but when I try to send the data with res.json() nothing shows up. Here is the code I have so far.
var express = require('express');
var client = new pg.Client({user: 'xxx', password: 'xxx', database: 'xxx', host: 'xxx'});
var app = express();
app.get('/test1', function(req,res){
var name;
client.connect(function(err){
if(err){
return console.error('could not connect to postgres', err);
}
client.query("select classname from class", function(err, result){
if(err){
return console.error('error running query', err);
}
name = result.rows[0].classname;
console.log(name);
client.end();
});
});
res.send(name);
});
I used the console log and it printed out what I needed but for some strange reason it won't send. Thanks for the help! Also, if you see anything else wrong don't be afraid to say it. Thanks!
It's an asynchronous function so it would go like this:
var express = require('express');
var client = new pg.Client({
user: 'xxx',
password: 'xxx',
database: 'xxx',
host: 'xxx'
});
var app = express();
app.get('/test1', function(req, res) {
var name;
client.connect(function(err) {
if (err) {
return console.error('could not connect to postgres', err);
}
client.query("select classname from class", function(err, result) {
if (err) {
return console.error('error running query', err);
}
name = result.rows[0].classname;
console.log(name);
client.end();
res.send(name);
});
});
});
What is happening in your code is that you are sending before the query is done executing. You can see it on the console because your log statement is correctly executing after the query.
Also you should take care of your errors as well - so instead of returning do another res.send (or res.json) with some error mesg.