ChangeStream#destroy is not a method? - mongodb

I got this error:
app:tail-mongodb ERROR Unhandled rejection:
z.cs.destroy is not a function
TypeError: z.cs.destroy is not a function
at createChangeStream
(/Users/Olegzandr/codes/interos/read-from-mongodb/dist/main.js:74:18)
at process.internalTickCallback (internal/process/next_tick.js:77:7)
here is my code:
import {ChangeStream} from "mongodb";
const z = {
cs: null as ChangeStream,
};
const createChangeStream = () => {
if (z.cs) {
z.cs.removeAllListeners();
z.cs.destroy();
}
const changeStream = z.cs = d.db(dbName).collection(dbCollName).watch();
changeStream.on('change', next => {
if (!(next && next.fullDocument)) {
log.warn('changed doc did not have fullDocument property, or was undefined:', next);
}
bun.handleIn(next.fullDocument || next);
});
};
seems weird that destroy() is not a valid method on the ChangeStream. Does anyone know the proper way to close a ChangeStream? The TypeScript typings say that this method is available, but I guess it is not.

Related

When I try to override a core function in converse.js I get an error

I am using converse.js 7.0.6 version. I am trying to set the subject topic button to be by default hidden, currently, it is visible by default. I have investigated I need to override this function toggleSubjectHiddenState, when I try to use _converse.api.user. I get an error TypeError: Cannot read properties of undefined (reading 'user')
This is how I tried, maybe I am doing wrong something.
export const addModifyHideTopicPlugin = () => {
window.converse.plugins.add('modify-hide-topic', {
overrides: {
ChatRoom: {
toggleSubjectHiddenState: async function () {
const _converse: any = this;
// const muc_jid = this.get('jid');
const jids = await _converse.api.user.settings.get(
'mucs_with_hidden_subject',
[],
);
return _converse.toggleSubjectHiddenState
.apply(_converse, arguments)
.then((response: any) => {
console.log(response, 'response');
return response;
});
},
},
},
});
};
This is the toggleSubjectHiddenState function I am trying to override because this function is handleing the show topic or hide topic.
async toggleSubjectHiddenState () {
const muc_jid = this.get('jid');
const jids = await api.user.settings.get('mucs_with_hidden_subject', []);
if (jids.includes(this.get('jid'))) {
api.user.settings.set('mucs_with_hidden_subject', jids.filter(jid => jid !== muc_jid));
} else {
api.user.settings.set('mucs_with_hidden_subject', [...jids, muc_jid]);
}
},

Error: Cannot find module 'react-bootstrap/lib/Breadcrumb'

I am following this tutorial: https://youtu.be/YPbgjPPC1d0 at 34:55 I am trying to use "truffle test", but keep getting Error: Cannot find module 'react-bootstrap/lib/Breadcrumb'
My code:
const { should, assert } = require('chai')
const { useReducer } = require('react')
const { Item } = require('react-bootstrap/lib/Breadcrumb')
const color = artifacts.require('./color.sol')
require('Chair')
useReducer(require('chai-as-promised'))
should()
contract ('color', (accounts) => {
describe('deployment', async () => {
It('deploys successfully', async () => {
contract = await color.deployed()
const address = contract.address
console.log(address)
assert.notEqual(address, '')
})
})
})
I am using Virtual Studio Code
Has anyone had similar problem or know how to fix it? Thanks

Express/MongoDB - How to use res.render inside a try/catch block when sending requests to a databse

I'm making a poll app, and one of my routes is a GET request to get all the polls.
All i want to do is pass the polls to my dashboard view, and if there are no polls I want to pass the error to the dashboard view also.
I think my current implementation is wrong because if there are no polls the dashboard view receives an empty array not the errors.
I was curious what the best approach would be in this situation.
Thanks
router.get('/dashboard', isAuth, async (req, res) => {
try {
const polls = await Poll.find().populate('user', ['name', 'id']);
res.render('dashboard', {
polls
});
} catch(err) {
res.status(400);
res.render('dashboard', {
error: 'Could not find any polls'
});
}
});
You can throw error if polls is falsy/empty. Like this this:
const getType = element => Object.prototype.toString.call(element);
// Put this function in a helper file and use it throughout the source code
const isEmpty = element => {
if (
// undefined
typeof element === 'undefined' ||
// string
(typeof element === 'string' && element.trim().length == 0) ||
// null
getType(element) === '[object Null]' ||
// object
(getType(element) === '[object Object]' && !Object.keys(element).length) ||
// array
(getType(element) === '[object Array]' && !element.length)
) {
return true;
}
return false;
}
router.get('/dashboard', isAuth, async (req, res) => {
try {
const polls = await Poll.find().populate('user', ['name', 'id']);
if (isEmpty(polls)) {
throw new Error("Could not find any polls");
}
res.render('dashboard', {
polls
});
} catch (err) {
res.status(400);
res.render('dashboard', {
error: 'Could not find any polls'
});
}
});

