Как подключиться к MongoDB с помощью Node.js, написанного на TypeScript? - PullRequest
0 голосов
/ 09 ноября 2018

Я работаю на сервере Node.js, подключаюсь к MongoDB и пишу с использованием TypeScript. Когда я пытаюсь использовать MongoDB, он не создает соединение, однако, когда я проверяю вывод монго, создается впечатление, что он создает соединение.

Чего мне не хватает в моем коде для определения соединения в Node.js?

Моя строка подключения 'mongodb://localhost:27017'

Мой метод подключения:

connect() {
    console.log('connecting to mongo') //this is called
    MongoClient.connect(this.connectionString, {useNewUrlParser: true})
    .then(client => {
        console.log('setting client'); //this doesn't get called
        this.client = client;
        console.log(this.client);
    })
    .catch(error => {
        console.log('error during connecting to mongo: '); //this also doesn't get called
        console.error(error);
    });
}

Монго вывод:

2018-11-08T23: 06: 24.106 + 0100 I СЕТЬ Соединение [слушатель] принято с 127.0.0.1:51345 # 11 (2 соединения теперь открыто)

2018-11-08T23: 06: 24.107 + 0100 I NETWORK [conn11] получил метаданные клиента из 127.0.0.1:51345 conn11: {драйвер: {name: "nodejs", версия: "3.1.9"}, os : {тип: "Darwin", имя: "darwin", архитектура: "x64", версия: "17.7.0"}, платформа: "Node.js v8.9.3, LE, ядро ​​mongodb: 3.1.8"}

Мой репозиторий находится на https://github.com/FrisoDenijs/MEAN-ToDo/blob/master/server/src/db/mongo.db.ts для полного кода.

console.log(db) по запросу shkaper

MongoClient {
  domain: null,
  _events: {},
  _eventsCount: 0,
  _maxListeners: undefined,
  s:
   { url: 'mongodb://localhost:27017',
     options:
      { servers: [Array],
        caseTranslate: true,
        useNewUrlParser: true,
        socketTimeoutMS: 360000,
        connectTimeoutMS: 30000,
        promiseLibrary: [Function: Promise] },
     promiseLibrary: [Function: Promise],
     dbCache: {},
     sessions: [] },
  topology:
   Server {
     domain: null,
     _events:
      { serverOpening: [Function],
        serverDescriptionChanged: [Function],
        serverHeartbeatStarted: [Function],
        serverHeartbeatSucceeded: [Function],
        serverHeartbeatFailed: [Function],
        serverClosed: [Function],
        topologyOpening: [Function],
        topologyClosed: [Function],
        topologyDescriptionChanged: [Function],
        commandStarted: [Function],
        commandSucceeded: [Function],
        commandFailed: [Function],
        joined: [Function],
        left: [Function],
        ping: [Function],
        ha: [Function],
        authenticated: [Function],
        error: [Function],
        timeout: [Function],
        close: [Function],
        parseError: [Function],
        open: [Object],
        fullsetup: [Object],
        all: [Object],
        reconnect: [Function] },
     _eventsCount: 25,
     _maxListeners: Infinity,
     clientInfo:
      { driver: [Object],
        os: [Object],
        platform: 'Node.js v8.9.3, LE' },
     s:
      { coreTopology: [Object],
        sCapabilities: null,
        clonedOptions: [Object],
        reconnect: true,
        emitError: true,
        poolSize: 5,
        storeOptions: [Object],
        store: [Object],
        host: 'localhost',
        port: 27017,
        options: [Object],
        sessionPool: [Object],
        sessions: [],
        promiseLibrary: [Function: Promise] } } }

Ответы [ 3 ]

0 голосов
/ 12 ноября 2018

Проблема в том, что mongo.connect - это асинхронный код, и контроллер вызывает его неправильно. поэтому следующая строка mongo.getDb() будет выполнена без инициализации this.client.

Поскольку вы используете Typescript, мы можем использовать async/await для более чистого кода.

async connect() { // add async
    console.log('connecting to mongo');

    try {
      if (!this.client) { // I added this extra check
        console.log('setting client');
        this.client = await MongoClient.connect(this.connectionString, { useNewUrlParser: true })
        console.log(this.client);      
      }
    } catch(error) {
      console.log('error during connecting to mongo: ');
      console.error(error);
    }    
}

А в коде контроллера

async get(req: Request, res: Response) { // add async
  const mongo = new MongoDb();
  await mongo.connect(); // add await
  const db = mongo.getDb(); 
  // ....     
}

Я попробовал ваше репо с изменениями и получил этот ответ

enter image description here

Надеюсь, это поможет

0 голосов
/ 19 апреля 2019

Вышеуказанные решения работают, но есть другой метод, который мне нравится немного лучше. Это больше похоже на стандартный HTTP-вызов (я получил его для работы с и без async-await, но это хорошая идея, чтобы оставить его внутри):

private async connect(){
    this.mongo = new mongodb.MongoClient(this.url, {useNewParser: true});
    await this.mongo.connect((err, client) => {
        if(client.isConnected()){
            console.log('setting client');
            this.client = client;
            console.log(this.client);
        }
        else{
            console.log('error during connecting to mongo: ');
            console.error(error);
        }
    });
}

Это основано на api v3.2 драйвера Node.js, который вы можете посмотреть здесь: https://mongodb.github.io/node-mongodb-native/3.2/api/index.html

Это может быть просто другой способ побрить кошку, но я полагаю, что стоит поделиться с кем-нибудь еще, кто окажется здесь позже.

0 голосов
/ 12 ноября 2018

Исходя из того, что вы сказали ни об ошибках, ни об успешных обратных вызовах, я думаю, что проблема не только в коде здесь: https://github.com/FrisoDenijs/MEAN-ToDo/blob/master/server/src/db/mongo.db.ts Но также, например, здесь: https://github.com/FrisoDenijs/MEAN-ToDo/blob/master/server/src/controllers/to-do.controller.ts Когда вы запускаете mongo.connect должна быть возможность дождаться обещания, возвращенного с MongoClient.connect.Поэтому я бы изменил код в mongo.db.ts, например, на sth, например так (зависит от того, как вы хотите выполнить это обещание):

connect() {
    console.log('connecting to mongo')
    return MongoClient.connect(this.connectionString, {useNewUrlParser: true})
    .then(client => {
        console.log('setting client');
        this.client = client;
        console.log(this.client);
    })
    .catch(error => {
        console.log('error during connecting to mongo: ');
        console.error(error);
    });
}

Тогда в to-do.controller.ts вы можете await this или использовать then:

get(req: Request, res: Response) {
    const mongo = new MongoDb();
    mongo.connect().then(() => {

      const db = mongo.getDb();
      const collection = db.collection('todo', (error, collection) => {
          if (error) {
              res.json(error);
              res.statusCode = HttpStatus.BAD_REQUEST
              return;
          }

          collection.find().toArray((error, result) => {
              if (error) {
                  res.json(error);
                  res.statusCode = HttpStatus.BAD_REQUEST
              }

              res.json(result);
              res.statusCode = HttpStatus.OK;
          })

      });

      mongo.close();
    });
} 

Я полагаю, что ваш код просто не «ждет» установления соединения, а затем терпит неудачу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...