Null when connect GraphQL with MongoDB - mongodb

I connect GraphQL with MongoDB but result is null. Help me !
index.js file:
const { graphql } = require('graphql');
const { MongoClient } = require('mongodb');
const assert = require('assert');
const readline = require('readline');
const mySchema = require('./schema/main.js');
const rli = readline.createInterface({
input: process.stdin,
output: process.stdout
});
const MONGO_URL = 'mongodb://127.0.0.1:27017/test';
MongoClient.connect(MONGO_URL, { useNewUrlParser: true }, (err, db) => {
assert.equal(null, err);
console.log('Connected to MongoDB server');
rli.question('Client Request: ', inputQuery => {
graphql(mySchema, inputQuery, {}, { db }).then(result => {
console.log('Server Answer: ', result.data);
db.close(() => rli.close());
});
});
});
main.js file:
const {
GraphQLSchema,
GraphQLObjectType,
GraphQLInt
} = require('graphql');
const queryType = new GraphQLObjectType({
name: 'RootQuery',
fields: {
usersCount: {
type: GraphQLInt,
resolve: (_, args, { db }) => db.collection('users').count()
}
}
});
const mySchema = new GraphQLSchema({
query: queryType
});
module.exports = mySchema;
And this is result:
Connected to MongoDB server
Client Request: { usersCount }
Server Answer: { usersCount: null }

From what i could understand the db object you get from MongoClient connect callback is not your db object but instead the client object so
you should first call
const db = client.db
see Connect to MongoDB
this is something that you can find and fix easily if you can debug your code

Related

TTL on specific field returns : MongooseError: Callback must be a function, got [object Object]

const mongoose = require("mongoose");
mongoose.set("strictQuery", true);
mongoose.connect("mongodb://localhost:27017/posts");
const db2 = mongoose.createConnection("mongodb://localhost:27017/users");
const db = mongoose.connection;
db.on("error", console.error.bind(console, "connection error:"));
db.once("open", function () {
console.log("Connected to MongoDB Posts");
});
db2.on("error", console.error.bind(console, "connection error:"));
db2.once("open", function () {
console.log("Connected to MongoDB Users!");
});
module.exports = db;
module.exports.users = db2;
this below code is not creating ttl indexes based on verified field...
it returns error that "createIndexes" takes 2nd argument as a callback
const mongoose = require("mongoose");
const { users } = require("../../connection/connection.js");
const schema = new mongoose.Schema(
{
verified: {
type: Boolean,
default: false,
},
},
{ timestamps: true }
);
const model = users.model("users", schema, "users");
model.createIndexes(
{
verified: 1,
},
{
expireAfterSeconds: 3600,
}
);
module.exports = model;
I want it to be deleted after 5 minutes if user is not verified

Cannot read properties of undefined "collectionName" - Mongoose.models

I'm trying to data in the Note collection from a local database of MongoDB using Mongoose with Nextjs and getting an error "Cannot read properties of undefined (reading 'note')"
Any ideas on what I am doing wrong?
import mongoose from 'mongoose';
const { Schema } = mongoose;
const NoteSchema = new Schema(
{
title: {
type: String,
maxlength: 60,
},
description: {
type: String,
maxlength: 200,
},
},
{ timestamps: true }
);
export default mongoose.models.note || mongoose.model('note', NoteSchema)
import dbConnect from "../../../lib/dbConnect"
import Note from "../../../models/Note"
export default async function handler(req, res) {
const { method } = req
await dbConnect()
if (method === 'GET') {
try {
const note = await Note.find({})
res.status(200).json({ success: true, data: note})
} catch (error) {
res.status(400).json({ success: false })
}
}
if (method === 'POST') {
try {
const note = await Note.create(req.body)
res.status(200).json({ success: true, data: note})
} catch (error) {
res.status(500).json(error)
}
}
}
import mongoose from 'mongoose'
const {MONGODB_URI} = process.env
let cached = global.mongoose
if (!cached) {
cached = global.mongoose = { conn: null, promise: null }
}
async function dbConnect() {
if (cached.conn) {
return cached.conn
}
if (!cached.promise) {
const opts = {
useNewUrlParser: true,
useUnifiedTopology:true,
bufferCommands: false,
}
cached.promise = mongoose.connect(MONGODB_URI, opts).then((mongoose) => {
return mongoose
})
}
cached.conn = await cached.promise
return cached.conn
}
export default dbConnect
I get the following
Unhandled Runtime Error
TypeError: Cannot read properties of undefined (reading 'note')
I was able to fix it by changing the export module
global.PizzaSchema = global.NoteSchema || mongoose.model('Note', NoteSchema);
export default global.NoteSchema;

