Why does Postman show "error 404" when I try to save data into my Mongo database? - model-view-controller

I have three files in my MVC architecture for my app.
Models folder:
I have exported the Mongoose schema and model like so:
const User = mongoose.model("User", UserSchema);
module.exports = User;
2. Controllers Folder
I have the following code in my controllers file:
const addUser = require('./../models/clientmodel');
exports.addUser = async (req, res) => {
try {
const newUser = await new addUser.create(req.body);
res.status(201).json({
status: "success",
data: {
newUser
}
});
} catch (err) {
res.status(204).json({
status: 'fail',
message: err
})
}
}
3. Routes folder
const router = express.Router();
router
.route('/')
.get (userControl.add_user)
app.post(userControl.newTour);
module.exports = router;
Why do I get the 404 error message in Postman?
How do I inser a loop?
NB: I am new to programming and learning the MERN stack.
The following code works fine in one folder:
const express = require("express");
const userModel = require("./models");
const app = express();
app.post("/add_user", async (request, response) => {
const user = new userModel(request.body);
try {
await user.save();
response.send(user);
} catch (error) {
response.status(500).send(error);
}
});
app.get("/users", async (request, response) => {
const users = await userModel.find({});
try {
response.send(users);
} catch (error) {
response.status(500).send(error);
}
});
module.exports = app;
I would like to refactor the code in the MVC architecture. When I split the code into controller/route configuration, then things do not work.

Related

How to get error from backend with axios?

I'm trying to display an error I recieve in my backend to the user in my JSX frontend file.
This is the initial call from frontend
dispatch(createGoal({ values }))
Goalslice, directly called from JSX:
export const createGoal = createAsyncThunk(
'goals/create',
async (goalData, thunkAPI) => {
try {
const token = thunkAPI.getState().auth.user.token
return await goalService.createGoal(goalData, token)
} catch (error) {
const message =
(error.response &&
error.response.data &&
error.response.data.message) ||
error.message ||
error.toString()
return thunkAPI.rejectWithValue(message)
}
}
)
Goalservice, directly called from goalslice:
const createGoal = async (goalData, token) => {
const config = {
headers: {
Authorization: `Bearer ${token}`,
},
}
const response = await axios.post(API_URL, goalData, config)
return response.data
}
Goalcontroller, my backend:
const setGoal = asyncHandler(async (req, res) => {
const goals = await Goal.find({ user: req.user.id })
var count = Object.keys(goals).length
if(count >2){
res.status(400)
throw new Error('Maximum of 3 trackers per user')
}
if (!req.body.values) { //if this isnt there. check if the body is there.
res.status(400) //This is an error
throw new Error('Please add a date field') //this is express error handler
}
console.log(req.body.values.dates)
const goal = await Goal.create({
values: req.body.values.dates, //get from request body
permit: req.body.values.permits,
numpermit: req.body.values.num,
user: req.user.id,
})
res.status(200).json(goal)
})
I want to display this error:
throw new Error('Maximum of 3 trackers per user')
I tried a try/catch method, but I'm very new to this and I feel like i'm missing a very key point in how it all fits together.
This is my custom error handler if it helps:
const errorHandler = (err, req, res, next) => { //overwrite express error handler, next to handle any new req
const statusCode = res.statusCode ? res.statusCode : 500 //500 is server error. conditional
res.status(statusCode)
res.json({
message: err.message,
stack: process.env.NODE_ENV === 'production' ? null : err.stack, //gives additional info if in development mode : is else
})
}
module.exports = { //export for others to use
errorHandler,
}

`next.js` api is resolved before promise fullfill?

I want to achieve something like this:
call my website url https://mywebsite/api/something
then my next.js website api will call external api
get external api data
update external api data to mongodb database one by one
then return respose it's status.
Below code is working correctly correctly. data is updating on mongodb but when I request to my api url it respond me very quickly then it updates data in database.
But I want to first update data in database and then respond me
No matter how much time its take.
Below is my code
export default async function handler(req, res) {
async function updateServer(){
return new Promise(async function(resolve, reject){
const statusArray = [];
const apiUrl = `https://example.com/api`;
const response = await fetch(apiUrl, {headers: { "Content-Type": "application/json" }});
const newsResults = await response.json();
const articles = await newsResults["articles"];
for (let i = 0; i < articles.length; i++) {
const article = articles[i];
try {
insertionData["title"] = article["title"];
insertionData["description"] = article["description"];
MongoClient.connect(mongoUri, async function (error, db) {
if (error) throw error;
const articlesCollection = db.db("database").collection("collectionname");
const customQuery = { url: article["url"] };
const customUpdate = { $set: insertionData };
const customOptions = { upsert: true };
const status = await articlesCollection.updateOne(customQuery,customUpdate,customOptions);
statusArray.push(status);
db.close();
});
} catch (error) {console.log(error);}
}
if(statusArray){
console.log("success", statusArray.length);
resolve(statusArray);
} else {
console.log("error");
reject("reject because no statusArray");
}
});
}
updateServer().then(
function(statusArray){
return res.status(200).json({ "response": "success","statusArray":statusArray }).end();
}
).catch(
function(error){
return res.status(500).json({ "response": "error", }).end();
}
);
}
How to achieve that?
Any suggestions are always welcome!

401 - unauthorized call to Twitch Api from nextjs

