I am trying to connect to mongoose through my server but failing to do so.
I have already tried to put it into a try catch block but it says db.close or client.close is not a function. when I try to connect, I am getting an error "Unhandled promise rejection warning".
I would be glad if anyone could help me with this
const mongoose = require('mongoose');
mongoose.Promise = global.Promise;
const client = mongoose.connect('mongodb://localhost:27017/customercli', {
useNewUrlParser: true });
// import the model
const Customer = require('./models/customer');
// Add customer
const addCustomer = (customer) => {
Customer.create(customer).then(customer => {
console.info("New Customer Added");
client.close();
});
}
// Find customer
const findCustomer = (name) => {
//Make this case insensitive
const search = new RegExp(name, 'i') // here lowercase i made it
insensitive
Customer.find({$or: [{firstname: search}, {lastname: search}]})
.then(customer => {
console.log(customer);
console.log(`${customer.length} matches`);
client.close();
});
}
//Export all methods
module.exports = {
addCustomer,
findCustomer
}
I found the way to do this by myself. The connection to mongoose through my server was not getting closed. so i replaced db.close() with mongoose.connection.close() and it worked just fine.
Related
This is my middleware,
export const parseUser = (req, res, next) => {
const token_header = req.header('Authorization');
if (token_header) {
req.user = jwt_decode(token_header.split(' ')[1].split(' ')[0]);
req.token = token_header.split(' ')[1].split(' ')[0];
next();
} else {
next();
}
};
this is my router,
router.get('/get/', parseUser, swaggerValidation.validate,
async(req, res) => {
...
} catch (err){
...
}
});
i am trying to mock the parseUser function and assign req.user and req.token values using jest and pass it, i need those values to authorize user and need the value assigned to do database query, I am using jest to mock the functions, I have tried google and stackoverflow, i was not able to solve it with those example, i have tried below methods and others,
jest.mock('../../utils/permission');
const mockedParseUser = jest.mocked(parseUser, true)
mockedParseUser.mockReturnValueOnce({req.user: "value", req.token: "value");
i have also tried,
const return = {req.user: "value", req.token: "value"}
const mockedReturn = jest.fn((): any => return}
jest.spyOn('../../utils/permission', parseUser).mockImpementation((): any => mockReturn())
Nothing worked for me, can someone help me with mocking the parseUser().
I tried to find the solutions over here but unable to get success while using $pull as the array values I have does not contain `mongo_id'.
So the scenario is that , I am trying to delete the specific comment of the particular user which I am passing through query params. M
My mongo data looks like this:
Now I am making API Delete request like this : http://localhost:8000/api/articles/learn-react/delete-comment?q=1 on my localhost .
ANd finally my code looks like this:
import express from "express";
import bodyParser from "body-parser";
import { MongoClient } from "MongoDB";
const withDB = async (operations, res) => {
try {
const client = await MongoClient.connect(
"mongodb://localhost:27017",
{ useNewUrlParser: true },
{ useUnifiedTopology: true }
);
const db = client.db("my-blog");
await operations(db);
client.close();
} catch (error) {
res.status(500).json({ message: "Error connecting to db", error });
}
};
app.delete("/api/articles/:name/delete-comment", (req, res) => {
const articleName = req.params.name;
const commentIndex = req.query.q;
withDB(async(db) => {
try{
const articleInfo = await db.collection('articles').findOne({name:articleName});
let articleAllComment = articleInfo.comments;
console.log("before =",articleAllComment)
const commentToBeDeleted = articleInfo.comments[commentIndex];
//console.log(commentToBeDeleted)
// articleAllComment.update({
// $pull: { 'comments':{username: commentToBeDeleted.username }}
// });
articleAllComment = articleAllComment.filter( (item) => item != commentToBeDeleted );
await articleAllComment.save();
console.log("after - ",articleAllComment);
//yaha per index chahiye per kaise milega pta nhi?
//articleInfo.comments = gives artcle comment
res.status(200).send(articleAllComment);
}
catch(err)
{
res.status(500).send("Error occurred")
}
},res);
});
I have used the filter function but it is not showing any error in terminal but also getting 500 status at postman.
Unable to figure out the error?
I believe you'll find a good answer here:
https://stackoverflow.com/a/4588909/9951599
Something to consider...
You can use MongoDB's built-in projection methods to simplify your code.
https://docs.mongodb.com/manual/reference/operator/projection/positional/#mongodb-projection-proj.-
By assigning a "unique ID" to each of your comments, you can find/modify the comment quickly using an update command instead of pulling out the comment by order in the array. This is more efficient, and much simpler. Plus, multiple read/writes at once won't interfere with this logic during busy times, ensuring that you're always deleting the right comment.
Solution #1: The recommended way, with atomic operators
Here is how you can let MongoDB pull it for you if you give each of your comments an ID.
await db.collection('articles').updateOne({ name:articleName },
{
$pull:{ "comments.id":commentID }
});
// Or
await db.collection('articles').updateOne({ name:articleName, "comments.id":commentID },
{
$unset:{ "comments.$":0 }
});
Solution #2 - Not recommended
Alternatively, you could remove it by index:
// I'm using "3" here staticly, put the index of your comment there instead.
db.collection('articles').updateOne({ name:articleName }, {
$unset : { "comments.3":0 }
})
I do not know why your filter is erroring, but I would recommend bypassing the filter altogether and try to utilize MongoDB's atomic system for you.
Trying to remove the users`s data calling a function from app.
'use strict';
const functions = require('firebase-functions');
const firebase_tools = require('firebase-tools');
const admin = require('firebase-admin');
const serviceAccount = require('./myapp.json');
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "https://myapp.firebaseio.com"
});
let db = admin.firestore();
exports.mintAdminToken = functions.https.onCall((data, context) => {
const uid = data.uid;
return admin
.auth()
.createCustomToken(uid, { admin: true })
.then(function(token) {
return { token: token };
});
});
exports.recursiveDelete = functions
.runWith({
timeoutSeconds: 540,
memory: '1GB'
})
.https.onCall((data, context) => {
if (!(context.auth && context.auth.token )) {
throw new functions.https.HttpsError(
'permission-denied',
'Must be an administrative user to initiate delete.'
);
}
let path = data.path;
console.log(
`User ${context.auth.uid} has requested to delete path ${path}`
);
return firebase_tools.firestore
.delete(path, {
project: process.env.GCLOUD_PROJECT,
recursive: true,
yes: true,
token: functions.config().fb.token
})
.then(() => {
return {
path: path
};
});
});
and I pass the path like:
Map<String, Object> data = new HashMap<>();
data.put("path", "./users/rnAjpK4LLSMMlENZqe4l3F2");
result:
Function execution took 540003 ms, finished with status: 'timeout'
probably the problem is in path. if I change for this line:
let path = admin.firestore().doc('users/' + context.auth.uid);
Im getting an error
Unhandled error TypeError: this.path.replace is not a function at new FirestoreDelete
is the problem with "path"?
what will be the right path to delete then?
I use this example https://github.com/firebase/snippets-node/tree/master/firestore/solution-deletes but here is nothing about it
UPDATED:
with
String path = "./users/rnAjpK4LLSMMlENAgrZqe4l3F2";
or
String data = "./users/rnAjpK4LLSMMlENAgrZqe4l3F2";
an error
Unhandled error { FirebaseError: Must specify a path. at Object.reject (/srv/node_modules/firebase-tools/lib/utils.js:82:27)
solution
const id = context.auth.uid;
const path = `users/${id}`;
As far as I can see from reading the code of the delete function, the path you pass in has to be a single string value of the collection or document to delete. The function will then delete all data under that collection or document.
I was accidentally sending an entire object. If you come across this question, double check you're not making the same mistake.
I am having some troubles trying to set up a database for testing purposes. The data stored in the database should be removed an re-populated for each test. I am currently doing the following:
db.js
const mongoose = require('mongoose');
// a Mongoose model describing an entity
const Entity = require('entity-model');
// entities.mock is an array containing entity objects.
const mockedEntities= require('./entities.mock');
function setUp() {
Entities.collection.insertMany(mockedEntities);
}
function breakDown() {
mongoose.connection.on('connected', () => {
mongoose.connection.db.dropDatabase();
});
}
module.exports = { setUp, breakDown };
Then in my test.js:
const db = require('./db');
describe('e2e tests to make sure all endpoints return the correct data from the database', () => {
beforeEach(async () => {
await db.breakDown();
db.setUp();
});
it('should check store-test-result (UR-101)', (done) => ...perform test);
it('should check store-nirs-device (UR-102)', (done) => ...perform test);
});
It seems like I am not emptying out the database before re-populating it correctly. Any advise as to what could be the cause?
I ended up doing:
beforeEach(async () => {
await MyEntity.collection.drop();
await MyEntity.collection.insertMany(mockedMyEntity);
});
This solved my issue.
In case this result in an Mongo Error ns not found you need to explicitly create the collection in the database before dropping it. This happens if the collection does not exist. You can do this by adding a before:
before(async () => {
await MyEntity.createCollection();
});
Do not set option: autoCreate to true in you model as this should not be set to false in production according to https://mongoosejs.com/docs/guide.html#autoCreate.
First of all, please forgive me if this is a duplicate, I am new to coding and Javascript in general.
I have an async function that queries mongodb based on an objects passed in the function call. The function executes, and returns the results to a callback function which logs the results to the console, and then hangs. Ultimately, I want to take the results of the async query and then do something with them outside the original async function. I am not understanding why it hangs after it logs to the console.
const MongoClient = require('mongodb').MongoClient;
let fObj = {
field : {},
limit : 100
}
let cObj = {
dbName : 'myNewDatabase',
colName : 'newCollection'
}
async function findDoc(cObj,fObj) {
const url = 'mongodb://localhost:27017';
const client = new MongoClient(url, { useNewUrlParser: true });
try {
await client.connect();
const db = client.db(cObj.dbName);
const col = db.collection(cObj.colName);
console.log(`Connection Made to ${db.databaseName} database.`);
return await col.find(fObj.field).limit(fObj.limit).toArray();
client.close();
} catch (err) {
console.log(err.stack);
}
};
findDoc(cObj,fObj).then(function(result) {
console.log(result);
});
The code executes, and logs the results to the console, but then hangs. I have to ctrl-c out to get it to end. What am I missing?
I suppouse you're running your code with NodeJs. This implies that you have a promise hanging up, which keeps the server running. I assume this is because your connection to the DB is still open after you have found the document.
You need to move your client.close(); statement above the return statement, because it is never reached otherwise and your server will hang up forever.
Your code will look like this in the end:
const MongoClient = require('mongodb').MongoClient;
let fObj = {
field : {},
limit : 100
}
let cObj = {
dbName : 'myNewDatabase',
colName : 'newCollection'
}
async function findDoc(cObj,fObj) {
const url = 'mongodb://localhost:27017';
const client = new MongoClient(url, { useNewUrlParser: true });
try {
await client.connect();
const db = client.db(cObj.dbName);
const col = db.collection(cObj.colName);
console.log(`Connection Made to ${db.databaseName} database.`);
const result = await col.find(fObj.field).limit(fObj.limit).toArray();
client.close();
return result;
} catch (err) {
console.log(err.stack);
}
};
findDoc(cObj,fObj).then(function(result) {
console.log(result);
});
Also, I advise you to enclose your whole async function's body into the try clause. This way you will be able to effectively intercept any error. Imagine your new MongoClient failed to instantiate - you would end up with an uncaught error inside a promise, which isn't very nice.