Create Web server using Node js model MVC - mysql

I'm trying to create a web server, and I'm using to MVC model so I tried to use routes inside so I don't know how can I do this. in the console log thats return all data otherwise in postman I test it it doesn't works. here is my code.
AirModel.js :
AirMonitoring.getAllData = (result) =>{
db.query('SELECT * FROM AirMonitoring', (err, res)=>{
if(err){
console.log('Error while fetching airMonitoring', err);
result(null,err);
}else{
console.log('AirMonitoring fetched successfully');
result(null,res);
}
})
}
airController.js :
exports.getAllData = (req, res)=> {
AirModel.getAllData((err, airMonitoring) =>{
if(err)
res.send(err);
console.log('data', airMonitoring);
res.send(airMonitoring)
})
}
index.js :
const server = http.createServer(function(req, res) {
console.log("http was created!");
if(req.url == '/airMonitoring'){
res.writeHead(200, { 'Content-Type': 'application/json' });
// get latest record of airMonitoring
router.get('/airMonitoring', airController.getAllData);
res.end();
}
});

It's not very clear what router is but I'm assuming it's an express router, and that's not how routing works. Currently you are (re?)defining the route on each request. The routing page is a good place to start, but basically you need to define the routes once.
var express = require('express')
var app = express()
app.get('/airMonitoring', airController.getAllData);
app.listen(PORT, () => {
console.log(`Example app listening at http://localhost:${PORT}`)
})
And also in your AirModel.js you have an error as far as I can tell, when handling the database error you should provide it as first argument, not second:
result(null,err); /* has to be result(err, null) */

Related

How to add a users auth in feathers middleware?

I use feathersjs framework in my projekt. In older version my middleware it was work but afer update a framework and after created new app with authenticate a middleware not working.
My index.js file show like below:
const cookieParser = require('cookie-parser');
const { authenticate } = require('#feathersjs/express');
module.exports = function (app) {
app.get('/login', (req, res) => {
res.sender('login');
});
app.use('/', cookieParser(), authenticate('jwt'), async (req, res) => {
const { user } = req;
try {
await app.service('users').get(user._id);
res.sender('home');
} catch(e){
res.redirect('/login');
}
});
}
I have a login script in jQuery like below:
$(document).ready(function(){
const socket = io();
const app = feathers();
app.configure(feathers.socketio(socket));
app.configure(feathers.authentication({
storage: window.localStorage
}));
$('.form-signin').submit(function(){
app.authenticate({
strategy: 'local',
username: $('#inputUsername').val(),
password: $('#inputPassword').val(),
}).then( result => {
document.cookie = "feathers-jwt=" + result.accessToken;
window.location.href = "/";
}).catch(error => {});
});
});
My problem is when I click a login button with a data correctly I receive an accessToken but I can't see home page and app show me every time 401 error code - not authorization with.
An console shows me this info: info: Invalid authentication information (no `strategy` set) {"type":"FeathersError","name":"NotAuthenticated","code":401,"className":"not-authenticated","errors":{}}
In new version not working too failureRedirect: '/login'
SOLUTION
Add below code before app.get('/', authenticate('jwt'), (req, res) => {});
app.use('/', cookieParser(), (req, res, next) => {
var cookies = req.cookies;
var token = cookies['feathers-jwt'];
req.authentication = {
strategy: 'jwt',
accessToken: token
}
next();
})

Angular HTTPClient (HTTP) requests pending forever

