This code don't give a response, where is trouble?
index.js:
const express = require('express')
const mongoose = require('mongoose')
const authRouter = require('./authRouter') //import of router.
const PORT = process.env.PORT || 3000
const app = express()
app.use(express.json()) //to get server to parse
app.use('/auth', authRouter)
const start = async () =>{
try{
await mongoose.connect('mongodb+srv://*****:*****#cluster0.lwems.mongodb.net/myFirstDatabase?retryWrites=true&w=majority')
app.listen(PORT, ()=> console.log('Server started on 3000'))
} catch(e){
console.log(e)
}
}
start()
authRouter.js
const Router = require('express')
const controller = require('./authController')
const router = new Router() //create an object
router.post('/registration', controller.registration)
router.post('/login', controller.login)
router.post('/users', controller.getUsers) //for different access
module.exports = router
authController.js
class authController{
async registration(req,res) {
try {
} catch (e) {
console.log(e)
}
}
async login(req, res) {
try {
} catch (e) {
console.log(e)
}
}
async getUsers(req, res) {
try {
res.json("HEY")
} catch (e) {
console.log(e)
}
}
}
module.exports = new authController()
when i do request from browser it returns:
Cannot GET /auth/users
I don't understand where is my mistake. all done in accordance with example.
Cannot GET /auth/users
Try changing request method from post to get in AuthRouter.js
router.post('/registration', controller.registration)
router.post('/login', controller.login)
router.get('/users', controller.getUsers)
The problem is you are not returning the res.json()
Please do -
async getUsers(req, res) {
try {
return res.json("HEY");
} catch (e) {
console.log(e)
return res.json({"result":"failed", "error": e});
}
}
and it would work ;)
Related
I need to make unit tests for some post requests but i dont understand how.I tried with mswjs but the test passes because i'm missing something and i dont know what.I tried to test the requests in an usual way but i wasnt able to put my conditions there and it was sending only 200 status code..
To start with,this is my folder structure:
+main folder
++nodeServer
+++public
+++routes
++public
++src
+++tests
This is my try for testing the post request to /subscribe endpoint,where i should send an email as a payload and get the response that the payload was received succesefully.
subscribeFetch.test.js:
import {setupServer} from 'msw/node'
import {rest} from 'msw'
const handlers = [
rest.post("/api/subscribe",(req,res,context)=>{
if (!req.body || !req.body.email) {
return res(context.status(400).json({ error: "Wrong payload" }));
}
if (req.body.email === 'forbidden#email.com') {
return res(context.status(422).json({ error: "Email is already in use" }));
}
return res(
context.status(200),
context.json({email:'gigi#gmail.com'})
)
})
]
const server = setupServer(...handlers)
beforeAll(()=>server.listen())
afterAll(()=>server.close())
afterEach(()=>server.resetHandlers())
test('should send post request to the server',async()=>{
server.use(
rest.post('/api/subscribe',(req,res,ctx)=>{
return res(
expect (ctx.status()).toBe(200)
)
}
)
)
})
//export {handlers,rest}
This is the subscribe post request function that i need to test:
import { validateEmail } from './email-validator.js'
export const sendSubscribe = (emailInput) => {
const isValidEmail = validateEmail(emailInput)
if (isValidEmail === true) {
sendData(emailInput)
}
}
export const sendHttpRequest = (method, url, data) => {
return fetch(url, {
method: method,
body: JSON.stringify(data),
headers: data
? {
'Content-Type': 'application/json'
}
: {}
}).then(response => {
if (response.status >= 400) {
return response.json().then(errResData => {
const error = new Error('Something went wrong!')
error.data = errResData
throw error
})
}
return response.json()
})
}
const sendData = (emailInput) => {
sendHttpRequest('POST', '/api/subscribe', {
email: emailInput
}).then(responseData => {
return responseData
}).catch(err => {
console.log(err, err.data)
window.alert(err.data.error)
})
}
Files from the server:
app.js:
const express = require('express');
const path = require('path');
const cookieParser = require('cookie-parser');
const logger = require('morgan');
const indexRouter = require('./routes/index');
const communityRouter = require('./routes/community');
const analyticsRouter = require('./routes/analytics');
const app = express();
global.appRoot = path.resolve(__dirname);
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', indexRouter);
app.use('/community', communityRouter);
app.use('/analytics', analyticsRouter);
module.exports = app;
index.js from routes folder in the server folder:
const express = require('express');
const router = express.Router();
const FileStorage = require('../services/FileStorage');
/* POST /subscribe */
router.post('/subscribe', async function (req, res) {
try {
if (!req.body || !req.body.email) {
return res.status(400).json({ error: "Wrong payload" });
}
if (req.body.email === 'forbidden#email.com') {
return res.status(422).json({ error: "Email is already in use" });
}
const data = {email: req.body.email};
await FileStorage.writeFile('user.json', data);
await res.json({success: true})
} catch (e) {
console.log(e);
res.status(500).send('Internal error');
}
});
/* GET /unsubscribe */
router.post('/unsubscribe', async function (req, res) {
try {
await FileStorage.deleteFile('user.json');
await FileStorage.writeFile('user-analytics.json', []);
await FileStorage.writeFile('performance-analytics.json', []);
await res.json({success: true})
} catch (e) {
console.log(e);
res.status(500).send('Internal error');
}
});
module.exports = router;
Please guys,help me write unit test for subscribe endpoint to match the conditions from index.js file from routes folder in the server folder,thank you in advance!
So,i got the expected result without any library,but i dont know if its a good aproach,but at least it works :
const app = require('../../../personal-website-server/app')
const request = require('supertest')
describe('POST /subscribe', () => {
it('should give 400 status code when email is empty', async () => {
const email = { email: '' }
const response = await request(app).post('/subscribe').send(email)
if (!request.body || !request.body.email) {
expect(response.status).toBe(400)
}
})
it('should give 422 status code when email is forbidden', async () => {
const email = { email: 'forbidden#gmail.com' }
const response = await request(app).post('/subscribe').send(email)
if (request.body === 'forbidden#gmail.com') {
expect(response.status).toBe(422)
}
})
it('should give 200 status code when email is valid', async () => {
const email = { email: 'gigi#gmail.com' }
const response = await request(app).post('/subscribe').send(email)
expect(response.error).toBe(false)
expect(response.status).toBe(200)
expect(response.body.body).not.toBeNull()
})
})
I was trying to display a string on the client-side by fetching the result from serverside but for some reason, it is not displaying the fetched data. When I console log the variable straight on the js file the server successfully prints the string. The program is not exporting the variable to the client-side to display it. I can't figure out where I went wrong. Any help is appreciated. Thanks in advance.
const router = require("express").Router();
const {
callName
} = require("pathJs");
router.route("PathRoute").get(async(req, res) => {
const Result = await callName();
return res.json(Result);
});
module.exports = router;
function name() {
const liner = "this works"
console.log(liner)
//updated
return liner;
}
async function callName() {
const data1 = await name()
return data1;
}
callName()
<p id="insertHere" style="color: white;"></p>
<script>
async function caller() {
await fetch(`http://localhost:5000/api/PATH`)
.then((res) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(res.json())
}, 1000)
})
}).then((response) => {
console.log(response)
document.getElementById("insertHere").innerHTML = response.liner
}
)
}
</script>
const express = require("express");
const cors = require("cors");
const routePath = require("./routePath");
const {
response
} = require("express");
require("dotenv").config({
debug: process.env.DEBUG
});
const port = process.env.PORT || 5000;
const app = express();
app.use(cors());
app.use(express.json());
app.use("/api", routePath);
app.listen(port, () => {
console.log(`server is running on port: http://localhost:${port}`);
});
There is no export in pathJs and you want name() to return an object containing liner. You need
function name() {
const liner = "this works"
console.log(liner)
//updated
return {liner};
}
async function callName() {
const data1 = await name()
return data1;
}
callName()
module.exports = { callName };
The backend is probably crashing with TypeError: callName is not a function while handling the request and therefore doesn't send a response.
UPDATE: I it checks for /:slug even if i go to a different route, i think thats causing the problem.
I'm trying to create a URL Shortener with Nodejs, Expressjs, MongoDB and EJS.
Even though my application is working perfectly, I keep getting this error in terminal:
My routes :
const express = require("express");
const URLs = require("../models/urls");
const { findById, find } = require("../models/urls");
const router = express.Router();
router.get("/", (req, res) => {
res.render("index", { shortUrl: new URLs() });
});
router.post("/redirect", (req, res) => {
let url = req.body.url;
let slug = req.body.slug;
let shortenUrl = new URLs({
url: url,
slug: slug,
});
shortenUrl.save();
res.render("shortenUrl", { shortenUrl });
});
router.get("/about", (req, res) => {
res.render("about");
});
router.get("/contact", (req, res) => {
res.render("contact");
});
router.get("/all", async (req, res) => {
try {
var shortUrls = await URLs.find({});
res.render("all", { shortUrls });
} catch (error) {
console.log(error);
}
});
//:TODO
router.get("/:slug", async (req, res) => {
var shortUrl = await URLs.findOne({ slug: req.params.slug }).exec();
try {
console.log(shortUrl);
var urls = await shortUrl.url;
if (urls.includes("http", 0)) {
return res.redirect(urls);
} else {
return res.redirect(`http://${urls}`);
}
} catch (error) {
console.log(error);
}
});
module.exports = router;
I didn't get this error until I made API for the app (in separate routes file).
Also in my server I'm using:
app.use(bodyParser.urlencoded({ extended: false }));
and using:
app.use(express.json());
doesn't help either.
Any help would be appreciated, Thank you c:
I added an if statement to the route and that solved the problem, thanks to #Pukka c:
router.get("/:slug", async (req, res) => {
var shortUrl = await URLs.findOne({ slug: req.params.slug }).exec();
if (shortUrl) {
try {
console.log(shortUrl);
var urls = await shortUrl.url;
if (urls.includes("http", 0)) {
return res.redirect(urls);
} else {
return res.redirect(`http://${urls}`);
}
} catch (error) {
console.log(error);
}
}
This is my code with written with express js
this query works but I think that using async is more reliable than this
const MongoClient = require('mongodb').MongoClient;
const assert = require('assert');
const url = "mongodb://localhost:27017/nodejs_crud";
const db_n = "nodejs_crud"
const client = new MongoClient(url, { useUnifiedTopology: true });
app.get("/", async (req, res) => {
// this is myquery code with right result
client.connect((err) => {
assert.equal(null, err);
const db = client.db(db_n)
db.collection("list").find({}).toArray((err, result) => {
if(err) throw res.send({ status: "Error when react data", bool: false}).status(450);
res.send(result).status(200);
})
})
});
Try this, not exactly the same as yours, but will give you the idea on how to use async/await with try/catch
const MongoClient = require('mongodb').MongoClient;
const url = "mongodb://localhost:27017/nodejs_crud";
const db_n = "nodejs_crud"
const client = new MongoClient(url, { useUnifiedTopology: true });
app.get('/', async (req, res) => {
// Connect client if it's not connected
if(!client.isConnected()) {
await client.connect();
// you can also catch connection error
try {
await client.connect();
catch(err) {
return res.status(500).send();
}
}
const db = client.db(db_n);
try {
// Run queries
const result = db.collection("list").find({});
res.json(await result.toArray());
} catch (err) {
// Catch any error
console.log(err.message);
res.status(450).send();
}
});
I have not tested this, but try something along the lines of:
const MongoClient = require('mongodb').MongoClient;
const assert = require('assert');
const url = "mongodb://localhost:27017/nodejs_crud";
const db_n = "nodejs_crud"
let client;
const getDb = async () => {
// If we don't have a client, create one.
if (!client) client = new MongoClient(url, { useUnifiedTopology: true });
// If we are not connected, then connect.
if (!client.connected()) await client.connect();
// Get our database
return client.db(db_n);
}
app.get("/", async (req, res) => {
try {
const db = await getDb();
const results = await db.collection("list").find({}).toArray();
res.send(result).status(200);
} catch (err) {
res.send({ status: "Error when react data", bool: false}).status(450);
}
});
My /chat route works well through Post method with validation with Joi schema but when I send request through Get method, it show Sending Request and continue loading...
My index.js file:
const express = require('express');
const cors = require('cors');
const bodyParser = require('body-parser');
const morgan = require('morgan');
const chat = require('./db/ChatModel');
const app = express();
app.use(bodyParser.json());
app.get('/chat', (req, res) => {
chat.getAllMessages().then( (messages) => {
res.json(messages);
});
});
app.post('/chat', (req, res) => {
console.log(req.dody);
chat.createMessages(req.body).then((message) => {
res.json(message);
}).catch( (error) => {
res.status(500);
res.json(error);
});
});
const port = process.env.PORT || 8888;
app.listen(port, () => {
console.log(`Listening on port ${port}...`);
});
In connection.js I coded this
const monk = require('monk');
const connectionString = 'localhost/chatboard';
const db = monk(connectionString);
module.exports = db;
And ChatModal.js has the following code
const Joi = require('joi');
const db = require('./connection');
const schema = Joi.object().keys({
username: Joi.string().alphanum().min(4).max(16).required(),
subject: Joi.string().required(),
message:Joi.string().max(300).required(),
imgUrl: Joi.string().uri({
scheme: [ // https://github.com/hapijs/joi/blob/v14.3.1/API.md#stringurioptions
/https?/
]
})
});
const chat = db.get('chat');
function getAllMessages() {
return chat.find();
};
function createMessages(message) {
const result = Joi.validate(message, schema);
if (result.error == null) {
message.created = new Date();
return chat.insert(message);
} else {
return Promise.reject(result.error);
}
}
module.exports = {
createMessages,
getAllMessages
};
I can't understand why getAllMessages() doesn't work and postman continue loading when Get request applied like this http://prntscr.com/s0d9c5
ChatModal.js
function getAllMessages() {
try {
return chat.find();
} catch (err) {
return next(err);
}
index.js
app.get('/chat', (req, res, next) => {
try{
data = chat.getAllMessages()
} catch (err) {
return next(error);
}
res.json(data);
});
User try-catch in the ChatModal.js and also index.js then you can understand what is actual error, like bellow:
ChatModal.js
function getAllMessages() {
try {
chat.find();
} catch (err) {
return next(err);
}
I think, may be your data, i mean message list data so weight, in this case you get all message,res.json(messages); json method have long time to parse messages data