I'm following this video series.
Here i have problem with getting data about user who created the event in following script
here's my app.js
const express = require('express');
const bodyParser = require('body-parser');
const graphqlHttp = require('express-graphql')
const { buildSchema } = require('graphql');
const mongoose = require('mongoose');
const bcrypt = require('bcrypt');
const Event = require('./models/event');
const User = require('./models/user');
const app = express();
const conString = `mongodb+srv://${process.env.MONGO_USER}:${process.env.MONGO_PASSWORD}#clusterpl-qiufl.mongodb.net/${process.env.MONGO_DB}?retryWrites=true&w=majority`
app.use(bodyParser.json());
app.use(
'/graphql',
graphqlHttp({
schema: buildSchema(`
type Event {
_id: ID!
title: String!
description: String!
price: Float!
date: String!
creator: User!
}
type User {
_id: ID!
email: String!
password: String!
createdEvents: [Event!]
}
input UserInput {
email: String!
password: String!
}
input EventInput {
title: String!
description: String!
price: Float!
date: String!
}
type RootQuery {
events: [Event!]!
}
type RootMutation {
createEvent(eventInput: EventInput): Event
createUser(userInput: UserInput): User
}
schema {
query: RootQuery,
mutation: RootMutation
}
`) ,
rootValue: {
events: () => {
return Event.find().populate('creator')
.then(events => {
console.log(events)
return events.map(event => {
console.log(event)
return {
...event._doc,
_id: event.id
};
});
})
.catch(err => {
throw err;
})
},
..
},
graphiql: true
})
);
mongoose.connect(conString, {useNewUrlParser: true}).then(
() => {console.log('Success !')},
err => { console.log(err) }
)
app.listen(3000);
user.js and event.js
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const userSchema = new Schema({
email: {
type: String,
required: true
},
password: {
type: String,
required: true
},
createdEvents: [
{
type: Schema.Types.ObjectId,
ref: 'Event'
}
]
});
module.exports = mongoose.model('User', userSchema)
const mongoose = require('mongoose');
const Schema = mongoose.Schema
const eventSchema = new Schema({
title: {
type: String,
required: true
},
description: {
type: String,
required: true
},
price: {
type: Number,
required: true
},
date: {
type: Date,
required: true
},
creator: [
{
type: Schema.Types.ObjectId,
ref: 'User'
}
]
});
module.exports = mongoose.model('Event', eventSchema);
once i submit this graphql query
query{
events {
creator {
email
}
}
}
returns "message": "Cannot return null for non-nullable field User.email.",
I'm completly new to graphql and any answer would be much appreciate.
maybe this might helps someone else, i don't know what happens there but i got expected results, by adding
const user = userId => {
return User.findById(userId).then(user => {
return { ...user._doc, _id: user.id };
})
.catch(err => {
throw err;
});
}
method and used it in event resolver function like this
events: () => {
return Event.find()
.populate('creator')
.then(events => {
return events.map(event => {
console.log('ev',event._doc)
return {
...event._doc,
_id: event.id,
// creator: {
// ...event._doc.creator._doc,
// _id: event._doc.creator.id
// }
creator: user.bind(this, event._doc.creator)
};
})
})
.catch(err => {
throw err;
})
},
Related
I have a User schema which has reference to a profile schema.
const UserSchema = new Schema(
{
_id: mongoose.Schema.Types.ObjectId,
email: {
....email props...
},
password: {
...password props...
},
profile: [{
type: mongoose.Schema.Types.ObjectId,
ref: "Profile",
}],
},
);
const Profile = new Schema({
_user: {
type: Schema.Types.ObjectId, ref: 'User'
},
'displayName': {
type: String,
default: ''
},
'interestedActivities': ['Ping-pong'], <---- This bad boy/girl is an array
'memberSince': { type: Date, default: Date.now }
}
)
I'd like to create a route which can update the User properties AND the Profile properties in one shot—with a caveat one of the properties on the Profile model is an array!!!
I tried this....
handler
.use(auth)
.put((req, res, next) => {
emailValidator(req, res, next, 'email');
},
async (req, res, next) => {
await connectDB()
const {
profileDisplayName,
profileEmail,
interestedActivities } = req.body;
const update = {
email: profileEmail,
'profile.$.displayName': profileDisplayName,
'profile.$.interestedActivities': interestedActivities
}
const filter = { _id: req.user.id };
const updatedUser = await User.findOneAndUpdate(filter, update, { new: true })
try {
console.log("updatedUser ", updatedUser);
if (updatedUser) {
return res.status(200).send({
updatedUser,
msg: `You have updated your profile, good job!`
});
}
} catch (error) {
errorHandler(error, res)
}
})
export default handler;
My response is:
Status Code: 500 Internal Server Error
Cast to ObjectId failed for value "[
{
id: 'ae925393-0935-45da-93cb-7db509aedf20',
name: 'interestedActivities',
value: []
}
]" (type Array) at path "profile.$"
Does anyone know how I could also afford for the property which is an array?
Thank you in advance!
my model(cart.js)
const mongoose = require('mongoose');
const Schema = mongoose.Schema
var cartSchema = new Schema({
prodId: { type: Number },
img: { type: String },
qnt: { type: Number },
amt: { type: Number },
name: { type: String },
address: {type: String}
})
module.exports = mongoose.model('cart', cartSchema,'carts');
=====>
my routes(cart.js):
router.post('/', (req, res) => {
let cartData = req.body
let cart = new Cart(cartData)
console.log(req.body)
cart.save((error, cart) => {
if(error){
console.log("Error: "+ error)
}
else{
res.status(200).send(cart)
}
})
})
there is no error in console .everything is fine but getting only _id,_v in database.
what is wrong ?please help me.
thanks in advance
Tried to insert auto increment number for serial number in mongodb using mongoose and nodejs but not working.Where i want to update my code to find solution.If anyone knows please help to find solution.
subs.model.js:
const mongoose = require('mongoose');
var subscriberSchema = new mongoose.Schema({
_id: {type: String, required: true},
email: {
type: String
}
}, {
versionKey: false,
collection: 'subscribers'
});
module.exports = mongoose.model('Subscribers', subscriberSchema);
data.controller.js:
module.exports.subscribeMail = (req, res, next) => {
var subscribeModel = mongoose.model("Subscribers");
var subscribemailid = req.query.email;
var subscribe = new subscribeModel({
email: subscribemailid
});
var entitySchema = mongoose.Schema({
testvalue: { type: String }
});
subscribe.save(function(error, docs) {
if (error) { console.log(error); } else {
console.log("subscribe mail id inserted");
console.log(docs)
res.json({ data: docs, success: true });
}
});
entitySchema.pre('save', function(next) {
var doc = this;
subscribe.findByIdAndUpdate({ _id: 'entityId' }, { $inc: { seq: 1 } }, function(error, counter) {
if (error)
return next(error);
doc.testvalue = counter.seq;
next();
});
});
};
If i use above code inserting data into mongodb like below:
_id:5f148f9264c33e389827e1fc
email:"test#gmail.com"
_id:6f148f9264c33e389827e1kc
email:"admin#gmail.com"
But i want to insert like this
_id:5f148f9264c33e389827e1fc
serialnumber:1
email:"test#gmail.com"
_id:6f148f9264c33e389827e1kc
serialnumber:2
email:"admin#gmail.com"
You can use this plugin: https://www.npmjs.com/package/mongoose-auto-increment
First you need to initialize it after creating Mongoose connection:
const connection = mongoose.createConnection("mongodb://localhost/myDatabase");
autoIncrement.initialize(connection);
Than in your subs.model.js file:
const mongoose = require('mongoose');
const autoIncrement = require('mongoose-auto-increment');
var subscriberSchema = new mongoose.Schema({
_id: {type: String, required: true},
email: {
type: String
}
}, {
versionKey: false,
collection: 'subscribers'
});
subscriberSchema.plugin(autoIncrement.plugin, {
model: 'Subscribers',
field: 'serialnumber'
});
module.exports = mongoose.model('Subscribers', subscriberSchema);
I'm trying to remove a product from a category using mongoose .remove from these other questions but none seem to work
Remove sub-document from Mongo with mongoose
But nothing is happening and I only get back the same thing unedited
Category Schema
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const Product = require('./Product');
const CategorySchema = Schema({
_id: Schema.Types.ObjectId,
categoryName: {
type: String,
required: true,
},
categoryDescription: String,
productList: [Product],
});
mongoose.model('Category', CategorySchema);
Products Schema
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const ProductSchema = Schema({
productName: {
type: String,
required: true,
},
productDescription: String,
categories: { type: Schema.Types.ObjectId, ref: 'Category' },
});
mongoose.model('Product', ProductSchema);
My express route to handle deleting of the subdocument
app.delete('/api/category-with-product/:categoryId', (req, res) => {
const categoryId = req.params.categoryId;
const { productId } = req.body;
Category.findById(categoryId)
.then((category) => {
category.productList.pull({ _id: productId });
return category.save();
})
.then((newCategory) => {
res.send(newCategory);
});
});
My expected outcome is for this is to just remove the product in the productList array
{
_id: 5c5b990d56b3f61ce3736e6f,
categoryName: 'A new category name',
description: 'description',
productList:[
{ _id: 5c6e4b5114333b25f8e9d737,
productName: 'test',
productDescription: 'test'
}
],
}
Could you please try this:
const ObjectId = mongoose.Types.ObjectId;
function funcName() {
return new Promise((resolve, reject) => {
db.category.update(
{ },
{ $pull: { productList: { _id: ObjectId(productId) } } },
{ multi: true }
)
.then((result) => resolve())
.catch((err) => reject(err));
});
}
You can also try Async/Await during database operations.
I want to do something like following code, but it failed.
var User = new Schema({
name: { type: String, required: true },
phone_number: { type: String, required: true },
modified: { type: Date, default: Date.now },
contacts: [{
user: { type : Schema.ObjectId, ref : 'User' }
}]
});
var UserModel = mongoose.model('User', User);
Is it able to achieve that purpose?
I think I used the wrong way to check it, actually it works.
Following is my test :
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
mongoose.connect('localhost', 'contacts_test');
var User = new Schema({
name: { type: String, required: true },
phone_number: { type: String, required: true },
modified: { type: Date, default: Date.now },
contacts: [
{
user: { type: Schema.ObjectId, ref: 'User' }
}
]
});
var UserModel = mongoose.model('User', User);
mongoose.connection.on('open', function () {
var user1 = new UserModel({name: 'kos', phone_number: "003"});
user1.save(function (err) {
if (err) throw err;
var user2 = new UserModel({name: 'java', phone_number: "008"});
user2.contacts = [{user: user1._id}];
user2.save(function (err) {
UserModel.findById(user2._id)
.populate('contacts.user')
.exec(function (err, user) {
if (err) console.error(err.stack || err);
console.log('user name: ' + user.name);
console.error('contact of first result : ', user.contacts[0].user.name);
mongoose.connection.db.dropDatabase(function () {
mongoose.connection.close();
});
});
});
});
});