I have this code:
const getToken = async () => {
return Axios.post(
`https://id.twitch.tv/oauth2/token?client_id=${process.env.TWITCH_ID}&client_secret=${process.env.TWITCH_SECRET}&grant_type=client_credentials`
).then((res) => res.data["access_token"]);
};
const getId = async (accessToken, session) => {
const response = await Axios.get(
`https://api.twitch.tv/helix/users?login=${session.user.name}`,
{
Authorization: `Bearer ${accessToken}`,
"Client-Id": process.env.TWITCH_ID,
}
);
return response.data.id;
};
export async function getServerSideProps(context) {
const session = await getSession(context);
if (session) {
const accessToken = await getToken();
console.log(accessToken);
const id = await getId(accessToken, session);
console.log(id);
}
return {
props: {}, // will be passed to the page component as props
};
}
This is Next.js function that will do this on every request.
I am using Next.js, next-auth for authentication.
Everything should work fine, even on line console.log(accessToken) I get the expected output. But in function getId it says 401 - unauthorized.
I am calling Twitch api.

AdonisJS Socket.IO JWT authentication

How can you define the auth provider? Now every time the auth variable is undefined in the playerLogin method.
I'm are using Adonis v4.1
The code:
start/socket.js
const Server = use('Server')
const io = use('socket.io')(Server.getInstance())
// Define controllers here
// Example: const WSController = use('App/Controllers/Http/ChatController')
const AuthenticateController = use('App/Controllers/Http/AuthenticateController');
io.on('connection', function (socket) {
// Define here the controller methods
// Example: WSController.goMessage(socket, io)
AuthenticateController.playerLogin(socket, io);
AuthenticateController.playerRegister(socket, io);
})
AuthenticateController.js
const Hash = use('Hash')
const User = use('App/Models/User')
class AuthenticateController {
static playerLogin(socket, io, {auth}) {
socket.on('playerLogin', async (data) => {
console.log('WORKS')
if (await auth.attempt(data.email, data.password)) {
let user = await User.findBy('email', data.email)
let accessToken = await auth.generate(user)
socket.emit('sendPlayerToken', { token: accessToken });
} else {
socket.emit('sendPlayerToken', { token: 'Credentials are incorrect' });
}
});
}
static playerRegister(socket, io) {
socket.on('playerRegister', async (data) => {
const safePassword = await Hash.make(data.password)
const user = new User()
user.username = data.username
user.email = data.email
user.password = safePassword
await user.save()
socket.emit('sendPlayerRegister', { success: true });
});
}
}
Kind regards,
Corné
As this discussion bellow:
https://github.com/adonisjs/core/discussions/2051?sort=new#discussioncomment-274111
You can use the API guard and authenticate using the code from the answer of M4gie.
You only need to install the crypto package with yarn add crypto and if you don't want to create the object to display the socket errors, just turn it into a string: throw new Error('SocketErrors:MissingParameter').

Cannot POST ajax request

can anyone explain to me why i cannot post the ajax request. When i run this code the console appear POST http://localhost:8080/api/users 404 (Not Found), and in the networth part the preview is 404 not found
In the index.js file
var path = require('path');
var express = require('express');
var webpack = require('webpack');
var config = require('./webpack.config.dev.js');
var app = express();
var compiler = webpack(config);
var bodyParser = require('body-parser');
var users = require('./server/routes/users');
app.use(bodyParser.json());
app.use('/api/users', users);
app.use(require('webpack-dev-middleware')(compiler, {
noInfo: true,
publicPath: config.output.publicPath
}));
app.use(require('webpack-hot-middleware')(compiler));
app.get('*', function(req, res) {
res.sendFile(path.join(__dirname, 'index.html'));
});
app.listen(8080, 'localhost', function(err) {
if (err) {
console.log(err);
return;
}
console.log('Listening at http://localhost:8080');
});
and the users file
var express = require('express')
var router = express.Router()
// middleware that is specific to this router
function validateInput(data) {
let errors = {};
if (Validator.isNull(data.username)){
errors.username = "This field is required";
}
if (Validator.isEmail(data.email)) {
errors.email = "Email is invalid";
}
if (Validator.isNull(data.password)){
errors.password = 'This field is required';
}
if (Validator.isNull(data.passwordConfirmation)){
errors.passwordConfirmation = 'This field is required';
}
if (Validator.equals(data.password, data.passwordConfirmation)){
errors.passwordConfirmation = 'Password must match';
}
return {
errors,
isValid: isEmpty(errors)
}
}
router.post('/api/users', (req, res) => {
console.log('runiing the router/post');
console.log(req.body);
const {errors, isValid} = validateInput(req.body);
if (!isValid) {
res.status(400).json(errors);
}
});
module.exports = router
in users.js file the function should be
router.post('/', (req, res) => {
console.log('runiing the router/post');
console.log(req.body);
const {errors, isValid} = validateInput(req.body);
if (!isValid) {
res.status(400).json(errors);
}
});
Because index.js have already resolved /api/users part in the request url http://localhost:8080/api/users at this point. So you only have to map after the /api/users in your users js file.
For example, if you have following function in users.js file
router.post('/:id', (req, res) => {
...
}
It will resole to the path http://localhost:8080/api/users/1
Edit
In your existing version,
router.post('/api/users', (req, res) => {
...
}
will resolve as http://localhost:8080/api/users/api/users

Resources