I have a user and project entity with OneToMany relations between them,
user.entity.ts
#ManyToOne(() => Project, pro => pro.members, {
nullable: true
})
#JoinColumn({
name: 'userId',
})
member: Project;
project.entity.ts
#OneToMany(() => User, user => user.member)
members: User[]
function to add user to project:
async addMemberToProject(projectId: number, memberEmail: string): Promise<void> {
const project = await this.conn.getRepository(Project).findOne({
where: {
id: projectId
}
}).catch(() => {
throw new BadRequestException("Project not found!");
});
const user = await this.getUserByEmail(memberEmail).catch(() => {
throw new BadRequestException("User not found!");
})
if(user !== null) {
project.members.push(user);
await this.conn.getRepository(Repository).save(project).catch(() => {
throw new BadRequestException("Member not added to project!");
});
}
}
why when I try to add user to project, my compiler throw me:
Cannot read property 'push' of undefined
What i'm doing wrong? Maybe I have a bad database logic? (User can be in many projects, project can have many users), Can someone help me? Thanks for any help!
#JoinColumn on the user.entity looks wrong, it should be named: projectId, assuming the primary key of Project.entity is projectId.
The reason for you error is you need to add relations: ['members'] to project findOne()
const project = await this.conn.getRepository(Project).findOne({
where: {
id: projectId
},
relations: ['members']
})
Without this, TypeORM does not populate "project.members": project.members is undefined, so project.members.push(user) causes an "undefined" error.
Related
I'm working on a nextjs 13 project with prisma ORM with MongoDB. Currently I am trying to fetch roles with permissions for admin role matrix. This is the Role model schema.
model Role {
id String #id #default(auto()) #map("_id") #db.ObjectId
name String #unique
userIDs String[] #db.ObjectId
users User[] #relation(fields: [userIDs], references: [id])
permissions String[]
##map("roles")
}
When fetching the records I'd like to process them a little. Running this query returns such result.
const roles = await prisma.role.findMany({
select: {
name: true,
permissions: true,
}
})
console.log(roles);
[
{ name: 'User', permissions: [ 'permissions.user.view.dashboard' ] },
{
name: 'Admin',
permissions: [
'permissions.admin.view.dashboard',
'permissions.user.view.dashboard'
]
}
]
I need the results in one object with role name prepended to the permission like so
{
'User.permissions.user.view.dashboard',
'Admin.permissions.user.view.dashboard',
'Admin.permissions.admin.view.dashboard'
}
So my question is how would I do this? Preferably directly in prisma, but if it's not possible javascript will do.
It's not possible to transform this object directly at Prisma level.
You can achieve this transformation like this:
import { PrismaClient } from '#prisma/client';
const prisma = new PrismaClient();
async function main() {
const roles = await prisma.role.findMany({
select: {
name: true,
permissions: true,
},
});
console.log(roles);
const updatedRoles = [];
roles.forEach((role) => {
role.permissions.forEach((permission) => {
updatedRoles.push(`${role.name}.${permission}`);
});
});
console.log(updatedRoles);
}
main()
.catch((e) => {
throw e;
})
.finally(async () => {
await prisma.$disconnect();
});
Here's the sample response:
So i was implementing a users model in my mvc and then i get a weird error saying
MongoClient constructor.
D:\node\node_modules\mongoose\lib\document.js:2022
if (path in this.$__.selected) {
^
TypeError: Cannot use 'in' operator to search for 'email' in saifkhan501721#gmail.com
at model.isSelected (D:\node\node_modules\←[4mmongoose←[24m\lib\document.js:2022:14)
at D:\node\node_modules\←[4mmongoose←[24m\lib\document.js:2195:14
at Array.filter (<anonymous>)
at _getPathsToValidate (D:\node\node_modules\←[4mmongoose←[24m\lib\document.js:2194:71)
at model.Document.$__validate (D:\node\node_modules\←[4mmongoose←[24m\lib\document.js:2365:23)
at D:\node\node_modules\←[4mkareem←[24m\index.js:369:33
←[90m at processTicksAndRejections (internal/process/task_queues.js:79:11)←[39m
i have no idea as to what is the reason behind the error is, is it a syntax error , logical error connection error or mispelling of a variable,well anyway here's my app.js
mongoose
.connect('mongodb+srv://turd_waffle:SaifKhan#cluster0.lltqs.mongodb.net/shop?retryWrites=true&w=majority')
.then((result) => {
User.findOne().then(user=>{
if(!user){
const user=new User({
name:'Saif',
email:'saifkhan501721#gmail.com',
cart:{
items:[]
}
})
user.save()
}
})//save() saves the documents(mostly used as a reference to generate a sample id in order to start a cluster working)
app.listen(3000)
})
.catch(err => {
console.log(err)
})
here's my user.js model to store users data in mongodb database
const mongoose = require('mongoose')
const Schema = mongoose.Schema;
const userSchema = new Schema({
name: {
type: String,
required: true
},
email: {
type: String,
required: true
},
cart: {
items: [{
productId: {
type: Schema.Types.ObjectId,
ref: 'Product',
required: true
},
quantity: {
type: Number,
required: true
}
}]
},
})
userSchema.methods.addToCart = function(product) {
const cartProductIndex = this.cart.items.findIndex(cp => {
return cp.productId.toString() === product._id.toString();
})
let newQuantity = 1;
const updatedCartItems = [...this.cart.items];
if (cartProductIndex >= 0) {
newQuantity = this.cart.items[cartProductIndex].quantity + 1;
updatedCartItems[cartProductIndex].quantity = newQuantity
} else {
updatedCartItems.push({
productId: product._id,
quantity: newQuantity
})
}
const updatedCart = {
items: updatedCartItems
}
this.cart=updatedCart
return this.save()
}
module.exports = mongoose.model('User', userSchema)
can anyone please be kind enough to atleast tell me what the error above is trying to say i used app.use to create a user so i can store his id, email and name
app.use((req, res, next) => {
User.findById('5f788c080ba19e0f8c642202')
.then(user => {
req.user = new User(user.name, user.email, user.cart, user._id);
next();
})
.catch(err => console.log(err));
});
Strange issue. From the code you provided, the issue should not arise.
When I look at the code in mongoose, the only way that this could happen is if you would do something like:
new User("saifkhan501721#gmail.com")
Then this.$__.selected would be a string instead of an object (e.g. {email: "saifkhan501721#gmail.com"}) and path in this.$__.selected would cause your received type error.
Not knowing enough about your app, I would assume that there maybe is a bad User object created somewhere else / cached / or already in database. Maybe it would help to verify this using a clean database?
See the source code for reference. When I take a look at the code it seems like an oversight that it is not checked if this.$__.selected is a string, because in this case it does not fail early (e.g. Object.keys(this.$__.selected) will not cause an error).
I wanted to make a chat app to practice working with graphql and node, for database I used prisma. I was doing everything like in this tutorial.
https://www.howtographql.com/graphql-js/0-introduction/
I just changed variable names.
so I have this code
const { PrismaClient } = require('#prisma/client')
const prisma = new PrismaClient()
const resolvers = {
Query: {
history: async (parent, args, context) => {
return context.prisma.Messages.findMany()
},
},
Mutation: {
post: (parent, args, context) => {
const newMessage = context.prisma.Messages.create({
data: {
username: args.username,
message: args.message,
},
})
return newMessage
},
},
}
const server = new GraphQLServer({
typeDefs: './src/schema.graphql',
resolvers,
context: {
prisma,
}
})
server.start(() => console.log(`Server is running on http://localhost:4000`))
as my index.js
this is my schema.prisma
provider = "sqlite"
url = "file:./dev.db"
}
generator client {
provider = "prisma-client-js"
}
model Message {
id Int #id #default(autoincrement())
sendedAt DateTime #default(now())
message String
username String
}
script.js
const { PrismaClient } = require("#prisma/client")
const prisma = new PrismaClient()
async function main() {
const newMessage = await prisma.Messages.create({
data: {
message: 'Fullstack tutorial for GraphQL',
username: 'www.howtographql.com',
},
})
const allMessages = await prisma.Messages.findMany()
console.log(allMessages)
}
main()
.catch(e => {
throw e
})
// 5
.finally(async () => {
await prisma.disconnect()
})
and schema.graphql
type Query {
history: [Message!]!
}
type Mutation {
post(username: String!, message: String!): Message!
}
type Message {
id: ID!
message: String!
username: String!
}
and that is what i got in my playground
"data": null,
"errors": [
{
"message": "Cannot read property 'findMany' of undefined",
"locations": [
{
"line": 2,
"column": 3
}
],
"path": [
"history"
]
}
]
}
please help
I managed to fix that. Actually, all I needed was to use the same name but lowercased as in schema.prisma
It should be noted it is not actually lowercase but camel case.
Example:
Model name: Message -> Prisma client name: message
Model name: MessagePerUser -> Prisma client name: messagePerUser
Would like to add on to the answer
Basically when calling await prisma.User.create, prisma allows the User model to be in caps, but when calling other models such as prisma.messages.create the m has to be in lowercase. Essentially,for all prisma calls, the models should be in lowercase. Hopefully this answers your question, prisma does not flag this error out
use Table name as camelCase in prisma Client to make Queries
Example:
Table Name is: StudentData
then use camelCase according to table name
prisma.studentData.findMany();
I am trying to create a DB for school. In this DB I want to store Class name with properties with sessionId is foreign key which is referencing to session table.
Similarly, I am storing students with foreign key classId
students array at the first line is coming from other function which perfectly working.
Problem is here when I create new session then get stored in DB and newSession variable also gets value but it not comes in class creation. It comes as null. Here sessionId: newSession.id it comes as null.
Similar class get stored in db with nulled sessionId and while creating Student the newClass.id comes null. Although class is perfectly get stored in DB.
What's the problem in code? Why newClass.id and newSession.id comes as null while creating Student and Class
students.forEach(async function(student) {
//Create Session
let newSession = await Session.findOrCreate({
where: {
name: student.session,
startDate: student.sStartDate,
endDate: sEndDate
}
})
.then(newSession => {
return newSession;
})
.catch(err => console.log(err));
//Create Class
let newClass = await Class.findOrCreate({
where: {
name: student.class
},
defaults: {
name: student.class,
sessionId: newSession.id
}
})
.then(newClass => {
return newClass;
})
.catch(err => console.log(err));
//Create a student.
Student.findOrCreate({
where: {
id: student.id
},
defaults: {
id: student.id,
name: student.name,
fphone: student.fphone,
fname: student.fname,
classId: newClass.id
}
})
.then(newStudent => {
// console.log(JSON.stringify(newStudent, null, 4));
})
.catch(err => console.log(err));
});
res.send(students);
}
Per the manual, findOrCreate returns an array containing the object that was found or created and a boolean that will be true, so you're using the result incorrectly.
https://sequelize.org/master/manual/models-usage.html
Try something like this:
let newSession = null;
try {
const sessionResult = await Session.findOrCreate({
where: {
name: student.session,
startDate: student.sStartDate,
endDate: sEndDate
}
});
newSession = sessionResult[0];
} catch(e) {
console.error(e);
}
Also, no need to use .then and .catch if you're using await. Use try/catch instead to catch the error.
I am creating a RESTful API using Node.js and mongoose by following the tutorial by Acedemind. I have got it working just fine and am now expanding it to allow the client to post several products in the same order. Basically I am modifying a simple "POST" request to be an array instead of some variables. My problem is that I run into a long validation error that hinders the array from being created. Here is the code for the post request:
router.post("/", async (req, res, next) => {
const productsMaybeFalses = await Promise.all(req.body.products.map(async ({ productId })=> {
const product = await Product.findById(productId);
if (!product) {
return false;
}
return {
...product,
productId,
}
}));
const errors = productsMaybeFalses
.map((productMaybeFalse, index) => {
return {
productMaybeFalse, index
}
})
.filter(({ productMaybeFalse }) => !productMaybeFalse)
if (errors.length) {
console.log(error);
return;
}
console.log(productsMaybeFalses);
const products = productsMaybeFalses
.filter((productMaybeFalse) => productMaybeFalse);
const order = new Order({
_id: mongoose.Types.ObjectId(),
products: products
});
return order.save().then(results => {
console.log(results);
res.status(201).json(results.map((result) => ({
message: "order stored",
createdOrder: {
_id: result._id
},
request: {
type: "GET",
url: "http://localhost:3000/orders/" + result._id
}
})));
})
.catch(err => {
console.log(err);
res.status(500).json({
error: err
})
})
})
And here is the Schema for the Order:
const mongoose = require("mongoose");
const pSchema = mongoose.Schema({
productId: { type: mongoose.Schema.Types.ObjectId, ref: "Product", required: true},
quantity: { type: Number, default: 1}
});
const orderSchema = mongoose.Schema({
_id: mongoose.Schema.Types.ObjectId,
products: [pSchema]
});
module.exports = mongoose.model("Order", orderSchema)
To keep this question from being too long I will only post the end part of the error. The part that I feel tells the most information abut the problem. If anyone wants the whole error message to better understand the problem and maybe come up with a solution for me I will be very willing to post it as well. Here it is:
kind: 'Array',
value: [Array],
path: 'products',
reason: TypeError: value[i].toObject is not a function
at DocumentArray.cast (/Users/axelhagman/Documents/Jacobs/node_modules/mongoose/lib/schema/documentarray.js:309:27)
at DocumentArray.SchemaType.applySetters (/Users/axelhagman/Documents/Jacobs/node_modules/mongoose/lib/schematype.js:755:12)
at model.$set (/Users/axelhagman/Documents/Jacobs/node_modules/mongoose/lib/document.js:922:18)
at model._handleIndex (/Users/axelhagman/Documents/Jacobs/node_modules/mongoose/lib/document.js:740:14)
at model.$set (/Users/axelhagman/Documents/Jacobs/node_modules/mongoose/lib/document.js:697:22)
at model.Document (/Users/axelhagman/Documents/Jacobs/node_modules/mongoose/lib/document.js:114:12)
at model.Model (/Users/axelhagman/Documents/Jacobs/node_modules/mongoose/lib/model.js:73:12)
at new model (/Users/axelhagman/Documents/Jacobs/node_modules/mongoose/lib/model.js:4324:13)
at router.post (/Users/axelhagman/Documents/Jacobs/api/routes/orders.js:70:17)
at <anonymous>
at process._tickCallback (internal/process/next_tick.js:189:7) } },
_message: 'Order validation failed',
name: 'ValidationError' }
POST /orders/ 500 440.085 ms - 7622
I am very new to using node.js and creating API overall so any help would be very much appreciated. Thanks!