I'm trying to get result from node.js api however, whenever i deploy my website, it gets html result like below.
but it works when it's on local. but not on the deployed website.
so i tried to use axios post then it gets 404 error.
and another api is work but when i write new api then it gets error.
this is my node.js
//this post work just fine .
app.post("/insertCodeVisual", async (req, res) => {
const { data } = await req.body;
const visualData = new CodeVisualData({
data: data,
});
try {
visualData.save((err, info) => {
res.send(info._id);
});
console.log("success");
} catch (error) {
console.log(error);
}
});
//but this post is not working
app.post("/api/database", async (req, res) => {
const { host, user, password, port, table, database } = await req.body;
var connection = mysql.createConnection({
host: host,
user: user,
password: password,
port: port,
database: database,
});
try {
connection.connect();
} catch (error) {
res.send([["ERROR_CODE"], [error.code]]);
}
const sql = `SELECT * FROM ${table}`;
connection.query(sql, function (err, results) {
if (err) {
return res.send([
["ERROR"],
[`code : ${err.code}`],
[`errno : ${err.errno}`],
[`sqlMessage : ${err.sqlMessage}`],
]);
} else {
const parse = papa.unparse(results, {
quotes: false, //or array of booleans
quoteChar: '"',
escapeChar: '"',
delimiter: ",",
header: true,
newline: "\r\n",
skipEmptyLines: false, //other option is 'greedy', meaning skip delimiters, quotes, and whitespace.
columns: null, //or array of strings
});
const unparse = papa.parse(parse);
res.send(unparse.data);
}
});
});
const __dirname = path.resolve();
app.use(express.static(path.join(__dirname, "dist")));
app.get("/*", (req, res) => {
res.sendFile(path.join(__dirname, "dist", "index.html"));
});
React.js
this one is working absolutely
const insertData = async () => {
try {
if (confirm("are u sure? ")) {
axios
.post(`${backend}/insertCodeVisual`, {
data: {
client: client,
header: header,
},
})
.then(res => {
setJustSavedDataId(res.data);
});
} else {
return;
}
} catch (error) {
console.log(error);
}
};
this below is not working when i deployed .
const getDatabase = async () => {
const url = `${backend}/api/database`;
const api = await axios.post(url, db[id]);
const data = api.data;
try {
setInfo({ ...info, [id]: data });
} catch (error) {
console.log(error);
}
};
So i wonder what cases make this kind of issue.
Related
I am getting (this.parent.acquire is not a function) error in the following code
app.post("/add", (req,res) => {
const config = {
server: 'server', //update me
user: 'user', //update me
password: 'pass', //update me
database: 'db',
trustServerCertificate: true
}
let pool2 = sql.connect(config)
try {
const transaction = new sql.Transaction(pool2)
transaction.begin(err => {
if(err) {
console.log(err);
}
const request = new sql.Request(transaction)
request.query('insert into fsraSample (A93) values (12345)', (err, result) => {
if(err) {
console.log(err);
}
transaction.commit(err => {
if(err) {
console.log(err);
}
console.log("Transaction committed.")
})
})
})
} catch(err) {
console.log();
}
res.sendFile(path.join(__dirname + '/index.html'));
});
Whats the issue here? I am using the above code to insert some data in sql server using node js
Today I am facing a silly problem after deploying to Heroku. I have a React front-end. And express back-end. It is a social media app. So in this app, I have a profile page for users. In this page I am using a back-end route to fetch the data of the user. So everything remains good. But once I refresh the page, it starts showing the JSON object coming from the back-end
Before refresh.
after refresh
I am getting this problem after deployment only. I am sharing all of my code which I have written to deploy it to heroku
Server - package.json
{
"name": "server",
"version": "1.0.0",
"description": "Back-end of the dev-media front-end",
"main": "app.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node app.js",
"heroku-postbuild": "NPM_CONFIG_PRODUCTION=false npm install --prefix client && npm run build --prefix client"
},
"keywords": [
"devr",
"dev-media"
],
"author": "Ratul-oss",
"license": "ISC",
"dependencies": {
"bcrypt": "^5.0.1",
"cookie-parser": "^1.4.5",
"cors": "^2.8.5",
"dotenv": "^8.2.0",
"express": "^4.17.1",
"jsonwebtoken": "^8.5.1",
"mongoose": "^5.11.15",
"validator": "^13.5.2"
}
}
server - App.js
require("dotenv").config();
const express = require("express");
const routes = require("./routes/routes");
const cors = require("cors");
const app = express();
const port = process.env.PORT || 8000;
app.use(routes);
app.use(cors());
if (process.env.NODE_ENV === "production") {
app.use(express.static("client/build"));
}
app.listen(port, () => console.log(`Listening to http://localhost:${port}`));
And you may also checkout the routes.js where all of my back-end routes/codes are written
const cookieParser = require("cookie-parser");
const express = require("express");
const UserData = require("../models/user");
const routes = express.Router();
require("../dbConnection");
const auth = require("../middlewares/auth");
const cors = require("cors");
const Posts = require("../models/posts");
const bcrypt = require("bcrypt");
const Comments = require("../models/comment");
routes.use(express.json());
routes.use(express.urlencoded({ extended: false }));
routes.use(cookieParser());
routes.use(cors());
// * all the get routes starts from here
routes.get("/auth", auth, (req, res) => {
res.status(200).send(req.user);
});
// for getting the data of a single user by the id
routes.get("/user/:id", async (req, res) => {
try {
const id = req.params.id;
const user = await UserData.findOne({ _id: id });
res.status(201).send(user);
} catch (err) {
res.status(404).json({ err: "User not found" });
}
});
// for getting the data of all users
routes.get("/users", async (req, res) => {
try {
const users = await UserData.find();
res.status(200).send(users);
} catch (err) {
res.status(400).json({ err: "Something is wrong" });
}
});
// for logging out the user
routes.get("/logout", auth, async (req, res) => {
try {
req.user.tokens = req.user.tokens.filter(
(token) => token.token !== req.token
);
res.clearCookie("jwt");
await req.user.save();
res.status(200).send("Succefuly logged out");
} catch (err) {
console.log(err, "from the routes line 23");
}
});
// for getting all the followers
routes.get("/followers/:id", async (req, res) => {
try {
const id = req.params.id;
const user = await UserData.findOne({ _id: id });
res.send(user);
} catch (err) {
console.log(err);
}
});
// for recieving all the posts
routes.get("/posts", async (req, res) => {
try {
const posts = await Posts.find();
res.send(posts);
} catch (err) {
console.log(err);
}
});
// to verify the user posts
routes.get("/post/:id", async (req, res) => {
try {
const id = req.params.id;
const posts = await Posts.find({ userId: id });
res.send(posts);
} catch (err) {
console.log(err);
}
});
// for getting the single post according to the post id
routes.get("/posts/:id", async (req, res) => {
try {
const id = req.params.id;
const post = await Posts.findOne({ _id: id });
res.status(200).send(post);
} catch (err) {
res.status(404).json({ err: "Post Not Found" });
}
});
// for getting the specific comments of a post
routes.get("/comments/:id", async (req, res) => {
try {
const id = req.params.id;
const comments = await Comments.find({ postId: id });
res.send(comments);
} catch (err) {
console.log(err);
}
});
// * all the delete routes starts from here
// for deleting the use account
routes.delete("/deleteAccount/:id", async (req, res) => {
try {
const id = req.params.id;
await UserData.findByIdAndRemove(id).exec();
res.clearCookie("jwt");
res.send("Account Deleted");
} catch (err) {
console.log(err);
}
});
// for deleting the post
routes.delete("/deletepost", async (req, res) => {
try {
const id = req.body.id;
await Posts.findByIdAndRemove(id).exec();
res.send("Post deleted");
} catch (err) {
console.log(err);
}
});
// for deleting a comment
routes.delete("/deleteComment/:id", async (req, res) => {
try {
const id = req.params.id;
await Comments.findByIdAndRemove(id).exec();
res.status(200).send("Deleted");
} catch (err) {
console.log(err);
}
});
// * all the post routes starts from here
// for registering the user
routes.post("/register", async (req, res) => {
try {
const {
name,
email,
bio,
password,
conPass,
country,
gender,
profession,
} = req.body;
if (
(!name, !email, !password, !conPass, !country, !gender, !profession, !bio)
) {
res.status(422).json({ err: "Please fill all the fields properly" });
}
const user = new UserData({
name,
email,
bio,
password,
conPass,
country,
gender,
profession,
});
const emailExists = await UserData.findOne({ email: email });
if (emailExists) {
res.status(401).json({ err: "Email already exists" });
}
if (password !== conPass) {
res.status(403).json({ err: "Password doesn't matched" });
} else if (password === conPass && !emailExists) {
const token = await user.generateToken();
res.cookie("jwt", token);
await user.save();
}
res.status(200).json({ success: "Your account has been registered" });
} catch (err) {
res.status(400).send("Something went wrong");
}
});
// the login route
routes.post("/loginuser", async (req, res) => {
try {
const { email, password } = req.body;
const user = await UserData.findOne({ email: email });
const isMatched = await bcrypt.compare(password, user.password);
if (isMatched) {
const token = await user.generateToken();
res.cookie("jwt", token);
res.status(200).json({ success: "Loggin Successful" });
} else if (!isMatched) {
res.status(403).json({ err: "Your login details are invalid" });
}
} catch (err) {
res.status(400).json({ err: "Invalid Credentials" });
}
});
// for posting any post
routes.post("/postsomething", async (req, res) => {
try {
const name = req.body.name;
const text = req.body.text;
const userId = req.body.userId;
const time = req.body.time;
const date = req.body.date;
if (!text) {
res.status(400).json({ err: "Please type something!" });
}
const post = new Posts({
name: name,
date: date,
time: time,
body: text,
userId: userId,
like: 0,
});
await post.save();
res.status(200).json({ success: "Your Post has been created" });
} catch (err) {
res.status(500).send(err);
}
});
// for posting a comment
routes.post("/postComment", async (req, res) => {
try {
const postId = req.body.postId;
const user = req.body.user;
const commentText = req.body.comment;
const userName = req.body.userName;
const comment = new Comments({
userName,
commentText,
user,
postId,
time: new Date().toLocaleTimeString(),
date: new Date().toLocaleDateString(),
});
await comment.save();
res.status(200).send("Comment Posted");
} catch (err) {
console.log(err);
}
});
// * all the put request starts from here
// for updating the user
routes.put("/updateUser", async (req, res) => {
try {
const { name, email, bio, profession, userId } = req.body;
await UserData.findById(userId, (err, updatedUser) => {
if (name) {
updatedUser.name = name;
}
if (email) {
updatedUser.email = email;
}
if (bio) {
updatedUser.bio = bio;
}
if (profession) {
updatedUser.profession = profession;
}
updatedUser.save();
res.status(200).send("Informations has been updated");
});
} catch (err) {
res
.status(400)
.send(
"Please fill all the fields. If you don't want to update on of them, please type the previous one"
);
}
});
// for following any user
routes.put("/followUser", async (req, res) => {
try {
const followerUser = req.body.authenticateduser; // follower
const followingUser = req.body.user; // this guy will get the follow
await UserData.findById(followingUser._id, (err, user) => {
// when any user will click on the follow button in the front-end, his / her data will be
// stored in the followers field as an object
user.followers = user.followers.concat({ follower: followerUser });
user.save();
res.send("Followed");
});
} catch (err) {
console.log(err);
}
});
// to unfollow an user
routes.put("/unfollowUser", async (req, res) => {
try {
const followerUser = req.body.authenticateduser; // unfollower
const followingUser = req.body.user; // this guy will get the unfollow
await UserData.findById(followingUser._id, (err, user) => {
user.followers = user.followers.filter((follower) => {
return follower.follower._id !== followerUser._id;
});
user.save();
res.send("Unfollowed");
});
} catch (err) {
console.log(err);
}
});
// for liking a post
routes.put("/likePost", async (req, res) => {
try {
const postId = req.body.postId;
const liker = req.body.user;
await Posts.findById(postId, (err, post) => {
post.like = post.like + 1;
post.likers = post.likers.concat({ liker: liker });
post.save();
res.send("Liked");
});
} catch (err) {
console.log(err);
}
});
// for unliking a post
routes.put("/unlikePost", async (req, res) => {
try {
const postId = req.body.postId;
const liker = req.body.user;
await Posts.findById(postId, (err, post) => {
post.like = post.like - 1;
post.likers = post.likers.filter(
(likerUser) => likerUser.liker._id !== liker._id
);
post.save();
res.send("unliked");
});
} catch (err) {
console.log(err);
}
});
module.exports = routes;
You may check out the app I have deployed and figure out the problem https://devr-dev-media.herokuapp.com/. At First open an account then go to your profile page, then try to reload. Your will face the problem.
If you need more information, let me know. Please help me fix that problem with deployment. Thanks for the time :) Have a great day.
The route serving your page in React and the route on your backend are the same that is one of the possible cause. To solve the issues change the name of one maybe add "s" if you wish to maintain the same name. example
instead of
node server.js
`router.get('/name',(req,res)=>{}`
React App.js
<Router>
<Routes>
<Route path="/name" element={<Home/>}/>
</Routes>
</Router>
Try adding "s"
node server.js
`router.get('/names',(req,res)=>{}`
React App.js
<Router>
<Routes>
<Route path="/name" element={<Home/>}/>
</Routes>
</Router>
const express = require('express')
const usersJs = require('./endpoints/users')
var cors = require('cors')
const app = express()
app.use(cors())
app.use(express.json());
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
next();
});
app.post('/addUser', (req, res) => {
result = usersJs.doAddUser().then(result => console.log(result))
res.json(result)
})
This is my server which is doing the call of doAdduser() from another file as you see bellow...
let stuff_i_want
module.exports.doAddUser = () => {
return addUser(async function (result) {
stuff_i_want = result;
return stuff_i_want
});
}
addUser = async (callback) => {
const mysql = require('mysql')
const connection = mysql.createConnection({
host: "localhost",
port: "",
user: "",
password: "",
database: ""
})
connection.connect(async function (err) {
if (err) throw err;
connection.query("SELECT * FROM USERS", async function (err, result) {
if (err) throw err;
stuff_i_want = result
});
});
return callback(result)
}
but the problem that result is always undefined in when im trying to res.json() it to the client, or when im trying console.log(result), its happening before addUser() which will make it undefined, tried with delay, with async await, but still result undefined in client and server but in doAdduser i can see the result from the database
I wanna be honest with you, this code looks super messi. However i have an solution for you.
You try to get the result outside the promise chain, that dont work. I would use the modern way async / await
const express = require('express')
const { addUser } = require('./endpoints/users')
var cors = require('cors')
const app = express()
app.use(cors())
app.use(express.json());
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
next();
});
app.post('/addUser', async (req, res) => {
try {
let result = await addUser();
return res.status(200).json(result);
} catch (err) {
console.log(err);
return res.status(500).json({ message: "Something went wrong" })
}
})
Also wrap it with an try / catch
Next to your mysql connection:
const mysql = rquire("mysql");
module.exports.addUser = () => {
return new Promise((resolve, reject) => {
const connection = mysql.createConnection({
host: "localhost",
port: "",
user: "",
password: "",
database: ""
});
connection.connect(err => {
if (err) reject(err);
connection.query("SELECT * FROM USERS", (err, result) => {
if (err) return reject(err);
return resolve(result);
});
});
});
};
import it on the top not somehwere in the middle of the code this is just confusing.
export a named module called addUser witch is an function.
That function returns an promise.
Then reject on errors and resolve if you got an result from your DB.
The try / catch block will catch the error.
Also add an status code to your response. I am not sure here i might be wrong but no status code means your request was successful even if something went wrong on the serverside
Its also good to have an router folder where you add all your routes and import the route handlers in there that looks something like this then:
const { addUserHandler } = require("./user");
router.post("/addUser", addUserHandler)
So routes and the logic are seperated and it doesnt look messi
I saw a similar question posted Here, but they are using MEAN-Stack.
I am currently just using a 'setTimeout' function to wait a few seconds before requesting new data from the server using a fetch api to give it time to update but this doesnt feel like the right way to do it. Is there a simple way for the front-end to update only after the database is updated in Express? I am new to Node please forgive me.
app.js:
const express = require('express');
const app = express();
const mysql = require('mysql');
let viewData = {
//html data
}
var pool = mysql.createPool({
connectionLimit : 10,
host: "localhost",
port: 3306,
database: 'testing',
user: "root",
password: "pass"
});
function sql(type) {
if(type == 'select') {
//Select query here
}
if(request == 'addRow') {
//Insert query here
}
}
app.get(`/`, function (req, res) {
res.sendFile('./views/index.html', {root: __dirname});
})
app.post('/api/add', function(req, res){
res.setHeader('Content-Type', 'application/json');
sql('addRow')
});
app.get('/api/viewData', function (req, res) {
res.setHeader('Content-Type', 'application/json');
res.send(JSON.stringify(viewData));
})
index.js:
function loadData() {
fetch('/api/viewData')
.then(z => z.json())
.then(a => {
//update html
})
}
function postData(a) {
fetch('/api/add', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
//data to send to app.js
})
}).then(setTimeout(function(){loadData();}, 3000))
}
You should use async and await function
Example: After async/await
async function fun1(req, res){
let response = await request.get('http://localhost:3000');
if (response.err) { console.log('error');}
else { console.log('fetched response');
}
The complete code of our example is shown below:
npm install express jsonschema body-parser promise-mysql
var express = require('express');
var bodyParser = require('body-parser')
var app = express();
var validate = require('./validate')
var mysqlConnection = require('./connectionShare');
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
const addItem = function(item, connection){
console.log("Adding Item");
return new Promise(function(resolve, reject){
connection.query("INSERT INTO product SET ?", item)
.then(function(result){
resolve(item.seller);
}).catch(function(error){
reject(error);
});
})
}
const findOrCreateUser = function(user,connection){
console.log("Finding User");
return new Promise(function(resolve,reject){
connection.query("SELECT * FROM user WHERE email=" + connection.escape(user.email))
.then(function(results){
if(results.length == 1){
resolve(results[0].id)
} else {
connection.query("INSERT INTO user SET ?", user)
.then(function(results){
resolve(results.insertId);
});
}
}).catch(function(error){
reject(error);
})
})
}
const selectUserItems = function(userID,connection){
console.log("Selecting Items " + userID);
return new Promise(function(resolve,reject){
connection.query("SELECT * FROM product WHERE seller = " + connection.escape(userID))
.then(function(results){
resolve(results);
}).catch(function(error){
reject(error);return;
});
})
}
app.post('/add/product', validate.JsonValidation, mysqlConnection.getConnection, async function(req,res){
var connection = req.connection;
var item = {
name: req.body.name,
price: req.body.price,
width: req.body.width,
height: req.body.height,
added: req.body.added,
image: req.body.image
};
var user = {
username: req.body.seller.username,
email: req.body.seller.email,
votes: req.body.seller.votes
};
try {
item.seller = await findOrCreateUser(user,connection);
var user_id = await addItem(item,connection);
var items = await selectUserItems(user_id, connection);
connection.connection.release();
res.status(200).json(result);
} catch(error) {
res.status(500).end(error);
}
});
process.on('uncaughtException', error => console.error('Uncaught exception: ', error));
process.on('unhandledRejection', error => {console.error('Unhandled rejection: ', error));
app.listen(8000, function () {
console.log('App listening on port 8000')
});
I'm having some issues with my expressJS application, posting to one route will always result in Cannot set headers after they are sent to the client - I don't understand why and where I'm sending a request/response twice.
I tried playing around with async and await in my functions to get rid of this error but ultimately it's always coming back. I'm also writing an ID to a database, I thought this would be the issue. But I don't think so, because I'm basically just returning a code and not even checking the dynamodb.put request in my current function.
async function putNewUrl(inputUrl) {
const newId = await getId();
const short = ShortURL.encode(newId);
const params = {
TableName: URL_TABLE,
Item: {
long: inputUrl,
short,
},
};
try {
const data = await dynamoDb.put(params).promise();
return short;
} catch (error) {
console.log(error);
}
return short;
}
app.post('/submit', async (req, res) => {
const inputUrl = req.body.url;
try {
const shortUrl = await putNewUrl(inputUrl);
console.log(shortUrl)
return res.json({ success: true, message: shortUrl });
} catch(error) {
console.log(error)
return
}
});
here are my imports:
import { config, DynamoDB } from 'aws-sdk';
import { json } from 'body-parser';
import express from 'express';
import helmet from 'helmet';
import { URL } from 'url';
const app = express();
app.use(helmet());
this is how I start my server
app.listen(3000, () => { console.log('app running'); });
solved it:
there was another route like this:
app.post('/submit', (req, res, next) => {
const inputUrl = req.body.url;
findExistingUrl(inputUrl, (error, data) => {
if (error) {
return res.json({ success: false, message: 'server error' });
}
if (typeof data.Items[0] === 'undefined' && data.Items[0] !== null) {
next();
} else {
return res.json({ success: true});
}
});
});
where I was calling next() right at the end again.
solved it:
there was another route like this:
app.post('/submit', (req, res, next) => {
const inputUrl = req.body.url;
findExistingUrl(inputUrl, (error, data) => {
if (error) {
return res.json({ success: false, message: 'server error' });
}
if (typeof data.Items[0] === 'undefined' && data.Items[0] !== null) {
next();
} else {
return res.json({ success: true});
}
});
});
where I was calling next() right at the end again.