I have recently started working with MySQL as the database for my Angular/NodeJS project (I have been using MongoDB all along). Nonetheless, I'm encountering issues when handling HTTP Requests. I have experimented with GET and POST requests as of now, and GET is forever pending, until failure and POST doesn't post to backend and to the database, likewise. I really hadn't changed the backend configuration from the one I used with MongoDB database, except for the queries, of course.
I have tried debugging the backend to check whether the server is actually running and everything was okay. It just came to requests reaching the specified endpoints that they're always pending. I also tried to log to console if a request gets at a certain endpoint, but nothing was being logged, unfortunately.
server.js
const app = require("./backend/app");
const debug = require("debug")("node-angular");
const http = require("http");
const normalisePort = setPort => {
const port = parseInt(setPort, 10);
if (isNaN(port)) return setPort;
if (port >= 0) return port;
return false;
};
const port = normalisePort(process.env.PORT || "8000");
const server = http.createServer(app);
const error = error => {
if (error.syscall !== "listen") {
throw error;
}
const bind = typeof port === "string" ? "pipe " + port : "port " + port;
switch (error.code) {
case "EACCES":
console.error(bind + " requires elevated privileges");
process.exit(1);
break;
case "EADDRINUSE":
console.error(bind + " is already in use");
process.exit(1);
break;
default:
throw error;
}
};
const listening = () => {
const address = server.address();
const bind = typeof port === "string" ? "pipe " + address : "port " + port;
debug.enabled = true;
debug("Listening on " + bind);
};
app.set("port", port);
server.on("error", error);
server.on("listening", listening);
server.listen(port, "localhost");
app.js
const express = require("express");
const bodyParser = require("body-parser");
const cors = require("cors");
const users = require("./routes/users");
const app = express();
app.use(cors);
app.use(bodyParser.json());
app.use(
bodyParser.urlencoded({
extended: false
})
);
app.use((req, res, next) => {
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader(
"Access-Control-Allow-Headers",
"Origin, X-Requested-With, Authorization, Content-Type, Accept"
);
res.setHeader(
"Access-Control-Allow-Methods",
"GET, POST, PATCH, DELETE, OPTIONS"
);
next();
});
app.get("/api/users", users);
module.exports = app;
users.js
const express = require("express");
const router = express.Router();
const db = require("../sql-connection");
router.get("", (req, res, next) => {
db.query("select * from users;", (error, results, fields) => {
if (results.length > 0) {
return res.status(200).send(results);
} else {
return res.status(404).send();
}
});
});
module.exports = router;
sql-connection.js
const mysql = require("mysql");
const sqlConnection = mysql.createConnection({
host: "localhost",
user: "root",
password: "",
database: "payroll"
});
sqlConnection.connect(error => {
if (error) throw error;
console.log("connected to database");
});
module.exports = sqlConnection;
auth.service.ts
export class AuthService {
private _BASE_URL: string = "http://localhost:8000/api";
constructor(private http: HttpClient) {}
public get users(): Observable<any> {
return this.http.get(this._BASE_URL + "/users");
}
}
signup.component.ts
export class SignUpComponent {
constructor(private _authService: AuthService) {}
public onSignUp(): void {
this._authService
.users()
.subscribe(data => (data ? console.log(data) : console.log("no data")));
}
}
When subscribed to the users observable data from backend should logged to console if present, otherwise, 'no data' is logged on the console. Unfortunately, this request takes forever (pending). However, if I don't subscribe to users no request is sent/seen under network tab in dev tools.
I've been using MYSQL database and I would recommend using mysql2 over mysql
mysql2 provides promise based syntaxes over conventional callback methods.
Here's the documentation for Mysql2 for nodejs.
Coming to the problem, I guess it might be because Nodejs is asynchronous while you're using a synchronous approach in setting up the API.
Also when you're working with Asynchronous programming you have to use try-catch-finally instead of conventional if-else statements to log the errors.
So you can use async (req, res, next)=>{ //your code here } rather than just using (req, res, next)=>{ //your code here }.
Also you have to await before calling the sql query, i.e;
await db.query
or
rather in mysql2 it is easier to use const [data] = await pool.execute(query, [params]).

How to resolve 502 Mysql query error on Netlify (Express server)

I have a React app + Express server deployed on netlify here. I have a simple api endpoint that queries my MySql DB on AWS.
When I make the api request I am given a "Failed to load resource: the server responded with a status of 502".
If I just return a simple
res.send("simple response")
then everything works fine and I get the response on the client. Could someone point me in the right direction on what I should be looking for?
I've tried to disable the skip_name_resolve parameter on my db to see if the hostname mattered, opening up access to all ports / ip's on the aws security group, look up common examples of express + mysql server implementations, lookup the netlify function docs, and using async await in the server.
// client.jsx
useEffect( () => {
fetch("/.netlify/functions/server/api/getSalesData")
.then(res => res.json())
.then(res => console.log(res));
// server.js
const express = require("express");
const bodyParser = require("body-parser");
const serverless = require('serverless-http');
const mysql = require("mysql");
const db = mysql.createConnection({ ... });
db.connect(function(err) {
if (err) throw err;
console.log('You are now connected...')
});
const app = express();
const router = express.Router();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
router.get("/api/getSalesData", (req, res) => {
// res.send({ express: "Hello from express" });
db.query("SELECT * FROM Sales LIMIT 5", (err, rows) => {
if (err) throw err;
res.send(rows);
});
});
app.use('/.netlify/functions/server', router);
module.exports = app;
module.exports.handler = serverless(app);

File upload using mysql in express js

Currently i'm doing some projects using Express 4.x and in the project seems that want to handle file upload (example: upload image on form). I am using localhost as server (mysql), searching for clue most of people using multer but i can not get. any helps, i appreciate
Formidable which helps you parse and get files from the POST request
Example code:
const formidable = require('formidable');
const fs = require('fs');
const path = require('path');
// POST | /upload
app.post('/upload', (req, res) => {
const form = new formidable.IncomingForm();
form.parse(req, (error, fields, files) => {
if(error){
res.status(500);
console.log(error);
res.json({
error,
});
return false;
}
const image = files.image;
console.log(image.name) // pony.png
console.log(image.type) // image/png
// Get the tmp file path
const tmpFilePath = image.path; // /tmp/<randomstring>
// Rename and relocate the file
fs.rename(tmpFilePath, path.join(`${__dirname}/uploads/${image.name}`), error => {
if(error){
res.status(500);
console.log(error);
res.json({
error,
});
return false;
}
res.status(201);
res.json({
success: true,
upload_date: new Date(),
});
// Do all kinds of MySQL stuff lol
});
});
});

Parsing JSON in Express without BodyParser

I'm trying to write a simple express server that takes incoming JSON (POST), parses the JSON and assigns to the request body. The catch is I cannot use bodyparser. Below is my server with a simple middleware function being passed to app.use
Problem: whenever I send dummy POST requests to my server with superagent (npm package that lets you send JSON via terminal) my server times out. I wrote an HTTP server in a similar fashion using req.on('data')...so I'm stumped. Any advice?
const express = require('express');
const app = express();
function jsonParser(req, res, next) {
res.writeHead(200, {'Content-Type:':'application/json'});
req.on('data', (data, err) => {
if (err) res.status(404).send({error: "invalid json"});
req.body = JSON.parse(data);
});
next();
};
app.use(jsonParser);
app.post('/', (req, res) => {
console.log('post request logging message...');
});
app.listen(3000, () => console.log('Server running on port 3000'));
I think the problem like to get rawBody in express.
Just like this:
app.use(function(req, res, next){
var data = "";
req.on('data', function(chunk){ data += chunk})
req.on('end', function(){
req.rawBody = data;
req.jsonBody = JSON.parse(data);
next();
})
})
And you need catch the error when parse the string to json and need to judge the Content-type of the Req.
Good luck.
another way that worked with me by collecting all chunks into an array and parsing the concatenated chunks.
app.use("/", (req, res, next)=>{
const body = [];
req.on("data", (chunk) => {
console.log(chunk);
body.push(chunk);
});
req.on("end", () => {
const parsedBody = Buffer.concat(body).toString();
const message = parsedBody.split('=')[1];
console.log(parsedBody);
console.log(message);
});
console.log(body);
});
To get access to req.body this worked for me:
app.use(express.json({extended: false}));
In Express v4.16.0 onwards:
app.use(express.json())