how to move into multiple json objects - javascript

i wrote a login page code in js that runs on node express.js server and anyone can put their username /email and password and all that data goes into an json file and it looks like this
{"username":"admin","password":"pasword","email":"user#stackoverflow.com","timestamp":1598668572045,"_id":"dx8HqKkVWe8olH5z"}
i managed to get the timestamp and NeDB gives a random _id to that object.
and when you login you go to a home page that looks like this
but the user gets the username value when there is on object only on the database which is "database.json"
if there is more than 1 object on the database that action will crash and the client can't see his name or any thing it shows nothing .
i don't know how to make it work with several objects on the database.
i thought JSON.parse Or stringfy could make it work but i don't know how to use them on my case.
so here is the js code
var jsonn = '/database.json';
async function userinfo() {
const response = await fetch(jsonn);
const data = await response.json();
var { username, password } = data;
document.getElementById('user').textContent = username;
console.log (data)
console.log (username);
console.log (id);
}
userinfo();
i appreciate any help, if you got any idea please share it with me i really need your help.
UPDATE :
the error message says :
uncaught (in promise) syntaxError : unxpected token in json positon 126.
my server.js code :
const Datastore = require('nedb');
app.listen(2000, () => console.log('listening at 3000'));
app.use(express.static('/public'));
app.use(express.json({
limit: '1mb'
}));
const database = new Datastore('public/database.json');
database.loadDatabase();
app.post('/public', (request, response) => {
const data = request.body;
const timestamp = Date.now();
data.timestamp = timestamp;
database.insert(data);
response.json(data);
console.log(data);
var logdate = new Date;
console.log(logdate);
});

There were some issues with the way that you are calling the DB insert. Basically, on every post request, you allow an insert. This is causing you to have multiple users with the same username. When you search for users by username then you will get a bunch of users. Instead, you want something like the sample code below.
I removed the status public to make it easier to test so make sure to add it back in so you can test front end code. Right now there's just a GET request endpoint so you can get the data by username through a query. This requires more cleanup and checks but at least it will get you started. Also, I remove the password and DB _id from the response as this is probs data you don't want to send back. Ideally, you will encrypt the password before storing it in DB.
const express = require('express');
const app = express();
const Datastore = require('nedb');
app.listen(3000, () => console.log('listening at 3000'));
app.use(express.json({
limit: '1mb'
}));
const database = new Datastore('public/database.json');
database.loadDatabase();
app.get('/public', (req, res) => {
const { username } = req.query;
database.findOne({
username,
}, (err, user) => {
if(err) {
return res.sendStatus(500);
}
delete user._id;
delete user.password;
return res.json(user);
});
});
app.post('/public', (req, res) => {
const data = req.body;
const {
username
} = data;
database.findOne({
username,
}, (err, user) => {
if(err) {
return res.sendStatus(500);
}
if(user) {
delete newUser._id;
delete newUser.password;
return res.json(user)
}
data.timestamp = Date.now();
database.insert(data, (createError, newUser) => {
if(createError) {
return res.sendStatus(500);
}
delete newUser._id;
delete newUser.password;
res.json(newUser);
});
});
});

Related

How to create a loop for SELECT function, to keep data updated?

I'm using an Oracle database, and every time it updates, the server doesn't understand this update and needs me to drop it for it to update the data.
const express = require('express');
const oracledb = require('oracledb');
const app = express();
var cors = require('cors')
app.use (cors())
app.engine('html', require('ejs').renderFile);
app.set('view engine', 'html');
// Connection details for the Oracle database
const connectionString = 'dbprod';
const user = 'sapiensproducao';
const password = 'fabrica';
// Connect to the database
oracledb.getConnection(
{
connectionString: connectionString,
user: user,
password: password
},
function(err, connection) {
if (err) {
console.error(err.message);
return;
}
console.log('Connection was successful!');
// Execute a SQL query
const query = 'SELECT CODEMP,CODORI,NUMORP,SEQEOQ,DATREA,HORREA,CODPRO,CODDER,QTDRE1,QTDRFG,CODLOT,OBSEOQ from USU_VPROEXT ORDER BY DATREA DESC, HORREA DESC';
connection.execute(query, [], (err, result) => {
if (err) {
console.error(err.message);
return;
}
console.log('Query was successful!');
console.log()
// Render the HTML template and pass the query results as a local variable
app.get('/teste', (req, res) => {
res.json(result.rows)
});
});
}
);
app.listen(3000, () => {
console.log('Server is listening on port 3000');
});
I thought of creating a loop for this SELECT function, but how can I create it?
How can I keep running this select in a loop, to keep the data always updated?
In the structure of your web server, you only ever query the database once and then create an endpoint to serve that data. Instead, create an endpoint which queries the data whenever it's invoked. Which may look more like this:
// define the endpoint
app.get('/teste', (req, res) => {
// within the endpoint, query the database
oracledb.getConnection(
{
connectionString: connectionString,
user: user,
password: password
},
function(err, connection) {
if (err) {
console.error(err.message);
// DON'T DO THIS, return an actual response to the user
return;
}
console.log('Connection was successful!');
const query = 'SELECT CODEMP,CODORI,NUMORP,SEQEOQ,DATREA,HORREA,CODPRO,CODDER,QTDRE1,QTDRFG,CODLOT,OBSEOQ from USU_VPROEXT ORDER BY DATREA DESC, HORREA DESC';
connection.execute(query, [], (err, result) => {
if (err) {
console.error(err.message);
// DON'T DO THIS, return an actual response to the user
return;
}
console.log('Query was successful!');
console.log();
// return the results to the user
res.json(result.rows);
});
});
});
The key difference here is that instead of wrapping the endpoint in the query, you wrap the query in the endpoint. So every time the endpoint is invoked it re-queries the database.
Please also note the comments for your error handling. If you just return; from the function and never return a response to the client, the client will just hang until it times out. Return an actual response, which can include error codes, messages, anything you like. Even just res.json(false); would be better than no response at all.

