Mongoose's default promise library is deprecated in MEAN stack - javascript

I'm trying to start a MEAN-stack server, however I'm getting this error msg:
Mongoose: mpromise (mongoose's default promise library) is deprecated, plug in your own promise library instead: http://mongoosejs.com/docs/promises.html
I tried to search some answers here but the one that I found wasn't clear enough for me:
(node:3341) DeprecationWarning: Mongoose: mpromise
I found the file calling the mongoose.connect, but the codes on that issue didn't work for me, can anyone explain for me how it works?

use this code,before the mongo connection and this will resolve the promise problem.
mongoose.Promise = global.Promise;

The way I usually connect to MongoDB is by using the Bluebird promise library. You can read more about it in this post. With any luck, this snippet below will help you get started, as it is what I use when prototyping.
let mongoose = require('mongoose');
let promise = require('bluebird');
let uri = 'mongodb://localhost:27017/your_db';
mongoose.Promise = promise;
let connection = mongoose.createConnection(uri);

Latest mongoose library, do not use any default promise library. And from Mongoose v 4.1.0 you can plug in your own library.
If you are using mongoose library(not underlying MongoDB driver) then you can plug in promise library like this:
//using Native Promise (Available in ES6)
mongoose.Promise = global.Promise;
//Or any other promise library
mongoose.Promise = require('bluebird');
//Now create query Promise
var query = someModel.find(queryObject);
var promise = query.exec();
If you are using MongoDB Driver then you will need to do some extra effort. Because, mongoose.Promise sets the Promise that mongoose uses not the driver. You can use the below code in this case.
// Use bluebird
var options = { promiseLibrary: require('bluebird') };
var db = mongoose.createConnection(uri, options);

Work for me.
Mongoose v4.11.7 resolve the promise problem
const mongoose = require('mongoose');
mongoose.Promise = global.Promise;
mongoose.connection.openUri('mongodb://127.0.0.1:27017/app_db', { /* options */ });
Mongoose #save()
var article = new Article(Obj);
article.save().then(function(result) {
return res.status(201).json({
message: 'Saved message',
obj: result
});
}, function (err) {
if (err) {
return res.status(500).json({
title: 'Ac error occurred',
error: err
});
}
});

Related

Is it necessary to put async in bluebird promises

I am trying to add bluebird promises in the project. I am using NodeJS, Express, Mongodb. This is my sample model file
const mongoose = require('mongoose')
// Blue Bird
mongoose.Promise = require('bluebird')
const schema = mongoose.SchemaAsync
const acModel = new schema({
// Schema here
}
})
module.exports = mongoose.modelAsync('myModel', acModel)
But is it necessary to put Async everywhere? For example SchemaAsync, modelAsync
I don't think you need to add Async at every call.
mongoose.Promise = require('bluebird');
User.findOne({}).then(function(user){
});
I guess you need to add async when you do this
Promise.promisifyAll(require("mongoose"));
Actually if you use async await you end up using the standard Promise object instead of bluebird

Redis use sync/await keywords on

I am new in the JS world, I am creating a query cache and I decide to use redis to cache the information, but I want to know if there is a way to use async/await keywords on the get function of redis.
const redis = require('redis');
const redisUrl = 'redis://127.0.0.1:6379';
const client = redis.createClient(redisUrl);
client.set('colors',JSON.stringify({red: 'rojo'}))
client.get('colors', (err, value) => {
this.values = JSON.parse(value)
})
I want to know if I can use the await keyword instead of a callback function in the get function.
You can use util node package to promisify the get function of the client redis.
const util = require('util');
client.get = util.promisify(client.get);
const redis = require('redis');
const redisUrl = 'redis://127.0.0.1:6379';
const client = redis.createClient(redisUrl);
client.set('colors',JSON.stringify({red: 'rojo'}))
const value = await client.get('colors')
With the util package i modified the get function to return a promise.
This is from redis package npm official documentation
Promises - You can also use node_redis with promises by promisifying node_redis with bluebird as in:
var redis = require('redis');
bluebird.promisifyAll(redis.RedisClient.prototype);
bluebird.promisifyAll(redis.Multi.prototype);
It'll add a Async to all node_redis functions (e.g. return client.getAsync().then())
// We expect a value 'foo': 'bar' to be present
// So instead of writing client.get('foo', cb); you have to write:
return client.getAsync('foo').then(function(res) {
console.log(res); // => 'bar'
});
// Using multi with promises looks like:
return client.multi().get('foo').execAsync().then(function(res) {
console.log(res); // => 'bar'
});
This example uses bluebird promisify read more here
So after you promsified a get to 'getAsync' you can use it in async await
so in your case
const value = await client.getAsync('colors');
For TypeScript users both util.promisify and bluebird.promisifyAll aren't ideal due to lack of type support.
The most elegant in TypeScript seems to be handy-redis, which comes with promise support and first-class TypeScript bindings. The types are generated directly from the official Redis documentation, i.e., should be very accurate.

Passing argument with dependency injection

