I want to load only the UserData which belongs to the correct AdminId
In this Code you load all the UserData. It works fine
async mounted() {
this.userData = (await DataService.index()).data;
}
Now i want to give the AdminId to my backend. This is my Code which does not work.
async mounted() {
this.userData = (await DataService.index({ AdminId: this.$store.state.admin.id })).data;
}
This is my Backend: The Code works for where :{AdminId: 1}
async index(req, res) {
try {
const { AdminId } = req.body
const userData = await User.findAll({
where: { AdminId: AdminId },
include: [UserStatus,
{ model: SurveyResult, include: [Survey] }]
})
.map(user => user.toJSON())
}
}
Change to req.query works
async index (req, res) {
try {
const { adminId } = req.query
const userData = await User.findAll({
where: { AdminId: adminId },
include: [UserStatus,
{ model: SurveyResult, include: [Survey] }]
})
.map(user => user.toJSON())
res.send(userData)
} catch (err) {
console.log(err)
}
Related
I am trying to update using this route.
router.put("/:id", async(req,res)=>{
try {
const updateUser = await User.findByIdAndUpdate(req.params.id, {
$push: {
clients:{
client_name: req.body.client_name,
client_Username: req.body.client_Username,
client_Password: req.body.client_Password,
documents : [
{
name : req.body.docName,
descritption : req.body.docDescription,
doc_upload : req.body.doc_upload,
}
]
}
}
},{new:true})
res.status(200).json(updateUser);
}
catch(err) {
res.status(500).json(err);
}
});
Once the function founds the id it updates client_name, client_Username and client_password without any issue.
My problem is when I try to update the nested array documents with a name/description and doc_upload. I am not able to do that.
What’s wrong ? How to do it please ?
One solution could be to separate the updates:
router.put('/:id', async (req, res) => {
try {
const { id } = req.params;
const { client_name, client_Username, client_Password } = req.body;
const updateUser = await User.findByIdAndUpdate(
id,
{
$push: {
clients: {
client_name,
client_Username,
client_Password,
},
},
},
{ new: true }
);
await User.findOneAndUpdate(
{
id,
'clients.client_name': client_name,
'clients.client_Username': client_Username,
},
{
$push: {
'clients.$.documents': {
name: req.body.docName,
descritption: req.body.docDescription,
doc_upload: req.body.doc_upload,
},
},
}
);
res.status(200).json(updateUser);
} catch (err) {
res.status(500).json(err);
}
});
What im trying to do is to update one or more users with some data.
I receive the user phone numbers in an array, exp: ["+1234555", "+1222222"]. I loop through them and I check if they exist or not.
If they exist I update the data in the user model.
The problem is that let's say I have two users to update. When I execute the function only the second user is updated, the first one is not.
exports.createNotifications= asyncHandler(async (req, res, next) => {
const { userPhone, someData } = req.body;
let createUserData;
let updateUserData;
let findUser;
const createData = async () => {
userPhone.map(async (phone) => {
findUser = await Users.findOne({ phone: phone}).then(
async (user) => {
if (user) {
updateUserData= await Users.findOneAndUpdate(
{ phone: phone},
{ $push: { someData : someData } },
{ new: true }
);
}
}
);
});
};
await createNotifications();
await new Promise((resolve) => setTimeout(resolve, 1000));
console.log(updateUserData)
res.status(200).json({
success: true,
});
});
How can I update both users?
It fails because you dont wait for the async functions built in your 'map' (and actually you mess a lot with async, await and promises :p).
Considering that the code you shared is invalid, I assume that createData and createNotifications are the same.
You can wrap this creation into promises and wait for it to complete
const createNotifications = () => {
return userPhone.map(async (phone) => {
const user = await Users.findOne({ phone: phone})
if (user) {
await Users.findOneAndUpdate(
{ phone: phone},
{ $push: { someData : someData } },
{ new: true }
)
}
})
}
Promise.all(createNotifications())
.then(() => {
res.status(200).json({
success: true,
})
})
note: code not tested
userPhone.map(phone => {
let data = await Users.updateMany({
phone
}, {
$push: {
someData: someData
}
}, {
new: true
})
});
I’m trying to add a test to getAllUsers function but I don’t know why the test is failing?
I think that the assertions are run before all the async call to User.findAllfinishes!!!
do you have any suggestions?
this is the file being tested:
const { Op } = require('sequelize')
const { User } = require('../models')
const catchAsync = require('../utils/catchAsync')
const AppError = require('../utils/appError')
exports.getAllUsers = catchAsync(async (req, res, next) => {
const users = await User.findAll({
attributes: ['id', 'username', 'email', 'role', 'avatar'],
where: {
id: { [Op.gt]: 0 }
}
})
if (!users.length) {
return next(new AppError('no data found', 204))
}
res.status(200).json({
status: 'success',
data: users
})
})
and this is the test code:
const userController = require('../controllers/userController')
describe('UserController', () => {
const users = [
{
username: 'Admin',
role: 'admin',
avatar: 'bb',
email: 'admin#gmail.com'
},
{
username: 'User',
role: 'user',
avatar: 'bb',
email: 'user#gmail.com'
}
]
test('Expect to respond with 200 code and users data', async () => {
const req = {}
const res = { status: jest.fn(() => res), json: jest.fn(() => res) }
const next = jest.fn()
await userController.getAllUsers(req, res, next)
expect(res.status).toHaveBeenCalledTimes(1)
expect(res.status).toHaveBeenCalledWith(200)
expect(res.json).toHaveBeenCalledTimes(1)
expect(res.json).toHaveBeenCalledWith({
status: 'success',
data: users
})
})
})
thanks for the help
Considering there's no pre-requisite (mocked database) that hasn't been shared in the question
When you run jest --coverage it will generate you a coverage report which would give you an overview of the code execution
above you can see that the if statement has not been executed, meaning that an error is thrown from User.findAll
To solve this: you can mock the User model and it's findAll's resolved value to overcome this
const userController = require('../controllers/userController');
const { User } = require('../models');
// generate auto-mock of the module
jest.mock('../models');
describe('UserController', () => {
const users = [
// .... same as in the question
];
beforeAll(() => {
// give the mock function a value
// for the promise to be resolved with
User.findAll.mockResolvedValue(users);
});
test('Expect to respond with 200 code and users data', async () => {
// .... same as in the question
});
});
I am interested in how to create log table that writes data in own table, every time user makes some request.
And how to get data like this:
{
_id: ObjectId('4f442120eb03305789000000'),
host: "127.0.0.1",
logname: null,
user: 'frank',
time: ISODate("2000-10-10T20:55:36Z"),
path: "/apache_pb.gif",
request: "GET /apache_pb.gif HTTP/1.0",
status: 200,
response_size: 2326,
referrer: "[http://www.example.com/start.html](http://www.example.com/start.html)",
user_agent: "Mozilla/4.08 [en] (Win98; I ;Nav)"
}
Maybe not all of this data, but atleast who made the request, what type of request, path and time.
I am using nodejs, mongodb, mongoose.
You can write a middleware that logs all the requests, being sent to your server, to the MongoDB Database.
You can easily get the information you are looking for, using these npm packages,
1 - useragent
2 - express-useragent
I solved on this way.
My middlewere
const Log = require("../models/log");
const log = async (req, res, next) => {
try {
let user_id = req.user.id
let firstName = req.user.firstName
let method = req.method
let path = req.path
const log = new Log({ user_id, firstName, method, path });
try {
await log.save()
} catch (e) {
res.status(400).send(e)
}
next();
} catch (e) {
res.status(401).send(e);
}
};
module.exports = log;
Model
const mongoose = require('mongoose')
const logSchema = new mongoose.Schema({
user_id: {
type: String,
},
firstName: {
type: String,
},
method: {
type: String,
},
path: {
type: String,
},
}, {
timestamps: true
})
const Log = mongoose.model('Log', logSchema);
module.exports = Log;
and router
const express = require('express')
const Log = require('../models/log')
const auth = require('../middleware/auth')
const router = new express.Router()
//Create log
router.post('/logs', async (req, res) => {
const log = new Log({
...req.body
})
try {
await log.save()
res.status(201).send(log)
} catch (e) {
res.status(400).send(e)
}
})
//Sort and search
router.get('/logs', auth, async (req, res) => {
const match = {}
const sort = {}
if (req.query.completed) {
match.completed = req.query.completed === 'true'
}
if (req.query.sortBy) {
const parts = req.query.sortBy.split(':')
sort[parts[0]] = parts[1] === 'desc' ? -1 : 1
}
try {
await req.user.populate({
path: 'logs',
match,
options: {
limit: parseInt(req.query.limit),
skip: parseInt(req.query.skip),
sort
}
}).execPopulate()
res.send(req.user.logs)
} catch (e) {
res.status(500).send()
}
})
module.exports = router;
In my app I've established an association between the User and Project table. using this code:
User.belongsToMany(Project, {
through: "users_projects"
});
Project.belongsToMany(User, {
through: "users_projects"
});
When I do a simple post request I get the following error:
currentUser.addProject is not a function
app.post("/project", async (req, res, next) => {
try {
const project = await Project.findOrCreate({
where: {
name: req.body.name,
content: req.body.content
}
});
const currentUser = await User.findAll({
where: { id: req.body.userId }
});
console.log(currentUser);
await currentUser.addProject(project[0]);
res.json(project[0]);
} catch (error) {
next(error);
}
});
What could cause this problem?
findAll returns an array, so your code should be
await currentUser[0].addProject(project[0])
However, if you are querying with id, you can use findByPk to get object.
const currentUser = await User.findByPk(req.body.userId);
await currentUser.addProject(project[0])