Unable to Pass Data to Backend from Input

I have an API which will send an email to a user based off the input. This is the on lick submit. I can confirm the data is being console.log for the state.
const inviteUser = async () => {
userRequest.get(`companyprofile/companyUser/invite/${companyuser._id}`, teamMemberEmail);
console.log('invite sent to', (teamMemberEmail))
}
With this api, i send the body to the API and then email based off the text, however when i log the field it does not appear at all and only shows as {}
router.get("/companyUser/invite/:id", async (req, res) => {
// must update to company
var stringLength = 25;
const companyUser = await CompanyProfile.findById(req.params.id)
const companyUserToken = await companyUser.inviteToken
const companyAccessTokenStripped = await companyUserToken.substring(0, stringLength);
//encrypt the accesstoken to invite users
const url = `http://localhost:5000/api/auth/inviteToJoinTeam/${companyUserToken}/${req.body.email}`;
// const url = `http://localhost:5000/api/companyprofile/companyUser/inviteToJoinTeam/${companyUserToken}`;
console.log(req.body)
const mailOptions = {
from: 'company#gmail.com',
to: req.body.email,
subject: `You have been invited to join ${companyUser.CompanyTitle}`,
html: `${companyUser.companyTitle} has invited you to join their team ${url}`
};
transporter.sendMail(mailOptions, function(error, info){
if (error) {
console.log(error);
} else {
console.log('Email sent: ' + info.response);
}
});
try {
// const savedCompany = await newCompany.save();
res.status(201).json(companyUserToken);
} catch (err) {
res.status(500).json(err);
}
});
Can anyone see why i cannot pass this data and email the user? Appears to be an error with how it's passed but i can confirm that the endpoint works in postman if i just plug an email body in
You are trying to send an email whenever the GET route is called. However, the data won't be sent inside as "req.body" as a GET request doesn't have a body.
If you are using GET method then the data is sent as query parameters.
router.get("/companyUser/invite/:email", async (req, res, next) => {
console.log(req.params.email);
};
You can also either use a POST or PUT request in order to access the URL body
router.post("/companyUser/invite", async (req, res, next) => {
console.log(req.body.email);
};

Req.session.users not available in other routes

i guys I am currently using nodejs with express session and connect session sequelize.
Currently I am trying to pass my userID from session and to be accessed at another add product page. So that the database can identify based on userID. I am getting req.session.users is not a function.
Below is my code.
Sessions login page:
const User = require('../models/user')
exports.postLoginPage = (req,res,next) =>{
User.findByPk(1)
.then(users =>{
req.session.isLoggedIn = true;
req.session.users = users;
res.redirect('/');
})
.catch(err =>{
console.log(err)
})
}
the addProduct Page
exports.postaddProductsMale = (req,res,next) =>{
const title = req.body.title;
const imageUrl = req.body.imageUrl;
const price = req.body.price;
console.log(+req.session.users)
req.session.users.createProduct({
title:title,
imageUrl:imageUrl,
price:price
})
.then(results =>{
console.log('Product created')
res.redirect('male_section');
})
.catch(err =>{
console.log(err)
})
};
this is my error :
TypeError: req.session.users.createProduct is not a function
at exports.postaddProductsMale (C:\Users\ASUS\Desktop\Hobby\projects\javascript\ecommerce clothing\maarancode\controllers\admin.js:28:23
I can get the data to the other routes using req.user not sure why req.session.users is not working.
Appreciate your feedback on this question. Thank you.
req.session must be serializable so that it can be stored between requests, see for example here. But a function like req.session.users.createProduct is not serializable, so it may not survive until the next request.
See the following example
express()
.use(session({
secret: "Se$$ion",
resave: false,
saveUninitialized: false
}))
.use("/test", function(req, res) {
if (!req.session.mybool) {
req.session.mybool = true;
req.session.myfunc = function() {};
}
res.end(typeof(req.session.mybool) + " " + typeof(req.session.myfunc));
})
.listen(80);
If you make two requests, the first response is boolean function but the second is boolean undefined.

Using a variable as a query in axios

I'm attempting to use a variable userEmail (which is assigned the user's email who is currently logged into my app) as a query for my api as I only want to search and return documents from my mongodb that relate to that specific email. I'm struggling to figure out how to pass this variable from my reactjs app to my api and utilising it, I don't even know if it is possible so any help would be great.
I'm using axios to make my GET request.
api.js contains my api helper functions
export async function surveyApiGet () {
let response = await axios.get('http://localhost:6000/'); // dateApi.js
return response.data;
}
dateApi.js is the api surveyApiGet() calls and at the moment my query is just regex that matches any emails, rahter than filtering to just the current user.
let MongoClient = require('mongodb').MongoClient;
var url = "mongodb://127.0.0.1:27017/";
const express = require('express');
const app = express();
app.use(express.json());
app.get('/', function (req, res) {
MongoClient.connect(url, function(err, db) {
if (err) throw err;
var dbo = db.db("manderleydb");
var query = { userId : /^(.)/ };
dbo.collection("manderleySurveyCompleted").find(query).sort({ date: 1}).limit(1)
.toArray(function(err, result) {
if (err) throw err;
console.log(result);
db.close();
res.status(200).json(JSON.stringify(result));
});
});
});
app.listen(6000, () => {
console.log('listening on port 6000');
});
Landing.js is where I make the call to my api helper function
surveyApiGet()
.then(response => {
// code
})
.catch(err => {
err.message;
});
For this, you can do a POST request to your Nodejs API and you can include the user's email with that request. To do so what you have to do is something like the following.
const usersEmail = "example#email.com"
Then through Axios, you can post this code to Nodejs API as follows.
const data = await axios.post("http://localhost:6000/", {
usersEmail : usersEmail
});
After you send this to Nodejs you can hold the value of the user's email through the request's body as follows. Change your endpoint to post instead of get.
app.post("/", function (req, res) {
const userEmail = req.body.userEmail;
//Put your MongoDB query and the status code here.
})
Drop a comment if you have any unclear points.

express.js retrieve username from mysql database doesn't redirect to signin page

I'm trying to retrieve username from mysql database, the below code can successfully retrieve the username. However, when err occurs, code doesn't redirect to /signin. The page redirect to /admin instead. Though, if I add
res.redirect('/signin')
just before the last curly bracket, it will redirect to the signin page, but it won't able to retrieve the username.
I want it to redirect to signin page, how?
const connection = require('./connection')
const signin = (req, res) => {
var email = req.body.email
var password = req.body.password
let queryStr = `select username from users where email='${email}' and password='${password}'`
return connection.query(queryStr, (err, rows, fields) => {
if (err) {
res.redirect('/signin')
} else {
req.session.email = email
res.json(rows[0])
}
})
}
module.exports = signin
I think it has to do with async because the code execute the last line then go back to the else statement. I think that's why it goes to /admin page instead. but not fixed yet.
connection.js
const mysql=require('mysql')
var connection=mysql.createConnection({
host:'localhost',
user:'root',
password:'root',
database:'essencejoin',
})
connection.connect()
connection.query('SELECT 1 + 1 AS solution', function (err, rows, fields) {
if (err) throw err
console.log('The solution is: ', rows[0].solution)
})
module.exports=connection
Actually, You're Query is correct, But query doesn't return any rows. So if user not found on username table. It needs to signin page(This is your question correct?), For that you have to update the code like following,
const connection = require('./connection')
const signin = (req, res) => {
var email = req.body.email;
var password = req.body.password;
let queryStr = `select username from users where email='${email}' and password='${password}'`;
return connection.query(queryStr, (err, rows, fields) => {
if (err) {
res.redirect('/signin');
} else if(!rows.length) {
res.redirect('/signin');
}else {
req.session.email = email;
res.json(rows[0]);
}
})
}
module.exports = signin
It looks your code is being executed after you have returned it. You can use promisified version of the same code.
use mysql-promise. this is promisified wrapper around the same library you are using. then Your code will look something like this:
// install mysql-promise
npm i mysql-promise
connection.js
const mysql = require("mysql-promise");
async function getDBConn() {
const connection = mysql.createConnection({
host: "localhost",
user: "root",
password: "root",
database: "essencejoin"
});
await connection.connect();
return connection;
}
module.exports = getDBConn;
then use it like this:
//signin.js
const signin = (req, res) => {
const email = req.body.email;
const password = req.body.password;
const connection = getDBConn();
let queryStr = `select username from users where email='${email}' and password='${password}'`;
try {
await connection.query(queryStr);
req.session.email = email;
res.json(rows[0]);
} catch (error) {
console.log(error);
res.redirect("/signin");
}
};
module.exports = signin;
disclaimer: I have not tested this, even if this does not work this should give you a fair idea how to make it work
Without knowing too much about your project, I think you want to look into adding a status code with the express redirect.
index(req, res, next) {
topicQueries.getAllTopics((err, topics) => {
if (err) {
res.redirect(500, "static/index");
} else {
res.render("topics/index", { topics });
}
});
}
Something like that. Also, look out for other simple mistakes in your project, that may cause this, that deal with Express.
https://expressjs.com/en/api.html#res.redirect

Categories