data modules belongs to user MEANJS - meanjs

Im really new to MEANJS and after some days of google research i can't find a good way and a good tutorial to learn how to make a kind of articles module (like the one in MEANJS starter) belongs to a user.
At now my crud module work well but all the data is displayed for all users. I just want that the user can add article (here this is have an another name but anyway) and only this user can see this article.
I find your question here and you look like to have achieve a kind of what i'm trying. So if you have any tips or any ressources to help me, i'm up ! Of course i have read the mongoose docs part about population and i'm sure this is it, but alone this is hard. I've already tried to link my users module and article module but don't work.
Thanks for your time man, and have a happy coding day :)
Greettings from Paris.

If you check mongodb entry for articles it already holds the user ObjectId that created the article:
> db.articles.find()
{ "_id" : ObjectId("55c7751dbafe1a306b6ce54d"), "user" : ObjectId("55c774f9bafe1a306b6ce54c"), "content" : "My latest test. another info", "title" : "Test", "created" : ISODate("2015-08-09T15:43:25.467Z"), "__v" : 0 }
{ "_id" : ObjectId("55c7c2edd4bc5f277b775ba9"), "user" : ObjectId("55c774f9bafe1a306b6ce54c"), "content" : "ATESTE", "title" : "TESTE", "created" : ISODate("2015-08-09T21:15:25.762Z"), "__v" : 0 }
>
The reason that all articles are loaded when you click "List Articles" menu entry is because the list implementation for articles in articles.server.controller.js does not restrict the find to load only the logged user articles, the default implementation loads all articles from mongodb:
/**
* List of Articles
*/
exports.list = function (req, res) {
Article.find().sort('-created').populate('user', 'displayName').exec(function (err, articles) {
if (err) {
return res.status(400).send({
message: errorHandler.getErrorMessage(err)
});
} else {
res.json(articles);
}
});
};
I've never tried that but I believe the easiest way to do what you want would be to change that call to have a criteria and load only the articles from the logged in user, something like:
/**
* List of Articles
*/
exports.list = function (req, res) {
Article.find({user: req.user}).sort('-created').populate('user', 'displayName').exec(function (err, articles) {
if (err) {
return res.status(400).send({
message: errorHandler.getErrorMessage(err)
});
} else {
res.json(articles);
}
});
};
This, or something like this(I didn't test it) should now bring only the logged in user created articles. Check details of mongoose query here.

Related

ExpressJS / MYSQL / Prisma - Save DB' entities changes

I'm looking for a way to save database entities changes for some entities. I mean I need to save in a database table all changes that are done on some tables (add, modify / delete) with ability to track user which did the change.
I'm working on NextJS with a custom ExpressJS server and MYSQL database were I use Prisma as ORM. I think it's maybe possible to write an ExpressJS middleware but I have yet no idea how to do it and asking myself if any library already exist.
Usually I work on PHP Symfony and used to manage this StofDoctrineExtensionsBundle which is great and works as expected. But my current project is a Typescript project only with Express/NextJS/React/Prisma/MYSQL.
Any feedback from your knowledge will be very appreciate.
Thank's in advance.
Regards,
Gulivert
EDIT: My current API which has to be moved to Express/NextJS is still running on Symfony and the table where all changes is logged looks like this :
{
"id": 59807,
"user": "ccba6ad2-0ae8-11ec-813f-0242c0a84005",
"patient": "84c3ef66-548a-11ea-8425-0242ac140002",
"action": "update",
"logged_at": "2021-11-02 17:55:09",
"object_id": "84c3ef66-548a-11ea-8425-0242ac140002",
"object_class": "App\\Entity\\Patient",
"version": 5,
"data": "a:2:{s:10:\"birth_name\";s:2:\"--\";s:10:\"profession\";s:2:\"--\";}",
"username": "johndoe",
"object_name": "patient",
"description": null
}
Explanation about database columns:
user => relation to user table
patient => relation to patient table
action => can be "create"/"update"/delete"
logged_at => date time where the change was done
object_id => entity row ID where an entity get a change
object_class => the entity updated
version => how many time the object was change
data => all data changed during the modification
username => the username of logged user did the change
object_name => a string to identify the object modified without
using the namespace of object_class
description => a value that can be update on some specific change * during usually the action delete to keep a trace what was deleted for instance
You might find prisma middleware useful for this.
Check out the example with session data middleware which is somewhat similar to what you're doing.
For your use-case the middleware might look like something like this:
const prisma = new PrismaClient()
const contextLanguage = 'en-us' // Session state
prisma.$use(async (params, next) => {
// you can find all possible params.action values in the `PrismaAction` type in `.prisma/client/index.d.ts`.
if (params.model == '_modelWhereChangeIsTracked_' && (params.action == 'create' || params.action == "update")) {
// business logic to create an entry into the change logging table using session data of the user.
}
return next(params)
})
// this will trigger the middleware
const create = await prisma._modelWhereChangeIsTracked_.create({
data: {
foo: "bar"
},
})
However, do note that there are some performance considerations when using Prisma middleware.
You can also create express middleware for the routes where you anticipate changes that need to be logged in the change table. Personally, I would prefer this approach in most cases, especially if the number of API routes where changes need to be logged is known in advance and limited in number.

Query across two tables in sequelize

I am quite new to sequelize and mySQL and feel like I have tried everything in order to pass a search term ('query') to both the books table (searching against titles) and the authors table (searching against first_name or last_name). In the event of matching any of those values substrings it is to return the whole book and author information as a JSON object. When I just have the query focused on book title, it returns everything just fine. The problem comes in when I try to pass in Author columns. I have tried aliasing, nesting where clauses, everything I can think of to do and nothing I come across on here or online seems to help me figure it out.
search: (req, res) => {
const { query } = req.query;
Book.findAll({
include: [Author],
where: {
[Op.or]: [
{ title: { [Op.substring]: query } },
]},
})
.then((Book) => res.json(Book))
.catch((err) => {
console.log(err);
res.status(500).json(err);
});
},
Here is the working code. In the where clause, I want to do { first_name: { [Op.substring]: query } }, for example but it isn't accessing the Author table. In the include statement I have tried aliasing and calling it in the where clause, but that throws a aliasing error saying I have already declared an alias (Author) but when I try to use that as { 'Author.first_name' { [Op.substring]: query } }, it returns that there is no Book.Author.first_name.
I am probably missing something simple, so anyone that might be able to help, let me know what I am doing wrong here!
Solved and it was super easy. I was missing the syntax for accessing the separate table which is '$Author.first_name$'.

email verification from database using express js node js and angular 6 with mysql database

i am creating a user, with 'email' field so i want to verify whether that email is already exist or not, if exists error must display. i have my code in express js, node js, angular 6 and mysql database and below is the code to create new user
exports.create = (req, res) => {
// Save to MySQL database
let customer = req.body;
Customer.create(customer).then(result => {
// Send created customer to client
res.json(result);
});
};
where should i use if statement in above code
Thanks in advance
I'm thinking the simplest way of solving your problem is making the email column in the database unique. If you try to insert a new user with an already existing email the query will fail.
Another solution would be that you first do a query that looks in the database if an already existing user has the email (from req.body.email). But that would require having two different SQL queries, which I personally would not prefer.
i think you are using Sequelize ORM.
You can do like this
Customer.findOrCreate({
where: {
email: req.body.email,
},
// other datas needs to inserted
defaults: {
name: req.body.name,
username: req.body.username,
},
}).spread((data, created) => {
if (created) {
// your logics
} else {
res.status(400).send(`${req.body.email} already exists.`);
}
});

Return list of posts in order of time 'liked' as stored in User collection array

Okay, so here's my problem. I now have an array like this that is added to when a user 'likes' a post, which also captures the time that they have liked it.
"liked_times" : [
{
"postId" : "5CeN95hYZNK5uzR9o",
"likedAt" : ISODate("2015-09-28T02:55:08.803Z")
},
{
"postId" : "vN7uZ2d6FSfzYJLmm",
"likedAt" : ISODate("2015-09-28T02:55:26.118Z")
},
{
"postId" : "b5JEtHb9hCsQPeEQB",
"likedAt" : ISODate("2015-09-28T02:55:31.359Z")
}
]
We used to just capture the postId, but updated to getting the time as well with this post How would I return the order of MongoDB Posts by time Favourited by user?
So then we used to be able to retrieve the posts with:
Posts.find({ _id: { $in: user.liked } },
{sort: {createdAt: -1} });
But now I'm trying to work out how I would return the posts a user has liked in the order that he liked them using this new data. I'm sure there must be a relatively easy way.
Edit as per comments: I also have a simple array or list of docs with just the postId
"liked" : [
"D4turxiezBvPtNjDr",
"Hk2YpqgwRM4QCgsLv",
"vN7uZ2d6FSfzYJLmm",
"beNdpXhYLnKygD3yd",
"EBMKgrD4DjZxkxvfY"
],
When a post is liked by the user the Id is added to the end of this list. However when I return posts with return Quotes.find({ _id: { $in: user.liked } }; They are not ordered in the same order (I'm thinking due to a Minimongo local cache behaviour).
Is there another way I should be calling these docs to order them in the specific order that the array stores them? Or should I just go ahead and try to solve this using the likedAt times programatically in the code?

How to get relationship/ assosiation in sequelizejs ORM

By below reference I understood how map many to many with a relationship table
http://sequelizejs.com/docs/latest/associations#many-to-many
User = sequelize.define('User', { user_name : Sequelize.STRING})
Project = sequelize.define('Project', { project_name : Sequelize.STRING })
UserProjects = sequelize.define('UserProjects', {
status: DataTypes.STRING
})
User.hasMany(Project, { through: UserProjects })
Project.hasMany(User, { through: UserProjects })
But how to query Project 's of a User
I Tried like
User.find({where:{id:1},include,[UserProjects]})
User.find({where:{id:1},include,[Projects]})
User.find({where:{id:1},include,[UserProjects]})
User.find({where:{id:1},include,[Projects]})
But i dont get results
Sequelize created table like below
users(id,name)
projects(id,project_name)
userprojects(id,UserId,ProjectId)
I tried https://github.com/sequelize/sequelize/wiki/API-Reference-Associations#hasmanytarget-options
User.find({where:{id:1}}).success(function(user){
user.getProjects().success(function (projects) {
var p1 = projects[0] // this works fine but 2 queries required. I expect in single find. without getProjects
p1.userprojects.started // Is this project started yet?
})
})
How to get all the projects of a USER ??
You should be able to get all of the properties of the user in two different ways: using includes and getting the projects from a user instance.
Using includes the code you submitted above is almost right. This method will only make one query to the database using the JOIN operation. If you want all of the users with their corresponding projects, try:
User.findAll({include: [Project]})
You can also get the projects directly from a user instance. This will take two queries to the database. The code for this looks like
User.find(1).then(function(user) {
user.getProjects().then(function(projects) {
// do stuff with projects
});
});
Does this work for you?