Model.populate() is not return document in Mongoose

I have two schema,
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
// Create the User Schema
const UserSchema = new Schema({
email: {
type: String
},
password: {
type: String
}
});
module.exports = User = mongoose.model("users", UserSchema);
OR
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
// Create the Status Schema
const StatusSchema = new Schema({
admin_id:{
type: Schema.Types.ObjectId,
ref: 'users'
},
text:{
type: String
},
});
module.exports = Status = mongoose.model("Status", StatusSchema, "Status");
then i use the populate in my api route:
router.get(
"/",
passport.authenticate("jwt", {
session: false,
}),
(req, res) => {
try {
Status.find({}).populate('admin_id').exec(err, data=>{
console.log(data); // return a blank array : []
return res.sendStatus(200)
})
}
} catch (error) {
res.sendStatus(500);
}
}
);
When i call this route i got an empty array [] .... Any idea what i do wrong? I should mention that i have inserted records in status collection for both admin_id
Is there any onther way to do this ?
There is a lot of ways to do this.
You sould use this,
Status.find({}).then((doc) => {
if (doc) {
Status.populate(doc, { path: "admin_id", model: "users" }, function (
err,
data
) {
if (err) throw err;
console.log(data); //here is your documents with admin user
});
}
});

why an empty array when I do an app.get()?

