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:
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()
MySQL runs fine with simple callbacks, but I want to run multiple mysql queries asynchronously in express node.js, for that I am using async await with promise.all. I also tried using promise.allSettled, but it still gives the same error.
Here is the complete code.
dbConn.js
var config = require('../config');
var conn = (module.exports = require("mysql").createConnection({
host: config.dbHost,
user: config.dbUser,
port: config.dbPort,
password: config.dbPassword,
database: config.dbName,
}));
conn.connect(err => {
if (err) {
return console.log(err.stack);
} else {
return console.log("Connected!");
}
});
Route File.
var conn = require('../DB/dbConn');
router.get('/search',async function(req, res, next) {
try {
const CourseContent = await conn.query( "SELECT cd.*,s.*,u.* from coursesdetails cd,subjects s,universities u where cd.subjectId = s.subjectId and u.universityId = cd.universityId and s.subjectNameEn like '%Art%';" );
const Allsubjects = await conn.query("select * from subjects;");
const AllCountries = await conn.query("SELECT distinct Country from worldcities;");
const AllDisciplines = await conn.query("select * from discipline;");
const promises = [CourseContent,Allsubjects,AllCountries,AllDisciplines];
Promise.all(promises).then((results) => {
console.log(results);
res.render('search', { results: results,layout: 'layouts/index-layout' });
}).catch((error)=> {console.log(error);})
} catch (error) {
console.error(error);
}
});
response From Promise.all results
[
Query {
_events: [Object: null prototype] {
error: [Function],
packet: [Function],
timeout: [Function],
end: [Function]
},
_eventsCount: 4,
_maxListeners: undefined,
_callback: undefined,
_callSite: Error
at Protocol._enqueue (C:\Users\myste\Documents\Office Work\FindCoursesNode.js\node_modules\mysql\lib\protocol\Protocol.js:144:48)
at Connection.query (C:\Users\myste\Documents\Office Work\FindCoursesNode.js\node_modules\mysql\lib\Connection.js:198:25)
at C:\Users\myste\Documents\Office Work\FindCoursesNode.js\routes\course.js:58:38
at Layer.handle [as handle_request] (C:\Users\myste\Documents\Office Work\FindCoursesNode.js\node_modules\express\lib\router\layer.js:95:5)
at next (C:\Users\myste\Documents\Office Work\FindCoursesNode.js\node_modules\express\lib\router\route.js:137:13)
at Route.dispatch (C:\Users\myste\Documents\Office Work\FindCoursesNode.js\node_modules\express\lib\router\route.js:112:3)
at Layer.handle [as handle_request] (C:\Users\myste\Documents\Office Work\FindCoursesNode.js\node_modules\express\lib\router\layer.js:95:5)
at C:\Users\myste\Documents\Office Work\FindCoursesNode.js\node_modules\express\lib\router\index.js:281:22
at Function.process_params (C:\Users\myste\Documents\Office Work\FindCoursesNode.js\node_modules\express\lib\router\index.js:335:12)
at next (C:\Users\myste\Documents\Office Work\FindCoursesNode.js\node_modules\express\lib\router\index.js:275:10),
_ended: false,
_timeout: undefined,
_timer: Timer { _object: [Circular], _timeout: null },
sql: "SELECT cd.*,s.*,u.* from coursesdetails cd,subjects s,universities u where cd.subjectId = s.subjectId and u.universityId = cd.universityId and s.subjectNameEn like '%Art%';",
values: undefined,
typeCast: true,
nestTables: false,
_resultSet: null,
_results: [],
_fields: [],
_index: 0,
_loadError: null,
_connection: Connection {
_events: [Object: null prototype] {},
_eventsCount: 0,
_maxListeners: undefined,
config: [ConnectionConfig],
_socket: [Socket],
_protocol: [Protocol],
_connectCalled: true,
state: 'authenticated',
threadId: 25,
[Symbol(kCapture)]: false
},
[Symbol(kCapture)]: false
},
Query {
_events: [Object: null prototype] {
error: [Function],
packet: [Function],
timeout: [Function],
end: [Function]
},
_eventsCount: 4,
_maxListeners: undefined,
_callback: undefined,
_callSite: Error
at Protocol._enqueue (C:\Users\myste\Documents\Office Work\FindCoursesNode.js\node_modules\mysql\lib\protocol\Protocol.js:144:48)
at Connection.query (C:\Users\myste\Documents\Office Work\FindCoursesNode.js\node_modules\mysql\lib\Connection.js:198:25)
at C:\Users\myste\Documents\Office Work\FindCoursesNode.js\routes\course.js:59:36
at processTicksAndRejections (internal/process/task_queues.js:97:5),
_ended: false,
_timeout: undefined,
_timer: Timer { _object: [Circular], _timeout: null },
sql: 'select * from subjects;',
values: undefined,
typeCast: true,
nestTables: false,
_resultSet: null,
_results: [],
_fields: [],
_index: 0,
_loadError: null,
_connection: Connection {
_events: [Object: null prototype] {},
_eventsCount: 0,
_maxListeners: undefined,
config: [ConnectionConfig],
_socket: [Socket],
_protocol: [Protocol],
_connectCalled: true,
state: 'authenticated',
threadId: 25,
[Symbol(kCapture)]: false
},
[Symbol(kCapture)]: false
},
Query {
_events: [Object: null prototype] {
error: [Function],
packet: [Function],
timeout: [Function],
end: [Function]
},
_eventsCount: 4,
_maxListeners: undefined,
_callback: undefined,
_callSite: Error
at Protocol._enqueue (C:\Users\myste\Documents\Office Work\FindCoursesNode.js\node_modules\mysql\lib\protocol\Protocol.js:144:48)
at Connection.query (C:\Users\myste\Documents\Office Work\FindCoursesNode.js\node_modules\mysql\lib\Connection.js:198:25)
at C:\Users\myste\Documents\Office Work\FindCoursesNode.js\routes\course.js:60:37
at processTicksAndRejections (internal/process/task_queues.js:97:5),
_ended: false,
_timeout: undefined,
_timer: Timer { _object: [Circular], _timeout: null },
sql: 'SELECT distinct Country from worldcities;',
values: undefined,
typeCast: true,
nestTables: false,
_resultSet: null,
_results: [],
_fields: [],
_index: 0,
_loadError: null,
_connection: Connection {
_events: [Object: null prototype] {},
_eventsCount: 0,
_maxListeners: undefined,
config: [ConnectionConfig],
_socket: [Socket],
_protocol: [Protocol],
_connectCalled: true,
state: 'authenticated',
threadId: 25,
[Symbol(kCapture)]: false
},
[Symbol(kCapture)]: false
}...
Node.js version 12.18.1
The mysql module does not support the Promise API, so you cannot use async/await with it. If you want to use async/await then you should take a look at the mysql2 module. Here is a small example of working with this module:
const mysql = require('mysql2');
(async function main(param) {
try {
const nativePool = mysql.createPool({
host: 'localhost',
user: 'root',
database: 'newsdb',
connectionLimit: 10,
});
const pool = nativePool.promise();
const query1 = pool.query('SELECT * FROM users');
const query2 = pool.query('SELECT * FROM users');
const query3 = pool.query('SELECT * FROM users');
const results = await Promise.all([query1, query2, query3]);
results.forEach(([rows, fields]) => console.log(rows));
} catch (error) {
console.error(error);
}
})();
Also, in your sample code, you do not need to use await before requests if you want to execute them in parallel in Promise.all. Because, using await, you will wait for each request to complete.
You could make it work with Promises as you want just importing the util module that already comes in node
the code would be something like this
const util = require('util')
conn.query = util.promisify(conn.query)
then after it you export the conn
But I would recommend you to use Pool instead of conn for mysql , the method I showed works also with Pool
I'm trying to do a sql transaction. for this I need to start a session which a possible only with a mongo dB connection instance.
In my app, I can reach only the DB instance. and I need to be able to get from it the mongodb connection instance. As I understand, getMongo() function should do exactly that.
The problem is the getMongo() is not acting as expected.
when i run this following code:
const db = await this.dbClient;
console.log(db,"db");
console.log(db.getMongo(),"getMongo");
const session = db.getMongo().startSession();
I get this following console.log and errors:
Db {
_events: [Object: null prototype] {},
_eventsCount: 0,
_maxListeners: undefined,
s: {
dbCache: {},
children: [],
topology: NativeTopology {
_events: [Object: null prototype],
_eventsCount: 35,
_maxListeners: Infinity,
s: [Object],
[Symbol(kCapture)]: false,
[Symbol(waitQueue)]: [Denque]
},
options: {
retryWrites: true,
readPreference: [ReadPreference],
promiseLibrary: [Function: Promise]
},
logger: Logger { className: 'Db' },
bson: BSON {},
readPreference: ReadPreference { mode: 'primary', tags: undefined },
bufferMaxEntries: -1,
parentDb: null,
pkFactory: undefined,
nativeParser: undefined,
promiseLibrary: [Function: Promise],
noListener: false,
readConcern: undefined,
writeConcern: undefined,
namespace: MongoDBNamespace { db: 'MyDB', collection: undefined }
},
serverConfig: [Getter],
bufferMaxEntries: [Getter],
databaseName: [Getter],
[Symbol(kCapture)]: false
} db
{"Error msg: TypeError: db.getMongo is not a
function\n...","level":"error"}
{"session is not defined....","level":"error"}
Anybody knows what it the problem?
My mongo version is 4.2.6.
Many thanks
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',
});
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.