prisma findMany not returning id's of rows - prisma

Using prisma findMany to fetch rows from postgres database, but it's not returning the actual id of the row, just the other columns. I need the id so that I can pass that the frontend can use it for CRUD operations, is there a way to return those ID's?
const bookList = await prisma.books.findMany({
where: {
author_id: "123",
}
});
schema
model books {
id String #id #default(uuid())
name String #db.VarChar(50)
author_id String
}
Expected response
[{
"id": "some-uid",
"name": "some-book-name"
}]
^ it includes the id field, which I'm currently not getting

The default behaviour is to return all the fields in findMany but you can explicitly select fields that should be returned by select clause.
Here is an example:
import { PrismaClient } from '#prisma/client';
const prisma = new PrismaClient();
// A `main` function so that you can use async/await
async function main() {
// ... you will write your Prisma Client queries here
const createBook = await prisma.books.create({
data: {
name: 'book1',
author_id: '1',
},
});
console.log('createBook:',createBook);
const books = await prisma.books.findMany({
where: {
author_id: '1',
},
select: {
name: true,
author_id: true,
id: true,
},
});
console.log('books:',books);
}
main()
.catch((e) => {
throw e;
})
.finally(async () => {
await prisma.$disconnect();
});
Here's the response
createBook: {
id: '04a86b46-0348-4aa3-99d4-9a28365c020c',
name: 'book1',
author_id: '1'
}
books: [
{
name: 'book1',
author_id: '1',
id: '04a86b46-0348-4aa3-99d4-9a28365c020c'
}
]

Related

why finding a record using objectId without await returns something else;