So I have a mongodb database to which I have imported some json data to its collection.
When I do a db.posts.find(), the data imported successfully, but when I attempt a get request, I get an empty array [].
Here is my server.js file:
'use strict';
const express = require('express');
const morgan = require('morgan');
const mongoose = require('mongoose');
mongoose.Promise = global.Promise;
const { DATABASE_URL, PORT } = require('./config');
const { BlogPost } = require('./models');
const app = express();
app.use(morgan('common'));
app.use(express.json());
app.get('/posts', (req, res) => {
BlogPost
.find()
.then(posts => {
res.json(posts.map(post => post.serialize()));
})
.catch(err => {
console.error(err);
res.status(500).json({ error: 'something went terribly wrong' });
});
});
app.get('/posts/:id', (req, res) => {
BlogPost
.findById(req.params.id)
.then(post => res.json(post.serialize()))
.catch(err => {
console.error(err);
res.status(500).json({ error: 'something went horribly awry' });
});
});
app.post('/posts', (req, res) => {
const requiredFields = ['title', 'content', 'author'];
for (let i = 0; i < requiredFields.length; i++) {
const field = requiredFields[i];
if (!(field in req.body)) {
const message = `Missing \`${field}\` in request body`;
console.error(message);
return res.status(400).send(message);
}
}
BlogPost
.create({
title: req.body.title,
content: req.body.content,
author: req.body.author
})
.then(blogPost => res.status(201).json(blogPost.serialize()))
.catch(err => {
console.error(err);
res.status(500).json({ error: 'Something went wrong' });
});
});
app.delete('/posts/:id', (req, res) => {
BlogPost
.findByIdAndRemove(req.params.id)
.then(() => {
res.status(204).json({ message: 'success' });
})
.catch(err => {
console.error(err);
res.status(500).json({ error: 'something went terribly wrong' });
});
});
app.put('/posts/:id', (req, res) => {
if (!(req.params.id && req.body.id && req.params.id === req.body.id)) {
res.status(400).json({
error: 'Request path id and request body id values must match'
});
}
const updated = {};
const updateableFields = ['title', 'content', 'author'];
updateableFields.forEach(field => {
if (field in req.body) {
updated[field] = req.body[field];
}
});
BlogPost
.findByIdAndUpdate(req.params.id, { $set: updated }, { new: true })
.then(updatedPost => res.status(204).end())
.catch(err => res.status(500).json({ message: 'Something went wrong' }));
});
app.delete('/:id', (req, res) => {
BlogPost
.findByIdAndRemove(req.params.id)
.then(() => {
console.log(`Deleted blog post with id \`${req.params.id}\``);
res.status(204).end();
});
});
app.use('*', function (req, res) {
res.status(404).json({ message: 'Yo stupido, Not Found' });
});
// closeServer needs access to a server object, but that only
// gets created when `runServer` runs, so we declare `server` here
// and then assign a value to it in run
let server;
// this function connects to our database, then starts the server
function runServer(databaseUrl, port = PORT) {
return new Promise((resolve, reject) => {
mongoose.connect(databaseUrl, err => {
if (err) {
return reject(err);
}
server = app.listen(port, () => {
console.log(`Your app is listening on port ${port}`);
resolve();
})
.on('error', err => {
mongoose.disconnect();
reject(err);
});
});
});
}
// this function closes the server, and returns a promise. we'll
// use it in our integration tests later.
function closeServer() {
return mongoose.disconnect().then(() => {
return new Promise((resolve, reject) => {
console.log('Closing server');
server.close(err => {
if (err) {
return reject(err);
}
resolve();
});
});
});
}
// if server.js is called directly (aka, with `node server.js`), this block
// runs. but we also export the runServer command so other code (for instance, test code) can start the server as needed.
if (require.main === module) {
runServer(DATABASE_URL).catch(err => console.error(err));
}
module.exports = { runServer, app, closeServer };
and here is my config.js file:
'use strict';
exports.DATABASE_URL =
process.env.DATABASE_URL || 'mongodb://localhost/seed_data';
exports.PORT = process.env.PORT || 8080;
In my models.js file, this is what my mongoose model looks like:
'use strict';
const mongoose = require('mongoose');
mongoose.Promise = global.Promise;
const blogPostSchema = mongoose.Schema({
author: {
firstName: String,
lastName: String
},
title: {type: String, required: true},
content: {type: String},
created: {type: Date, default: Date.now}
});
blogPostSchema.virtual('authorName').get(function() {
return `${this.author.firstName} ${this.author.lastName}`.trim();
});
blogPostSchema.methods.serialize = function() {
return {
id: this._id,
author: this.authorName,
content: this.content,
title: this.title,
created: this.created
};
};
const BlogPost = mongoose.model('BlogPost', blogPostSchema);
module.exports = {BlogPost};
The issue is with your first parameter in your mongoose.model(). Since you shared that the collection name is posts, that should be the name of your first parameter as a string 'posts'.
Checkout this documentation on how to declare collection name and model name:
How to declare collection name and model name in mongoose
So your mongoose.model() should look like this:
const BlogPost = mongoose.model('posts', blogPostSchema);
Give that a try.

Mongoose - how to move object to another collection

My db include following collections:
users
deleted_users
My code is following:
const name = { type: String, required: true, index: { unique: true } };
const UserSchema = new mongoose.Schema({ name });
const DeletedUserSchema = new mongoose.Schema({ name }, {
versionKey: 'version',
});
const UserModel = mongoose.model('User', UserSchema);
const DeletedUserModel = mongoose.model('Deleted_user', DeletedUserSchema);
router.put('/:id/move', (req, res) => {
UserModel.findOne(
{ _id: id }
).then((user) => {
if (!user) {
return fail(...);
}
console.log(`moving user width id ${id}`);
const newUser = new DeletedUserModel(user);
return newUser.save()
.then(
() => {
console.log('ok');
})
.catch((err) => {
console.log('catch err ', err);
});
});
}
but I always receive
{ Error
at model.wrappedPointCut [as save] (/~/prj/node_modules/mongoose/lib/services/model/applyHooks.js:111:29)
at UserModel.findOne.then (/~/prj/src/routes/user/index.js:123:20)
at process._tickDomainCallback (internal/process/next_tick.js:135:7)
message: 'No matching document found for id "58dd804c434bdc1848d491cd"',
name: 'VersionError' }
Can you check that this id you are querying is not a String but an ObjectId because I think you are passing a String as id.