Как отладить JavaScript, который не будет получать данные из MongoDB?

avatar
RioTz
8 апреля 2018 в 06:58
355
1
0

Я следую этому руководству: https://anmolkoul.wordpress.com/2015/06/05/interactive-data-visualization-using-d3-js-dc-js-nodejs-and-mongodb /

После решения нескольких проблем вроде бы все работает, но на странице не отображаются данные из MongoDB. Похоже, он пытается подключиться, но всегда терпит неудачу.

Я даже поместил свою коллекцию Mongo в mLab, чтобы посмотреть, сможет ли она подключиться к чему-то другому, кроме локального хоста. Это не так.

У меня есть файл Server.js

// modules =================================================
var express        = require('express');
var app            = express();
var mongoose       = require('mongoose');
var bodyParser     = require('body-parser');
var methodOverride = require('method-override');

// configuration ===========================================

// config files
var port = process.env.PORT || 8080; // set our port
var db = require('./config/db');

// connect to our mongoDB database (commented out after you enter in your own credentials)
connectionsubject = mongoose.createConnection(db.urlSubjectViews);



// get all data/stuff of the body (POST) parameters
app.use(bodyParser.json()); // parse application/json 
app.use(bodyParser.json({ type: 'application/vnd.api+json' })); // parse application/vnd.api+json as json
app.use(bodyParser.urlencoded({ extended: true })); // parse application/x-www-form-urlencoded

app.use(methodOverride('X-HTTP-Method-Override')); // override with the X-HTTP-Method-Override header in the request. simulate DELETE/PUT
app.use(express.static(__dirname + '/public')); // set the static files location /public/img will be /img for users

// routes ==================================================
require('./app/routes')(app); // pass our application into our routes

// start app ===============================================
app.listen(port);   
console.log('Magic happens on port ' + port);           // shoutout to the user
exports = module.exports = app;                         // expose app

Файл db.js для указания базы данных:

    module.exports = {
    urlSubjectViews: 'mongodb://localhost:27017/donorschoose',

}

файл SubjectViews.js для указания нужных мне данных

// define our nerd model
// module.exports allows us to pass this to other files when it is called
module.exports = connectionsubject.model('', {}, 'projects');

И файл Route.js для настройки маршрута для данных JSON

var Subjects = require('./models/SubjectViews');

module.exports = function(app) {

    // server routes ===========================================================
    // handle things like api calls
    // authentication routes    
    // sample api route
 app.get('/api/data', function(req, res) {
  // use mongoose to get all nerds in the database
  Subjects.find({}, {'_id': 0, 'school_state': 1, 'resource_type': 1, 'poverty_level': 1, 'date_posted': 1, 'total_donations': 1, 'funding_status': 1, 'grade_level': 1}, function(err, subjectDetails) {
   // if there is an error retrieving, send the error. 
       // nothing after res.send(err) will execute
   if (err) 
   res.send(err);
    res.json(subjectDetails); // return all nerds in JSON format
  });
 });





 // frontend routes =========================================================
 app.get('*', function(req, res) {
  res.sendfile('./public/index.html');
 });
}

Это моя коллекция в Studio 3T: Коллекция Mongo

Я знаю, что он указывает на базу данных, потому что, когда я смотрю на localhost:8080/api/data, страница загружается, но через некоторое время истекает время ожидания. Это только кажется, что это у меня такая проблема??

Источник
lineus
8 апреля 2018 в 07:41
0

какие версии сервера/узла mongoose/mongodb вы используете?

RioTz
8 апреля 2018 в 07:49
0

Mongo Shell v3.4.9, Express 4.5.1, Mongoose 3.8.0, узел 8.6.0

Ответы (1)

avatar
lineus
8 апреля 2018 в 08:46
1

Более общая проблема в этом случае заключается в том, что вы следуете руководству трехлетней давности, основанному на пакете, который не работает так, как рекламируется (по крайней мере, больше не работает или не для меня).

opc: git clone https://github.com/anmolkoul/node-dc-mongo.git
Cloning into 'node-dc-mongo'...
remote: Counting objects: 930, done.
remote: Total 930 (delta 0), reused 0 (delta 0), pack-reused 930
Receiving objects: 100% (930/930), 1.75 MiB | 0 bytes/s, done.
Resolving deltas: 100% (133/133), done.
opc: cd node-dc-mongo/
node-dc-mongo>: rm -rf node_modules/
node-dc-mongo>: npm install
npm WARN deprecated mongodb@1.4.38: Please upgrade to 2.2.19 or higher

> bson@0.2.22 install /Users/lineus/dev/opc/node-dc-mongo/node_modules/bson
> (node-gyp rebuild 2> builderror.log) || (exit 0)

  CXX(target) Release/obj.target/bson/ext/bson.o

> kerberos@0.0.11 install /Users/lineus/dev/opc/node-dc-mongo/node_modules/kerberos
> (node-gyp rebuild 2> builderror.log) || (exit 0)

  CXX(target) Release/obj.target/kerberos/lib/kerberos.o
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN starter-node-angular@1.0.1 No repository field.
npm WARN starter-node-angular@1.0.1 No license field.

added 64 packages in 8.994s
node-dc-mongo>: node server.js 
{ Error: Cannot find module '../build/Release/bson'
    at Function.Module._resolveFilename (module.js:538:15)
    at Function.Module._load (module.js:468:25)
    at Module.require (module.js:587:17)
    at require (internal/module.js:11:18)
    at Object.<anonymous> (/Users/lineus/dev/opc/node-dc-mongo/node_modules/bson/ext/index.js:15:10)
    at Module._compile (module.js:643:30)
    at Object.Module._extensions..js (module.js:654:10)
    at Module.load (module.js:556:32)
    at tryModuleLoad (module.js:499:12)
    at Function.Module._load (module.js:491:3) code: 'MODULE_NOT_FOUND' }
