I have an express application, and there are some situations in which the whole node process will fail, mostly on ReferenceError.
I am wondering if there is a way to set up Winston to handle node crashing, and logging the issue that shows up in my console.
For example, I can force my application to crash by putting in a reference to window, resulting in:
ReferenceError: window is not defined
How can I get winston to log this?
In my app.js, I have the following set up for Winston, but it does not work:
const winston = require('winston');
const logger = new (winston.Logger)({
transports: [
new (winston.transports.File)({
filename: `results.log`,
timestamp: true,
level: 'info',
json: true,
eol: 'n',
handleExceptions: true,
humanReadableUnhandledException: true
})
],
exitOnError: false
});
process.on('uncaughtException', function (error) {
console.log('error'); // doesn't log this,
});
Can someone help me out?
Basically, I am trying to log this error that comes up in my console if I make the app crash on purpose:
Listening on port 4200
EXCEPTION: Error in :0:0 caused by: window is not defined
ORIGINAL EXCEPTION: window is not defined
ORIGINAL STACKTRACE:
ReferenceError: window is not defined
at AppComponent.ngOnInit (/Users/test/universal/dist/server/server.bundle.js:2135:9)
at Wrapper_AppComponent.ngDoCheck (/AppModule/AppComponent/wrapper.ngfactory.js:22:53)
at CompiledTemplate.proxyViewClass.View_AppComponent_Host0.detectChangesInternal (/AppModule/AppComponent/host.ngfactory.js:31:26)
at CompiledTemplate.proxyViewClass.AppView.detectChanges (/Users/test/universal/node_modules/#angular/core/bundles/core.umd.js:9354:18)
at CompiledTemplate.proxyViewClass.DebugAppView.detectChanges (/Users/test/universal/node_modules/#angular/core/bundles/core.umd.js:9447:48)
at ViewRef_.detectChanges (/Users/test/universal/node_modules/#angular/core/bundles/core.umd.js:7337:24)
at /Users/test/universal/node_modules/#angular/core/bundles/core.umd.js:6588:88
at Array.forEach (native)
at ApplicationRef_.tick (/Users/test/universal/node_modules/#angular/core/bundles/core.umd.js:6588:42)
at ApplicationRef_._loadComponent (/Users/test/universal/node_modules/#angular/core/bundles/core.umd.js:6566:18)
ERROR CONTEXT:
DebugContext {
_view:
DebugAppView {
clazz: [Function: View_AppComponent_Host0],
componentType:
RenderComponentType {
id: '39',
templateUrl: '',
slotCount: 0,
encapsulation: 2,
styles: [],
animations: {} },
type: 0,
viewUtils:
ViewUtils {
_renderer: [Object],
_nextCompTypeId: 0,
sanitizer: DomSanitizerImpl {} },
parentView: null,
parentIndex: null,
parentElement: null,
cdMode: 4,
declaredViewContainer: null,
viewContainer: null,
numberOfChecks: 0,
ref: ViewRef_ { _view: [Circular], _originalMode: 2 },
renderer:
NodeDomRenderer {
_rootRenderer: [Object],
componentProto: [Object],
_animationDriver: _NoOpAnimationDriver {},
_styles: [],
_contentAttr: null,
_hostAttr: null,
__rootRenderer: [Object] },
_directRenderer: undefined,
staticNodeDebugInfos: [ [Object] ],
_currentDebugContext: [Circular],
context: {},
_hasExternalHostElement: true,
_hostInjector:
NgModuleInjector {
_parent: _NullComponentFactoryResolver {},
_factories: [Object],
parent: [Object],
bootstrapFactories: [Object],
_destroyListeners: [Object],
_destroyed: false,
_CommonModule_0: CommonModule {},
_ApplicationModule_1: ApplicationModule {},
_NodeModule_2: NodeModule {},
_NodeHttpModule_3: NodeHttpModule {},
_NodeJsonpModule_4: NodeJsonpModule {},
_UniversalModule_5: UniversalModule {},
_InternalFormsSharedModule_6: InternalFormsSharedModule {},
_FormsModule_7: FormsModule {},
_ModalModule_8: ModalModule {},
_CollapseModule_9: CollapseModule {},
_StoreModule_10: StoreModule {},
_EffectsModule_11: EffectsModule {},
_InfiniteScrollModule_12: InfiniteScrollModule {},
_PopoverModule_13: PopoverModule {},
_Token_ROUTER_FORROOT_GUARD_14: 'guarded',
_RouterModule_15: RouterModule {},
_CacheService_16: [Object],
_AppModule_17: [Object],
_ErrorHandler_20: [Object],
_ApplicationInitStatus_21: [Object],
_TestabilityRegistry_22: [Object],
_Testability_23: [Object],
_ApplicationRef__24: [Object],
_Token_Token__ngrx_store_reducer_62: [Function: reducers],
_Token_Token_ngrx_store_reducer_63: [Function: reducers],
__Dispatcher_60: [Object],
_Reducer_64: [Object],
_Token_Token__ngrx_store_initial_state_65: undefined,
_Token_Token_ngrx_store_initial_state_66: [Object],
_State_67: [Object],
_Store_68: [Object],
_EffectsSubscription_69: [Object],
__ApplicationRef_25: [Object],
__UrlSerializer_70: DefaultUrlSerializer {},
__RouterOutletMap_71: [Object],
__Token_ORIGIN_URL_44: 'localhost',
__Token_REQUEST_URL_45: '/',
__Token_appBaseHref_46: '/',
__PlatformLocation_47: [Object],
__Token_ROUTER_CONFIGURATION_72: {},
__LocationStrategy_73: [Object],
__Location_74: [Object],
__Compiler_26: [Object],
__NgModuleFactoryLoader_75: [Object],
__Token_ROUTES_76: [Object],
__Router_77: [Object],
__NoPreloading_78: NoPreloading {},
__PreloadingStrategy_79: NoPreloading {},
_RouterPreloader_80: [Object],
__ResponseOptions_54: [Object],
__BrowserXhr_52: [Function: _noop],
__XSRFStrategy_51: [Function: _noop],
__XHRBackend_55: [Object],
__RequestOptions_53: [Object],
__Http_56: [Object],
__HeaderPromotionsActions_94: HeaderPromotionsActions {},
_CheckoutFormService_98: [Object],
instance: [Object],
__NodeSharedStylesHost_28: [Object],
__Token_DocumentToken_29: [Object],
__NodeDomEventsPlugin_30: [Object],
__Token_HammerGestureConfig_31: [Object],
__Token_EventManagerPlugins_32: [Object],
__NodeEventManager_33: [Object],
__EventManager_34: [Object],
__AnimationDriver_35: _NoOpAnimationDriver {},
__NodeDomRootRenderer_36: [Object],
__DomRootRenderer_37: [Object],
__RootRenderer_38: [Object],
__DomSanitizer_39: DomSanitizerImpl {},
__Sanitizer_40: DomSanitizerImpl {},
__ViewUtils_41: [Object],
__AuthService_87: [Object],
__ProductActions_93: ProductActions {},
__ActivatedRoute_91: [Object],
__IterableDiffers_42: [Object],
__KeyValueDiffers_43: [Object] },
_hostProjectableNodes: [],
_el_0:
{ type: 'tag',
name: 'app-root',
namespace: 'http://www.w3.org/1999/xhtml',
attribs: [Object],
'x-attribsNamespace': {},
'x-attribsPrefix': {},
children: [Object],
parent: [Object],
prev: [Object],
next: [Object] },
_vc_0:
ViewContainer {
index: 0,
parentIndex: null,
parentView: [Circular],
nativeElement: [Object] },
compView_0:
DebugAppView {
clazz: [Function: View_AppComponent0],
componentType: [Object],
type: 1,
viewUtils: [Object],
parentView: [Circular],
parentIndex: 0,
parentElement: [Object],
cdMode: 2,
declaredViewContainer: null,
viewContainer: null,
numberOfChecks: 0,
ref: [Object],
renderer: [Object],
_directRenderer: undefined,
staticNodeDebugInfos: [Object],
_currentDebugContext: [Object],
_map_39: [Function],
_map_40: [Function],
_expr_41: [Object],
_map_42: [Function],
_expr_43: [Object],
_expr_44: [Object],
context: [Object],
_el_0: [Object],
_text_1: [Object],
_el_2: [Object],
_NgClass_2_3: [Object],
_text_3: [Object],
_el_4: [Object],
_NgClass_4_3: [Object],
_text_5: [Object],
_text_6: [Object],
_text_7: [Object],
_anchor_8: [Object],
_vc_8: [Object],
_TemplateRef_8_5: [Object],
_NgIf_8_6: [Object],
_text_9: [Object],
_el_10: [Object],
_NgClass_10_3: [Object],
_text_11: [Object],
_el_12: [Object],
_text_13: [Object],
_el_14: [Object],
_vc_14: [Object],
_RouterOutlet_14_5: [Object],
_text_15: [Object],
_text_16: [Object],
_el_17: [Object],
_text_18: [Object],
_anchor_19: [Object],
_vc_19: [Object],
_TemplateRef_19_5: [Object],
_NgIf_19_6: [Object],
_text_20: [Object],
_text_21: [Object],
_text_22: [Object],
_anchor_23: [Object],
_vc_23: [Object],
_TemplateRef_23_5: [Object],
_NgIf_23_6: [Object],
_text_24: [Object],
lastRootNode: null,
allNodes: [Object],
disposables: [Object] },
_AppComponent_0_5: Wrapper_AppComponent { _changed: false, _changes: {}, context: [Object] },
_el_1:
{ type: 'comment',
data: 'template bindings={}',
parent: null,
prev: null,
next: null },
lastRootNode:
{ type: 'comment',
data: 'template bindings={}',
parent: null,
prev: null,
next: null },
allNodes: [ [Object] ],
disposables: [ [Function: bound disposeInlineArray], [Function] ] },
_nodeIndex: 0,
_tplRow: 0,
_tplCol: 0 }
ReferenceError: window is not defined
at AppComponent.ngOnInit (/Users/test/universal/dist/server/server.bundle.js:2135:9)
at Wrapper_AppComponent.ngDoCheck (/AppModule/AppComponent/wrapper.ngfactory.js:22:53)
at CompiledTemplate.proxyViewClass.View_AppComponent_Host0.detectChangesInternal (/AppModule/AppComponent/host.ngfactory.js:31:26)
at CompiledTemplate.proxyViewClass.AppView.detectChanges (/Users/test/universal/node_modules/#angular/core/bundles/core.umd.js:9354:18)
at CompiledTemplate.proxyViewClass.DebugAppView.detectChanges (/Users/test/universal/node_modules/#angular/core/bundles/core.umd.js:9447:48)
at ViewRef_.detectChanges (/Users/test/universal/node_modules/#angular/core/bundles/core.umd.js:7337:24)
at /Users/test/universal/node_modules/#angular/core/bundles/core.umd.js:6588:88
at Array.forEach (native)
at ApplicationRef_.tick (/Users/test/universal/node_modules/#angular/core/bundles/core.umd.js:6588:42)
at ApplicationRef_._loadComponent (/Users/test/universal/node_modules/#angular/core/bundles/core.umd.js:6566:18)
Here's the full code from the express app (using angular-universal):
import './polyfills.ts';
import './__2.1.1.workaround.ts'; // temporary until 2.1.1 things are patched in Core
import * as path from 'path';
import * as express from 'express';
import * as compression from 'compression';
import { createEngine } from 'angular2-express-engine';
import { enableProdMode } from '#angular/core';
import { AppModule } from './app/app.module.node';
import { environment } from './environments/environment';
import { routes } from './server.routes';
const winston = require('winston');
const logger = new (winston.Logger)({
transports: [
new (winston.transports.File)({
filename: `results.log`,
timestamp: true,
level: 'info',
json: true,
eol: 'n',
handleExceptions: true,
humanReadableUnhandledException: true
})
],
exitOnError: false
});
process.on('uncaughtException', function (error) {
console.log('error'); // doesn't log this,
});
// App
const app = express();
const ROOT = path.join(path.resolve(__dirname, '..'));
const port = process.env.PORT || 4200;
/**
* enable prod mode for production environments
*/
if (environment.production) {
enableProdMode();
}
/**
* Express View
*/
app.engine('.html', createEngine({}));
app.set('views', path.join(ROOT, 'client'));
app.set('view engine', 'html');
/**
* Enable compression
*/
app.use(compression());
/**
* serve static files
*/
app.use('/', express.static(path.join(ROOT, 'client'), { index: false }));
const cache = {};
function ngApp(req, res) {
let baseUrl = '/';
let url = req.originalUrl || '/';
res.setHeader('Cache-Control', 'public, max-age=1000');
if (cache[url]) {
res.status(200).send(cache[url]);
return;
}
res.render('index', {
req,
res,
ngModule: AppModule,
preboot: {
appRoot: ['app-root'],
uglify: true,
buffer: true
},
async: false,
baseUrl: baseUrl,
requestUrl: req.originalUrl,
originUrl: req.hostname
},
(err, html) => {
cache[url] = html;
res.status(200).send(html);
});
}
/**
* use universal for specific routes
*/
app.get('/', ngApp);
routes.forEach(route => {
app.get(`/${route}`, ngApp);
app.get(`/${route}/*`, ngApp);
});
/**
* if you want to use universal for all routes, you can use the '*' wildcard
*/
app.get('*', function (req: any, res: any) {
res.setHeader('Content-Type', 'application/json');
const pojo = { status: 404, message: 'No Content' };
const json = JSON.stringify(pojo, null, 2);
res.status(404).send(json);
});
app.listen(port, () => {
console.log(`Listening on port ${port}`);
});
Since my original answer didn't help, I ran your code and it properly logged uncaught exceptions with the following modification:
process.on('uncaughtException', function (error) {
logger.log("error", "qqq")
console.log('error'); // just prints the word 'error',
});
Related
When I try to refer to db.startSession () I have an error db.startSession () is not a function. In console.log I put db and I put logged variable below. Why can't I refer to startSession()?
connection
module.exports.db = mongoose
.createConnection(process.env.DATABASE, {
useNewUrlParser: true,
useFindAndModify: false,
useUnifiedTopology: true,
useCreateIndex: true
}
);
controller
const db = require('./connection');
const session = db.startSession();
session.startTransaction();
logged variable db
{
db: NativeConnection {
base: Mongoose {
connections: [Array],
models: [Object],
modelSchemas: [Object],
options: [Object],
_pluralize: [Function: pluralize],
plugins: [Array]
},
collections: {},
models: {},
config: { autoIndex: true },
replica: false,
options: null,
otherDbs: [],
relatedDbs: {},
states: [Object: null prototype] {
'0': 'disconnected',
'1': 'connected',
'2': 'connecting',
'3': 'disconnecting',
'99': 'uninitialized',
disconnected: 0,
connected: 1,
connecting: 2,
disconnecting: 3,
uninitialized: 99
},
_readyState: 1,
_closeCalled: false,
_hasOpened: true,
_listening: false,
_connectionOptions: {
useNewUrlParser: true,
useFindAndModify: false,
useUnifiedTopology: true,
useCreateIndex: true,
promiseLibrary: [Function: Promise]
},
client: MongoClient {
_events: [Object: null prototype] {},
_eventsCount: 0,
_maxListeners: undefined,
s: [Object],
topology: [ReplSet],
[Symbol(kCapture)]: false
},
name: null,
'$initialConnection': Promise { [Circular] },
db: Db {
_events: [Object: null prototype],
_eventsCount: 3,
_maxListeners: undefined,
s: [Object],
serverConfig: [Getter],
bufferMaxEntries: [Getter],
databaseName: [Getter],
[Symbol(kCapture)]: false
}
}
}
you can do like this for using transaction in mongoose:
Note:for using transaction you need to replica mongodb, so you should Convert a Standalone to a Replica Set, and need to add retryWrites: false as argument in mongoose.createConnection()
connect to mongoose :
await mongoose.connect(`mongodb://localhost/namedb`, {
useNewUrlParser: true,
useUnifiedTopology: true,
useCreateIndex: true,
retryWrites: false
});
const mongoose = require("mongoose");
const sess = await mongoose.startSession();
sess.startTransaction();
await teacher.save({ session: sess }); // a query
student.messeges.push(); // do somthing
await student.save({ session: sess }); //// a query
await sess.commitTransaction();
for using replica set in localhost you should stop mongod service and run this code
mongod --port 27017 --dbpath C:\data\rs1 --replSet m101 --bind_ip localhost
C:\data\rs1 data stored path
rs.initiate()
This question already has answers here:
How to Deep clone in javascript
(25 answers)
Closed 3 years ago.
Pardon the title, I have no idea how to describe this. I have a problem where my code changes variables it has no business changing, and I can't figure out why.
The code:
getCalendar (parameters, callback) {
var returnData = this.calendars
// If limit parameter is set, remove all but n events
if (parameters.limit) {
returnData.forEach((calendar) => {
calendar.events = calendar.events.slice(0, parameters.limit)
})
}
callback(returnData)
}
this.calendars is filled with the data shown below.
The code is supposed to return a copy of this.calendars, with the number of events limited by parameters.limit. This does work as intended, but this code also removes events from this.calendars somehow. So if I run the code with parameters.limit set to 3, and then again with parameters.limit set to 5, it will return 3 events both times.
This is a node app if it matters.
this.calendars
[
{
id: '5e29843erkjfassfv1h8#group.calendar.google.com',
lastUpdate: '2019-09-18T10:16:32+02:00',
summary: 'Calendar1',
description: 'Description',
timeZone: 'Europe/Oslo',
updated: '2019-09-11T00:09:34.954Z',
events: [ [Object] ]
},
{
id: 'd3llqgg43irfkcf8pjfe8#group.calendar.google.com',
lastUpdate: '2019-09-18T10:16:32+02:00',
summary: 'Calendar 2',
description: 'Description',
timeZone: 'Europe/Oslo',
updated: '2019-09-16T16:36:41.373Z',
events: [
[Object], [Object], [Object],
[Object], [Object], [Object],
[Object], [Object], [Object],
[Object], [Object], [Object],
[Object], [Object], [Object],
[Object], [Object], [Object],
[Object], [Object], [Object],
[Object], [Object], [Object],
[Object], [Object], [Object],
[Object], [Object], [Object]
]
}
]
You are creating a shallow copy of this.calendars, so when you change returnData it mutates this.calendars also. Try this.
var returnData = JSON.parse(JSON.stringify(this.calendars))
In document it is quite simple to do, but using selenium pack to get variable from website is problematic (as I need to now). The problem is that console.log() returns it as an object without parameters I want (that can be seen, exactly the number of clients as string/int (after removing /).
var webdriver = require('selenium-webdriver'),
By = webdriver.By,
until = webdriver.until;
var driver = new webdriver.Builder()
.forBrowser('firefox')
.build();
var number;
driver.get('the website');
number = driver.findElement(By.xpath('/html/body/table/tbody/tr[4]/td[2]/table/tbody/tr/td[1]/table/tbody/tr[15]/td[2]')); //.toString is not working either, valueof too
console.log(number);
HTML of the page and string I am looking for
And what I get from console.log
[ thenableWebDriverProxy {
flow_:
ControlFlow {
propagateUnhandledRejections_: true,
activeQueue_: [Object],
taskQueues_: [Object],
shutdownTask_: null,
hold_: [Object] },
session_:
ManagedPromise {
flow_: [Object],
stack_: null,
parent_: [Object],
callbacks_: [Object],
state_: 'blocked',
handled_: true,
value_: undefined,
queue_: null },
executor_: Executor { w3c: false, customCommands_: [Object], log_: [Object] },
fileDetector_: null,
onQuit_: [Function: onQuit],
cancel: [Function],
then: [Function: bound then],
catch: [Function: bound then] },
ManagedPromise {
flow_:
ControlFlow {
propagateUnhandledRejections_: true,
activeQueue_: [Object],
taskQueues_: [Object],
shutdownTask_: null,
hold_: [Object] },
stack_: null,
parent_: null,
callbacks_: null,
state_: 'fulfilled',
handled_: false,
value_: 'unused',
queue_:
TaskQueue {
name_: 'TaskQueue::3',
flow_: [Object],
tasks_: [Object],
interrupts_: null,
pending_: null,
subQ_: null,
state_: 'new',
unhandledRejections_: Set {} } },
[Function],
[Function: bound then],
[Function: bound catch],
[Function] ]
Output after using console.log(number.getText());
ManagedPromise {
flow_:
ControlFlow {
propagateUnhandledRejections_: true,
activeQueue_:
TaskQueue {
name_: 'TaskQueue::3',
flow_: [Circular],
tasks_: [Object],
interrupts_: null,
pending_: null,
subQ_: null,
state_: 'new',
unhandledRejections_: Set {} },
taskQueues_: Set { [Object] },
shutdownTask_: null,
hold_:
Timeout {
_called: false,
_idleTimeout: 2147483647,
_idlePrev: [Object],
_idleNext: [Object],
_idleStart: 431,
_onTimeout: [Function],
_timerArgs: undefined,
_repeat: 2147483647 } },
stack_:
{ Task: WebElement.getText()
at thenableWebDriverProxy.schedule (/home/soda/node_modules/selenium-webdriver/lib/webdriver.js:816:17)
at WebElementPromise.schedule_ (/home/soda/node_modules/selenium-webdriver/lib/webdriver.js:1921:25)
at WebElementPromise.getText (/home/soda/node_modules/selenium-webdriver/lib/webdriver.js:2185:17)
at getNumber (/home/soda/main.js:15:24)
at Object.<anonymous> (/home/soda/main.js:19:1)
at Module._compile (module.js:573:32)
at Object.Module._extensions..js (module.js:582:10)
at Module.load (module.js:490:32)
at tryModuleLoad (module.js:449:12)
at Function.Module._load (module.js:441:3) name: 'Task' },
parent_: null,
callbacks_: null,
state_: 'pending',
handled_: false,
value_: undefined,
queue_: null }
number is WebElement, when you use toString() you get the object string, not the text. For the text use getText()
number = driver.findElement(By.xpath('/html/body/table/tbody/tr[4]/td[2]/table/tbody/tr/td[1]/table/tbody/tr[15]/td[2]')).getText();
console.log(number);
.getText() returns a promise, so in order to get the text you need to extract the value from the promise using .then();
number = driver.findElement(By.xpath('/html/body/table/tbody/tr[4]/td[2]/table/tbody/tr/td[1]/table/tbody/tr[15]/td[2]')); //.toString is not working either, valueof too
number.then(function(text){
console.log(text); //this will log the actual text.
});
I'm pretty new in Node.js and I have this project. Basically I have some data sits in a mongoDB collection("data") and I'm trying to get that data and display it on the browser.
Here is what I've got so far;
var MongoClient = require('mongodb').MongoClient
,format = require('util').format;
var sys = require ("sys");
my_http = require("http");
my_http.createServer(function(request, response){
sys.puts("Touched !!");
response.writeHeader(200, {"Content-Type": "text/plain"});
response.write(extractData()).toString();
response.end();
}).listen(8080);
sys.puts("Server is running on 8080"); // Server kicks in...np
function extractData(){
MongoClient.connect('mongodb://127.0.0.1:27017/mongoDB', function(err, db){
if (err){
console.log("Can't Connect to DB !!");
}else {
console.log("Connected to DB !!"); // connects to DB, np
db.data.find({}, function(err, data){ // .find is the problem
if (err || !data) console.log("No Data Found");
else data.forEach(function (data){
console.log(data);
});
}).toArray();
}
});
}
And after I run "node server.js" and refresh the already open localhost:8080, I get this;
Server is running on 8080
Touched !!
Touched !!
Connected to DB !!
d:\Projects\SCRIPTS\mdp.scripts.testing-tools\jsFinderWmongoDB\node_modules\mongodb\lib\mongodb\mongo_client.js:475
throw err
^
TypeError: Cannot call method 'find' of undefined
at d:\Projects\SCRIPTS\mdp.scripts.testing-tools\jsFinderWmongoDB\server.js:21:21
at d:\Projects\SCRIPTS\mdp.scripts.testing-tools\jsFinderWmongoDB\node_modules\mongodb\lib\mongodb\mongo_client.js:4
72:11
at process._tickCallback (node.js:415:13)
Don't understand why there is a problem with .find() and of course can't display any data...
Any ideas?
Edit:
Well, we are certainly getting somewhere. I've made some changes.
Current code:
function extractData(){
MongoClient.connect('mongodb://127.0.0.1:27017/mongoDB', function(err, db){
if (err){
console.log("Can't Connect to DB !!");
}else {
sys.puts("Connected to DB !!"); // connects to DB, np
db.collection('data').find({}, function(err, data){
if (err || !data) console.log("No Data Found");
//else db.collection('data').forEach(function (data){
// console.log(data);
//});
});//.toArray();
}
});
}
Browser response is "undefined"
I'm guessing "extractData" function is NOT returning something legit. Therefore the collection set "data" is returning empty.
And yes I've checked one more time, I have data in the dataset.
You need to set a collection to use before you can do anything with it.
var collection = db.collection('data');
collection.find({},function(err,data){
console.log(data);
});
Would be how you do it.
Update ** This was how I did my first mongoDB stuff using express
Might help you.
var mongo = require('mongodb');
var monk = require('monk');
var db = monk('localhost:27017/nodetest1');
app.get('/userlist', function(req, res) {
var db = req.db;
var collection = db.get('usercollection');
collection.find({},{},function(e,docs){
res.render('userlist', {
"userlist" : docs
});
});
});
I get the details about the stored data when do console.log(data);
Here is a glimpse of it
Server is running on 8080
Touched !!
Connected to DB !!
{ db:
{ domain: null,
_events: {},
_maxListeners: 10,
databaseName: 'mongoDB',
serverConfig:
{ domain: null,
_events: {},
_maxListeners: 10,
auth: [Getter],
_callBackStore: [Object],
_commandsStore: [Object],
_dbStore: [Object],
host: '127.0.0.1',
port: 27017,
options: [Object],
internalMaster: true,
connected: true,
poolSize: 5,
disableDriverBSONSizeCheck: false,
_used: true,
replicasetInstance: null,
emitOpen: false,
ssl: false,
sslValidate: false,
sslCA: null,
sslCert: undefined,
sslKey: undefined,
sslPass: undefined,
serverCapabilities: [Object],
name: '127.0.0.1:27017',
socketOptions: [Object],
logger: [Object],
eventHandlers: [Object],
_serverState: 'connected',
_state: [Object],
recordQueryStats: false,
socketTimeoutMS: [Getter/Setter],
_readPreference: [Object],
db: [Circular],
dbInstances: [Object],
connectionPool: [Object],
isMasterDoc: [Object] },
options:
{ read_preference_tags: null,
read_preference: 'primary',
url: 'mongodb://127.0.0.1:27017/mongoDB',
native_parser: true,
readPreference: [Object],
safe: false,
w: 1 },
_applicationClosed: false,
slaveOk: false,
bufferMaxEntries: -1,
native_parser: true,
bsonLib:
{ BSON: [Object],
Long: [Object],
ObjectID: [Object],
DBRef: [Object],
Code: [Object],
Timestamp: [Object],
Binary: [Object],
Double: [Object],
MaxKey: [Object],
MinKey: [Object],
Symbol: [Object] },
bson: { promoteLongs: true },
bson_deserializer:
{ Code: [Object],
Symbol: [Object],
BSON: [Object],
DBRef: [Object],
Binary: [Object],
ObjectID: [Object],
Long: [Object],
Timestamp: [Object],
Double: [Object],
MinKey: [Object],
MaxKey: [Object],
promoteLongs: true },
bson_serializer:
{ Code: [Object],
Symbol: [Object],
BSON: [Object],
DBRef: [Object],
Binary: [Object],
ObjectID: [Object],
Long: [Object],
Timestamp: [Object],
Double: [Object],
MinKey: [Object],
MaxKey: [Object],
promoteLongs: true },
_state: 'connected',
pkFactory:
{ [Function: ObjectID]
index: 16043018,
createPk: [Function: createPk],
createFromTime: [Function: createFromTime],
createFromHexString: [Function: createFromHexString],
isValid: [Function: isValid],
ObjectID: [Circular],
ObjectId: [Circular] },
forceServerObjectId: false,
safe: false,
notReplied: {},
isInitializing: true,
openCalled: true,
commands: [],
logger: { error: [Function], log: [Function], debug: [Function] },
tag: 1425061857066,
eventHandlers:
{ error: [],
parseError: [],
poolReady: [],
message: [],
close: [] },
serializeFunctions: false,
raw: false,
recordQueryStats: false,
retryMiliSeconds: 1000,
numberOfRetries: 60,
readPreference: { _type: 'ReadPreference', mode: 'primary', tags: undefined } },
collection:
I try to build a chat room webpage with node.js/express/redis on the server side.
Following this snips of code : A Message Wall With Long Poll Properties in Node.JS and Express , I succeed to make one node server running correctly. In this example, the res objects are saved in a list, no any transformation is needed.
But I want to run the node app with pm2 cluster mode(-i 4), so I have to save res object into some place that shared between 4 nodes.
I already used redis in my node project, for the express.session. So I want to cache res into redis.
But the problem occured: when I try to sting-lized res object with JSON.stringify(res), I got :
TypeError: Converting circular structure to JSON
My problem is:
how could I save one res object for later use across node cluster, with redis or something else.
Appreciate.
I use util.inspect to print out my container of res (chatroom_id:res) object:
{ '0': null,
'1390640136999':
{ domain: null,
_events:
{ finish: [Object],
header: [Function],
close: [Function: logRequest] },
_maxListeners: 10,
output: [],
outputEncodings: [],
writable: true,
_last: false,
chunkedEncoding: false,
shouldKeepAlive: false,
useChunkedEncodingByDefault: false,
sendDate: true,
_headerSent: false,
_header: '',
_hasBody: true,
_trailer: '',
finished: false,
_hangupClose: false,
socket:
{ _connecting: false,
_handle: [Object],
_readableState: [Object],
readable: true,
domain: null,
_events: [Object],
_maxListeners: 10,
_writableState: [Object],
writable: true,
allowHalfOpen: true,
onend: [Function],
destroyed: false,
errorEmitted: false,
bytesRead: 894,
_bytesDispatched: 0,
_pendingData: null,
_pendingEncoding: '',
server: [Object],
_idleTimeout: 120000,
_idleNext: [Object],
_idlePrev: [Object],
_idleStart: 1390640145289,
parser: [Object],
ondata: [Function],
_paused: false,
_httpMessage: [Circular],
_peername: [Object] },
connection:
{ _connecting: false,
_handle: [Object],
_readableState: [Object],
readable: true,
domain: null,
_events: [Object],
_maxListeners: 10,
_writableState: [Object],
writable: true,
allowHalfOpen: true,
onend: [Function],
destroyed: false,
errorEmitted: false,
bytesRead: 894,
_bytesDispatched: 0,
_pendingData: null,
_pendingEncoding: '',
server: [Object],
_idleTimeout: 120000,
_idleNext: [Object],
_idlePrev: [Object],
_idleStart: 1390640145289,
parser: [Object],
ondata: [Function],
_paused: false,
_httpMessage: [Circular],
_peername: [Object] },
_headers: { 'x-powered-by': 'Express' },
_headerNames: { 'x-powered-by': 'X-Powered-By' },
req:
{ _readableState: [Object],
readable: true,
domain: null,
_events: {},
_maxListeners: 10,
socket: [Object],
connection: [Object],
httpVersion: '1.0',
complete: true,
headers: [Object],
trailers: {},
_pendings: [],
_pendingIndex: 0,
url: '/robot/chat/query/99/1390640136999/270125/',
method: 'GET',
statusCode: null,
client: [Object],
_consuming: false,
_dumped: false,
httpVersionMajor: 1,
httpVersionMinor: 0,
upgrade: false,
originalUrl: '/robot/chat/query/99/1390640136999/270125/',
_parsedUrl: [Object],
query: {},
res: [Circular],
next: [Function: next],
secret: undefined,
cookies: [Object],
signedCookies: {},
sessionStore: [Object],
sessionID: '4PACUldyCHhT8NgdGY1yz9Pk',
session: [Object],
_startTime: Sat Jan 25 2014 16:55:45 GMT+0800 (CST),
_remoteAddress: '127.0.0.1',
body: {},
originalMethod: 'GET',
_route_index: 2,
route: [Object],
params: [Object] },
locals: [Function: locals],
end: [Function],
student_id: '99',
channel_id: '1390640136999',
last_msg_id: '270125' } }
There are three [Circular].
My pseudocode:
/*
* query from http client
* url: /chat/query/:student_id/:channel_id/:last_msg_id/
*/
exports.query = function(req, res){
// if find some new msg
// return them as json, immediately
// else
// set participator info into res object
// read the res_list from redis
// put this res into res_list
// write back res_list into redis
};
/*
* notification from other web server: one new msg been created
* url: /chat/notify/:new_msg_id/
*/
exports.notify = function(req, res){
// get new_msg from database by id
// read the res_list from redis
// for old_res in res_list
// if this old_res is releated with the new_msg (participator)
// old_res.sent(json_content)
// remove this old_res from res_list
// write back res_list into redis
};
how could i implement those 'read-and-write-back' part?
The short answer: it's not possible to put the res object into a cache and obtain it again from another process, in any meaningful way.
If you think about how long poll works, each HTTP client maintains an open connection to the server, waiting (a long time) for something to be sent back. In other words, when you come to push out new messages, you're just sending data down an already open connection. If you cache your res into redis, what would happen to the connection?
It may not matter though, as long as you have a way to pass the content between your 4 backend processes, they can each update their own set of res connections. New connections would still be load balanced.