Closed A-Ghattas closed 2 years ago
use `mongodb://locahost:27017' as your connection uri
use `mongodb://locahost:27017' as your connection uri
That was not helpful at all but thank you. I did some digging and I removed a try catch and now I have this error:
const AsyncIteratorPrototype = Object.getPrototypeOf(Object.getPrototypeOf( /*#__PURE__*/_wrapAsyncGenerator(function* () {})).prototype);
^
TypeError: Cannot convert undefined or null to object
at Function.getPrototypeOf (<anonymous>)
and it's related to webpack.
Edit: Another important thing. I think this is a bug because when I downgrade the mongoose version to 5, everything works fine.
Can you provide the full script you are running?
Of course To reproduce you can make an empty angular universal project:
ng new project-name
cd project-name
ng add @nguniversal/express-engine
npm i mongoose
npm i @types/mongoose
// add mongoose.connect() to ./server.ts
// and run with:
npm run dev:ssr
This is the script I am running: ./server.ts
import '@angular/localize/init';
import 'zone.js/dist/zone-node';
import { ngExpressEngine } from '@nguniversal/express-engine';
import * as express from 'express';
import { join } from 'path';
import { AppServerModule } from './src/main.server';
import { APP_BASE_HREF } from '@angular/common';
import { existsSync } from 'fs';
import { connect } from './src/express/utils/database';
import * as swaggerUI from 'swagger-ui-express';
import { getSwaggerJson } from './src/express/utils/swagger-json-files';
import to from 'await-to-js';
import { config } from './src/environments/config';
import { router } from './src/express/router';
import bodyParser from 'body-parser';
import multer from 'multer';
import morgan from 'morgan';
import { Routes } from './src/models/routes.enum';
// The Express app is exported so that it can be used by serverless Functions.
export async function app(): Promise<express.Express> {
const server = express();
const distFolder = join(process.cwd(), 'dist/school-crow/browser');
const indexHtml = existsSync(join(distFolder, 'index.original.html')) ? 'index.original.html' : 'index';
// Our Universal express-engine (found @ https://github.com/angular/universal/tree/master/modules/express-engine)
server.engine(
'html',
ngExpressEngine({
bootstrap: AppServerModule,
})
);
server.set('view engine', 'html');
server.set('views', distFolder);
// Example Express Rest API endpoints
// server.get('/api/**', (req, res) => { });
// Serve static files from /browser
server.use(morgan('dev'));
server.use(bodyParser.json());
server.use(bodyParser.urlencoded({ extended: true }));
server.use(<any>multer().single('file'));
const [err, swaggerDocument] = await to(getSwaggerJson());
if (err) console.error(err);
server.use(
Routes.ApiDocs,
express.static('node_modules/swagger-ui-dist/', { index: false }),
swaggerUI.serve,
swaggerUI.setup(swaggerDocument)
);
server.use(Routes.Api, router);
server.get(
'*.*',
express.static(distFolder, {
maxAge: '1y',
})
);
// All regular routes use the Universal engine
server.get('*', (req, res) => {
res.render(indexHtml, { req, providers: [{ provide: APP_BASE_HREF, useValue: req.baseUrl }] });
});
return server;
}
function run(): void {
const port = process.env['PORT'] || 4000;
connect() // <=================== This is where I call the function that connect to mongoose
.then(() => {
// Start up the Node server
app().then((server) => {
server.listen(port, () => {
console.log(`Node Express server listening on http://localhost:${port}`);
});
});
})
.catch((e) => console.error('Mongoose connect error', e));
}
// Webpack will replace 'require' with '__webpack_require__'
// '__non_webpack_require__' is a proxy to Node 'require'
// The below code is to ensure that the server is run only when not requiring the bundle.
declare const __non_webpack_require__: NodeRequire;
const mainModule = __non_webpack_require__.main;
const moduleFilename = (mainModule && mainModule.filename) || '';
if (moduleFilename === __filename || moduleFilename.includes('iisnode')) {
run();
}
export * from './src/main.server';
./src/express/utils/database
import mongoose, { ConnectOptions } from 'mongoose';
import { config } from '../../environments/config';
export const connect = (url = config.db.url, opts: ConnectOptions = {}): Promise<typeof mongoose> => {
console.log('connecting to ' + url);
return mongoose.connect(config.db.url, {
...opts,
useNewUrlParser: true,
useUnifiedTopology: true,
useFindAndModify: false,
useCreateIndex: true,
});
};
If you need anything else let me know.
We'll take a look at this, but one suggestion you might try is disabling Zone.js as discussed here: https://github.com/Automattic/mongoose/issues/7838 . In the past, we've run into issues with Zone.js badly monkey-patching Node built-ins, that may be a potential cause.
I put in PRs to work around this issue in Angular and in the upstream dep that's causing this issue.
Regardless, I strongly recommend figuring out a way to avoid the "downleveling" that Angular does to force Node code to ES2015 for Zone.js support. I haven't been able to find a way, but I'm also not terribly familiar with Angular configs. Mongoose and several of its upstream deps, like mongodb@4.x
and whatwg-url@11
, require Node >= 12, and these libs don't test in environments where they're transpiled down to lower ECMAScript versions.
Do you want to request a feature or report a bug? A bug
What is the current behavior? A new empty Angular 13.1.0 Universal app. I added mongoose 6.1.3 When I add mongoose.connect('mongodb://username:password@127.0.0.1:27017/database') I get the error
127.0.0.1:52098 IS NOT the uri I am passing to the connect function. I tried with a hosted mongodb server to be sure of that.
If the current behavior is a bug, please provide the steps to reproduce.
In a new Angular universal app add the following code to server.ts:
What is the expected behavior? To connect to the mongo database
What are the versions of Node.js, Mongoose and MongoDB you are using? Note that "latest" is not a version. mongoose: 6.1.3 MongoDB: 5.0.4 Node.js: 16.13.1 (also tried with the new v17, same behavior)