js-bson: Failed to load c++ bson extension, using pure JS version
Magic happens on port 8080
^C
node-dc-mongo>: 

Итак, придется немного потрудиться, чтобы все заработало.

Давайте начнем с того, что немного упростим проблемное пространство, создав отдельный файл, который имитирует части кода Mongoose, чтобы вам было легче рассуждать. (Я использую более новую версию Mongoose, но детали те же).

'use strict'

const mongoose = require('mongoose')
const conn = mongoose.createConnection('mongodb://localhost/test')

const Model = conn.model('', {}, 'tests')

Model.find({}, (err, docs) => {
  if (err) { return console.error(err) }
  console.log(`there are ${docs.length} docs in this collection.`)
  return conn.close()
})

Если мы запустим этот код, вывода не будет, и все застрянет.

49715319: node ./connect.js
^C
49715319:

Метод createConnection возвращает объект подключения, который наследуется от eventEmitter. Чтобы успешно использовать возвращенный объект подключения, мы должны «прослушать» событие «открыть».

Мы можем изменить наш файл следующим образом:

'use strict'

const mongoose = require('mongoose')
const conn = mongoose.createConnection('mongodb://localhost:27017/test')

const Model = conn.model('', {}, 'tests')

conn.on('open', function (err) {
  if (err) { return console.error(err) }
  Model.find({}, (err, docs) => {
    if (err) { return console.error(err) }
    console.log(`there are ${docs.length} docs in this collection.`)
    return conn.close()
  })
})

Вывод становится следующим:

49715319: node ./connect.js
there are 1000 docs in this collection.
49715319:

Это означает, что вы должны изменить файл server.js следующим образом:

// modules =================================================
var express = require('express');
var app = express();
var mongoose = require('mongoose');
var bodyParser = require('body-parser');
var methodOverride = require('method-override');

// configuration ===========================================

// config files
var port = process.env.PORT || 8080; // set our port
var db = require('./config/db');

// connect to our mongoDB database (commented out after you enter in your own credentials)
connectionsubject = mongoose.createConnection(db.urlSubjectViews);


connectionsubject.on('open', function (err) {
  if (err) { return console.error(err) }
  // get all data/stuff of the body (POST) parameters
  app.use(bodyParser.json()); // parse application/json
  app.use(bodyParser.json({ type: 'application/vnd.api+json' })); // parse application/vnd.api+json as json
  app.use(bodyParser.urlencoded({ extended: true })); // parse application/x-www-form-urlencoded

  app.use(methodOverride('X-HTTP-Method-Override')); // override with the X-HTTP-Method-Override header in the request. simulate DELETE/PUT
  app.use(express.static(__dirname + '/public')); // set the static files location /public/img will be /img for users

  // routes ==================================================
  require('./app/routes')(app); // pass our application into our routes

  // start app ===============================================
  app.listen(port);
  console.log('Magic happens on port ' + port);           // shoutout to the user
  exports = module.exports = app;                         // expose app
})

Экспресс-приложение не запустится, пока Mongoose не подключится к серверу.

Скорее всего, это все равно не будет работать, учитывая версию Mongoose, которую вы используете. Если это все еще не удается, я бы предложил установить последнюю версию Mongoose или, по крайней мере, последнюю версию Mongoose 4 на момент написания этой статьи.

Для полноты картины я сгенерировал документы для этой тестовой коллекции (используя Mongoose 5):

#!/usr/bin/env node
'use strict'

const mongoose = require('mongoose')
mongoose.connect('mongodb://localhost/test')
const Schema = mongoose.Schema

const schema = new Schema({
  name: String
})

const Test = mongoose.model('test', schema)

const tests = []

for (let i = 0; i < 1000; i++) {
  tests.push(new Test({ name: `testing${i}` }))
}

async function run () {
  await mongoose.connection.dropDatabase()
  let docs = await Test.create(tests)
  console.log(`added ${docs.length} docs to ${Test.modelName}`)
  return mongoose.connection.close()
}

run()
RioTz
8 апреля 2018 в 09:23
0

Как бы вы порекомендовали переписать это в более современной версии Mongoose? Мне очень не хватает времени, и я просто хочу, чтобы это работало, ха-ха, спасибо, что нашли время, чтобы помочь, хотя я действительно ценю это.

lineus
8 апреля 2018 в 09:37
0

просто измените файл server.js, как я сделал в своем комментарии выше, выполните npm install mongoose@latest и запустите его. Если это выдает какие-либо ошибки, не стесняйтесь переходить на gitter.im/Automattic/mongoose, и мы сможем разобраться :)

lineus
8 апреля 2018 в 09:39
0

Я выделил строку прямо перед кодом изменения вашего файла server.js жирным шрифтом выше, чтобы его было легче найти. Я знаю, что это был длинный ответ, извините :)

RioTz
8 апреля 2018 в 09:40
0

Спасибо, я сейчас на работе, но я вернусь немного позже, чтобы попробовать еще раз

halfer
8 апреля 2018 в 09:58
0

Это отличный ответ, Линус, надеюсь увидеть вас здесь в будущем! Хорошая работа.

lineus
8 апреля 2018 в 10:38
1

Спасибо полумер! Я признателен за это :)

RioTz
8 апреля 2018 в 18:37
0

Я только что вернулся и обновил мангуста в пакете, и он работает! Большое спасибо!