I have function in unbound.js with the the following code
export default async function connect({ mongoose: mongoose }, URI) {
console.log('in connect');
mongoose.connect(URI);
mongoose.Promise = global.Promise;
});
}
I then have another index.js to deal with dependency injection which looks like this
module.exports = async url => {
return await require("./unbound").default.bind(
null,
{
mongoose: require("mongoose")
},
url
);
};
The only thing I am doing different to plain vanilla dependency injection is to pass the URL as an argument.
When I call the export from index.js I get no response. This is confirmed by console.lognot outputting
Any guidance on how I could resolve this ?
Since chat restricted, I'm gonna post the answer here instead.
In this snippet, you export a function that when invoked, return another function
module.exports = async url => {
return await require("./unbound").default.bind(
null,
{
mongoose: require("mongoose")
},
url
);
};
So if you want to actually run it, you have to invoke it twice like require('./')()() for example
As others have suggested, bind returns a bound function that you can call, it does not actually call the function - that is what .apply or .call does. #ptdien's solution is somewhat correct, but it won't work because you've forgotten to return the promise that mongoose.connect returns so your connect function returns undefined, so there is nothing the the caller to await. I.e. you need to do this:
export default function connect({ mongoose: mongoose }, url) {
mongoose.Promise = global.Promise;
return mongoose.connect(url);
}
(Also note that I've removed the async keyword as that is not necessary when we are not using await - the code returns a promise already.
Also, bind will automatically forward arguments after the bound ones (i.e the url in this case), so you can simplify your code to this:
module.exports = require("./unbound").default.bind(
null,
{
mongoose: require("mongoose")
}
);
By the way, the reason you have to append .default is because you are mixing node.js requires and ES6 imports. Pick one and stick to it.

Can this usage of native JS Promise result in memory leak in Node.js?

Here is a sample representation of the code I have. I have a UDP receiver which receives a very high volume of packets continuously. It is stock market live data. That should give some idea about the packet volume.
Based on the data received, an update goes to a Mysql DB and another one to MongoDB. This code however leaks memory like anything and within about 12 minutes crashes with OOM error on an EC2 machine with 7.5GB RAM. This crash is very consistent.
I read several stackoverflow questions and github issues about memory leaks related to Promise chaining or recursively calling Promises. I felt my code did not fit that description and hence want to know if this code will also lead to a memory leak.
When I changed this entire code to work without Promises and only callbacks, memory consumption is close to just 1%. No leak at all.
I am using the current stable version of Node.js (v6.9.5 LTS). Using native Promises, no library like Bluebird etc.
const dgram = require('dgram');
const receiver = dgram.createSocket('udp4');
const myObject = require('./myObject.js');
receiver.on('message', function(payload, sender) {
myObject.processPayload(payload);
});
receiver.bind(PORT);
// In mObject.js
var myObject = {
processPayload: function(payload) {
var updateDoc = doSomethingToPayload(payload);
// Mongo npm package offers APIs which return a Promise
var promise1 = this.mongoClient.collection('coll1').update(updateDoc);
var promise2 = this.getMysqlPromise(updateDoc);
Promise.all([promise1, promise2]).then(function(values) {
doSomethingElse();
}).catch(function(err) {
doErrorHandling();
});
},
// The mysql npm package does not offer APIs which return a Promise. Hence creating a Promise myself.
// The mysql2 package does. Tried that too and the same memory leak exists.
getMysqlPromise: function(updateDoc) {
var queryStatement = buildQueryFromUpdateDoc(updateDoc);
var self = this;
var promise = new Promise(function(resolve, reject) {
self.MysqlDB.query(queryStatement, function(err, results, fields) {
if (err) {
reject(err);
return;
}
resolve(results);
});
});
return promise;
}
}

Node - ReferenceError: Promise is not defined

I am starting out with Node. Sorry for what probably is a stupid question.
Trying to understand why the below code throws an error: ReferenceError: Promise is not defined
allAccountFixtures: ['account-customer-joe', 'account-partner-sam', 'account-partner-jane', 'account-admin-jill'],
allProductFixtures: ['product-123', 'product-234', 'product-345', 'product-456'],
...
loadBasicFixtures: (Api) => {
return Promise.all([
Support.importRecords(Api.accountsAPI, Support.allAccountFixtures),
Support.importRecords(Api.productsAPI, Support.allProductFixtures)
]);
},
My APIs are defined elsewhere as:
this.accountsAPI = app.service('/api/accounts');
this.productsAPI = app.service('/api/products');
The import function is:
importRecords: (feathersService, fixtureNames) => {
// Wrap in an array if there's only one.
if (!(fixtureNames instanceof Array)) { fixtureNames = [fixtureNames]; }
// Create a separate promise for each JSON fixture to load the JSON from a
// file and send it to feathers.create(). Don't execute yet.
var promises = fixtureNames.map(fixtureName => {
var filePath = `test/fixtures/json/${fixtureName}.json`;
// console.log(`-> Loading JSON fixture: ${filePath}`);
return fs.readFileAsync(filePath, 'utf8')
.then((jsonString) => {
return JSON.parse(jsonString);
}).then((json) => {
return feathersService.create(json);
});
});
// Wrap all fixture loading promises inside a single outer promise that will
// fire when all of the child promises are complete.
return Promise.all(promises);
},
Don't know whether the supplied information is sufficient to advise what is happening. I looked up the concept of a "promise" and that's pretty much it. Perhaps you could point to the right direction. The documentation mentions resolve and reject.
I'll make my comment into an answer since it solved your issue.
Some older versions of node.js do not have promises built-in and to use promises with them requires loading a third party library that adds promise support.
If you upgrade to any 4.x version of node.js or newer, you will have promises built-in to node.js.
You need to import and require Promise
npm install promise --save
Then
var Promise = require('promise');

Categories

Resources