object is probably 'undefined' - Mocha

I am using Protractor. The below solution works, but i get this warning:
this.currentTest.state
- error TS2532: Object is possibly 'undefined'
(property) Mocha.Context.currentTest?: Mocha.Test | undefined
How do i fix this warning?
Test file:
const helper = new HelperClass();
afterEach(async ()=> {
const state = this.currentTest.state;
await helper.getSource(state);
});
Class File
import { browser, } from 'protractor';
export class HelperClass {
public getSource(state:any) {
if (state === 'failed') {
browser.driver.getPageSource().then(function (res) {
console.log(res);
});
}
}
}
I think the error occurs because the access to this.currentTest.state happens inside another function: the arrow function passed in to afterEach--flow analysis does not cross function boundaries. Try simply pulling that line outside of the function:
const helper = new HelperClass();
afterEach(async ()=> {
const state = this.!currentTest.state;
await helper.getSource(state);
});
Does that change anything?

How can I wrap sails-mongo db methods for profiling?

I'm trying to setup a sails hook with miniprofiler to help profile mongo usage. I'm struggling for how to wrap the db methods in a function that will execute the profile. I'm trying to do this via a user hook:
setupMiniprofilerMongo(req, res, next) {
const adapter = sails.hooks.orm.datastores.default.adapter;
const adapterPrototype = Object.getPrototypeOf(adapter);
const originalMethod = adapter.adapter.find;
methodPrototype.find = function profiledMongoCommand(connectionName, collectionName, options, cb) {
sails.log.info(`${collectionName}.find`);
return originalMethod.call(adapter, connectionName, collectionName, options, cb);
};
}
That causes the following error to be thrown:
TypeError: Cannot read property 'collections' of undefined
at Object.module.exports.adapter.find (/Users/jgeurts/dev/platform/node_modules/sails-mongo/lib/adapter.js:349:40)
at Object.profiledMongoCommand [as find] (/Users/jgeurts/dev/platform/config/http.js:234:37)
Any help would be appreciated. I tried to wrap the methods on mongodb package, but that doesn't seem to work either. :/
I got this working by wrapping waterline query methods. There is room for improvement, though.
setupMiniprofilerWaterline(req, res, next) {
const dbOperations = [
'count',
'create',
'createEach',
'define',
'describe',
'destroy',
'drop',
'find',
'join',
// 'native',
// 'registerConnection',
'update',
];
const waterlineMethodByModels = {};
const miniprofilerWaterline = () => {
return {
name: 'mongodb',
handler(req, res, next) {
if (!req.miniprofiler || !req.miniprofiler.enabled) {
return next();
}
const profiler = req.miniprofiler;
for (const modelName of _.keys(sails.models)) {
for (const dbOperation of dbOperations) {
const model = sails.models[modelName];
if (!model[dbOperation]) {
continue;
}
if (!waterlineMethodByModels[modelName]) {
waterlineMethodByModels[modelName] = {};
}
// Prevent wrapping a method more than once
if (waterlineMethodByModels[modelName][dbOperation]) {
continue;
}
waterlineMethodByModels[modelName][dbOperation] = true;
const originalMethod = model[dbOperation];
model[dbOperation] = function profiledMongoCommand(...args) {
const query = args && args.length ? args[0] : '';
const lastArg = args && args.length ? args[args.length - 1] : null;
const modelAndMethod = `${modelName}.${dbOperation}`;
if (lastArg && typeof lastArg === 'function') {
sails.log.debug(`mongo::${modelAndMethod} - ${JSON.stringify(query)}`);
const callback = args.pop();
const timing = profiler.startTimeQuery('mongodb', query ? JSON.stringify(query || '') : '');
// In general, the callstack is kind of useless to us for these profiles
// The model/db method is more useful in the miniprofiler UI
timing.callStack = `\n\nMethod: ${modelAndMethod}`;
return originalMethod.call(this, ...args, function profiledResult(...results) {
profiler.stopTimeQuery(timing);
callback(...results);
});
}
const methodResult = originalMethod.call(this, ...args);
const methodResultPrototype = Object.getPrototypeOf(methodResult);
const isDeferred = !!methodResultPrototype.exec;
// If methodResult is a Deferred object type, then the query method will be profiled above when the deferred is executed (with a callback)
// So we only care to log this if the methodResult is not a deferred object
if (!isDeferred) {
sails.log.warn(`Was not able to profile mongo::${modelAndMethod}. Maybe its a promise? query: ${JSON.stringify(query)}`);
}
return methodResult;
};
}
}
next();
},
};
};
miniprofiler.express.for(miniprofilerWaterline())(req, res, next);
},
The code is available as miniprofiler-waterline if you want to contribute/use it in your own projects