**Any one know about this ?? **
This is my code , I want to know why it gives output like these
if(orderItem != null){
// orderItem = []
orderItem.forEach( async data => {
productData = await AdminDB.findById({_id: data.orderedItemId}) ; // here data.orderedItemId contains objectId as string
console.log(productData);
});
}
Without await
Query {
_mongooseOptions: {},
_transforms: [],
_hooks: Kareem { _pres: Map(0) {}, _posts: Map(0) {} },
_executionStack: null,
mongooseCollection: Collection {
strictQuery: true,
strict: true,
pluralization: true
}, ** etc. etc ...and something like these**
with await
{
_id: new ObjectId("62af22d10cb99b48652d5d62"),
category: 'ghee',
quantity: '5',
amount: '12000',
productimg: 'https://images.pexels.com/photos/12447940/pexels-photo-12447940.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1',
__v: 0
} ** which returns record **

How to create dynamic query in mongoose for update. i want to update multiple data(Not all) with the help of Id

If I'm doing this, the field which I don't want to update is showing undefined. Any solution? (Like generating dynamic query or something)
exports.updateStudentById = async (req, res) => {
try {
const updateAllField = {
first_name: req.body.first_name,
last_name: req.body.last_name,
field_of_study: req.body.field_of_study,
age: req.body.age,
};
const data = await student_master.updateOne(
{ _id: req.body._id },
{ $set: updateAllField }
);
res.json({ message: "Student Data Updated", data: data });
} catch (error) {
throw new Error(error);
}
};
You can go for a dynamic query creation .Example
const requestBody = {
first_name: "John",
last_name: "Cena",
field_of_study: ""
}
const query={};
if(requestBody.first_name){
query["first_name"]=requestBody.first_name
}
if(requestBody.last_name){
query["last_name"]=requestBody.last_name
}
Check for the fields that are present in req.body and create a dynamic query
and when updating using mongoose use this
const data = await student_master.updateOne(
{ _id: req.body._id },
{ $set: query }
);
In this way only those fields would be updated which are present in your req.body

Merge or 'reference' and object into another through GraphQL?

Very new to graphQL (and MongoDB), and I am wondering how to reference an another object in graph QL.
I have two objects in two collections in MongoDB...
{
_id: 1,
companies: [
{
id: 1,
name: 'Google'
},
{
id: 2,
name: 'Apple'
}
]
}
{
_id: 2,
jobs: [
{
id: 1,
title: 'Designer'
},
{
id: 2,
name: 'Developer'
}
]
}
The Designer job is posted by google, and I want to include that in the returned object from GraphQL (I am using the 'id: 1' as a reference I guess? Presume ObjectID might be the way to go instead tho )
How would I go about that?
Ideally I want to return
{
"data": {
"job": {
"id": 1,
"title": "Designer",
"company": {
id: 1,
name: "Google"
}
}
}
}
But not sure how to go about it, I currently have...
resolvers.js
export const resolvers = {
Query: {
jobs: async (_parent, {}, context) => {
const jobs = await context.db
.collection('jobs')
.findOne()
return jobs.jobs
},
companies: async (_parent, {}, context) => {
const companies = await context.db
.collection('companies')
.findOne()
return companies.companies
},
job: async (_parent, { id }, context) => {
const job = await context.db.collection('jobs').findOne()
return job.jobs.find((job) => job.id === Number(id))
},
},
}
typeDefs.js
export const typeDefs = gql`
type Job {
_id: ID
id: Int
title: String
}
type Company {
_id: ID
id: Int
name: String
}
type Query {
jobs: [Job]
companies: [Company]
job(id: Int): Job
}
`
But not sure how to tie these in together? I am using Apollo / GraphQL / MongoDB / NextJS and essentially set up very close to this
Thanks in advance for any help or guidance!

GraphQL Mongoose: Cast to ObjectId failed for value

I have the following resolver for GraphQL:
const Post = require("../../models/Post");
module.exports = {
getAllActivePosts: async (userId) => {
try {
const posts = await Post.find({
userId: userId
})
.select(["name", "createdAt"])
.populate("posts", ["name", "createdAt"]);
return posts;
} catch (err) {
console.log(err);
throw err;
}
},
};
which tries to get all active posts by the ID of the user from the Post model:
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const PostSchema = new mongoose.Schema({
userId: {
type: Schema.Types.ObjectId,
ref: "User",
required: true,
},
content: {
type: String,
required: true,
},
createdAt: {
type: Date,
required: true,
}
});
module.exports = Post = mongoose.model("Post", PostSchema);
Here's the GraphQL Schema:
const { buildSchema } = require('graphql');
module.exports = buildSchema(`
type User {
_id: MongoId!
email: String!
password: String
}
type Post {
_id: MongoId!
userId: MongoId!
content: String!
createdAt: String!
}
scalar MongoId
input LoginInput {
email: String!
password: String!
}
type RootQuery {
login(email: String!, password: String!): AuthData!
getAllActivePosts(userId: MongoId!): [Post]
}
type RootMutation {
createUser(loginInput: LoginInput): AuthData!
}
schema {
query: RootQuery
mutation: RootMutation
}
`);
... and the GraphQL query I'm running in GraphiQL:
{
getAllActivePosts(userId: "5fbfc92312b90071179a160f") {
name
createdAt
}
}
For this, the result of the query is:
{
"errors": [
{
"message": "Cast to ObjectId failed for value \"{ userId: '5fbfc92312b90071179a160f' }\" at path \"userId\" for model \"Post\"",
"locations": [
{
"line": 2,
"column": 3
}
],
"path": [
"getAllActivePosts"
]
}
],
"data": {
"getAllActivePosts": null
}
}
Searched here for similar issues, tried wrapping userId in ObjectId, but nothing helped. What am I missing here?
I was go through this problem once a year ago with no solution till i get main concept of graphql.
Here you are passing string
{
getAllActivePosts(userId: "5fbfc92312b90071179a160f") {
name
createdAt
}
}
and graphql expecting to have mongoose.Types.ObjectId
getAllActivePosts(userId: MongoId!): [Post]
You need to do sync like
getAllActivePosts(userId: mongoose.Types.ObjectId("5fbfc92312b90071179a160f")) {
But using above way you are not eligible for run query in graphiQL becuse there is no mongoose defined.
type RootQuery {
login(email: String!, password: String!): AuthData!
getAllActivePosts(userId: String!): [Post]
}
Better solution is use userId input as string and then validate on your resolver function like
getAllActivePosts: async ({ userId }) => {
try {
if(mongoose.Types.ObjectId.isValid(userId)) {
const posts = await Post.find({
userId: userId
})
.select(["name", "createdAt"])
.populate("posts", ["name", "createdAt"]);
// you can;t return null you need to return array
return posts ? posts : []
} else {
// if mongoose id is wrong
return []
}
} catch(error) {
// it is better to throw error return blank array to complete flow
throw error
}
}
Turned out, I was using userId directly, whereas I should've used args.userId. The proper resolver below:
module.exports = {
getAllActivePosts: async (args) => {
try {
const posts = await Post.find({
userId: args.userId
})
.select(["name", "createdAt"])
.populate("posts", ["name", "createdAt"]);
return posts;
} catch (err) {
console.log(err);
throw err;
}
},
};
and for the schema:
getAllActivePosts(userId: String!): [Post]

graphql query return object with null id

Graphql return Oject with null id.
with mongodb.
It looks strange to me.
If I delete new GraphQLNonNull() on MailType id,
It works with id: null, another fields working fine.
const MailType = new GraphQLObjectType({
name: 'Mail',
fields: () => ({
id: { type: new GraphQLNonNull(GraphQLID), },
...
})
const Query = {
mails: {
type: new GraphQLList(MailType),
args: {
senderId: { type: GraphQLID },
isOffline: { type: GraphQLBoolean },
},
async resolve(root, args, req, ctx) {
if (args.isOffline === false) {
let a = await model.aggregate([
{ $match: { isOffline: false } },
]);
let b = await model.find({ isOffline: false });
console.log(JSON.stringify(a) == JSON.Stringify(b)) /// return true
return a // error
return b // working
}
return model.find({senderId: args.senderId});
}
}
}
// with a
"errors": [
{
"message": "Cannot return null for non-nullable field Mail.id."
}]
I am in trouble for 2 hours but I do not get the answer.
Can anybody help me?
You probably have a mistake in your mongodb schema, not in graphQl.
make sure you did not define you id by id key, it should be _id.
for example if you are using mongoose it can be something like this:
const MailSchema = new Schema({
_id: {
type: String,
unique: true,
},
....
....
});