Node.JS и Postgres Панель поиска - PullRequest
0 голосов
/ 11 февраля 2020

Я пытаюсь создать панель поиска, которая будет запрашивать и отображать данные из моей собственной базы данных Postgres. У меня есть строка поиска на моем экране, и я думаю, что я подключен к своей базе данных, но я не могу получить никаких результатов, чтобы показать. Любая помощь будет оценена. Я все еще новичок в использовании node.js и разработке таких инструментов, как этот. Когда я отправляю запрос, я получаю сообщение об ошибке 404. Указатель. js

const express = require('express');
const router = express.Router();
const pg = require('pg');
const path = require('path');
const connectionString = process.env.DATABASE_URL || 'postgres://postgres:postgres@localhost:5432/todo';


router.get('/', (req, res, next) => {
  res.sendFile(path.join(
    __dirname, '..', '..', 'client', 'views', 'index.html'));
});

router.get('/api/v1/todos', (req, res, next) => {
  const results = [];
  // Get a Postgres client from the connection pool
  pg.connect(connectionString, (err, client, done) => {
    // Handle connection errors
    if(err) {
      done();
      console.log(err);
      return res.status(500).json({success: false, data: err});
    }
    // SQL Query > Select Data
    const query = client.query('SELECT name FROM world_heritage_sites.caravanserai ORDER BY iso ASC;');
    // Stream results back one row at a time
    query.on('row', (row) => {
      results.push(row);
    });
    // After all data is returned, close connection and return results
    query.on('end', () => {
      done();
      return res.json(results);
    });
  });
});

Приложение. js

const express = require('express');
const path = require('path');
const favicon = require('serve-favicon');
const logger = require('morgan');
const cookieParser = require('cookie-parser');
const bodyParser = require('body-parser');
const routes = require('./server/routes/index');
// var users = require('./routes/users');

const app = express();

// view engine setup
// app.set('views', path.join(__dirname, 'views'));
// app.set('view engine', 'html');

// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'client')));

app.use('/', routes);
// app.use('/users', users);

// catch 404 and forward to error handler
app.use((req, res, next) => {
  var err = new Error('Not Found');
  err.status = 404;
  next(err);
});

// error handlers

// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
  app.use((err, req, res, next) => {
    res.status(err.status || 500);
    res.json({
      message: err.message,
      error: err
    });
  });
}

// production error handler
// no stacktraces leaked to user
app.use((err, req, res, next) => {
  res.status(err.status || 500);
  res.json({
    message: err.message,
    error: {}
  });
});


module.exports = app;

HTML

 <!DOCTYPE html>
<html ng-app="nodeTodo">
  <head>
    <title>Todo App - with Node + Express + Angular + PostgreSQL</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" media="screen">
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
    <script src="/search.js" type="text/javascript"></script>
    <script src="/search.js"></script>
    <script src="//code.jquery.com/jquery-2.2.4.min.js" type="text/javascript"></script>
    <script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" type="text/javascript"></script>
  </head>
  <body ng-controller="mainController">
    <div class="container">
      <div class="header">
        <h1>SuckySearchBar</h1>
        <hr>
        <h1 class="lead">Designing Search Bars Suck This Never Works</h1>
      </div>
    </body>
    <body ng-controller="searchController">
      <div class="container">
        <div class="search-box">
                <input class="search" type="text" placeholder="Search" id="search" method='GET' autocomplete="on" onkeyup="search();">
                <table class="result table-bordered" id="search"></table>
<script>
                function searchinput(){
                  $.ajax({
                      type: 'GET',
                      url: '/api/v1/todos' + searchinput,
                      success: function(result){
                          window.location.reload(true);
                      }
                  })
                }

                </script>
      </div>
     </body>
</html>

Поиск. js

function search(search_string, func) {
     pool.query(
        "SELECT name FROM world_heritage_sites.caravanserai ORDER BY iso ASC", 
        [search_string],
        function(err, result) {  
            if(err) {
                func([])
            } else {
                func(result.rows)
            }
        }
    );
}

module.export = search;

Ответы [ 2 ]

2 голосов
/ 11 февраля 2020

прежде всего, поздравляю с началом нового учебного задания! Но давайте решим эту проблему, не так ли?

1 - Мой совет для вас: прежде чем вы начнете беспокоиться о интерфейсе, давайте удостоверимся, что наш сервис работает нормально, и мы проверим его только на стороне сервера. «Я думаю, что я подключен к своей базе данных», мы не можем продолжить, если думаем, что что-то идет хорошо, нам нужно убедиться!

2 - Нам нужен наш сервис, это единственный способ, которым мы можно подключить нашу БД. Итак, пока мы забыли об интерфейсе и БД, давайте сосредоточимся на сервисе: внутри вашего "приложения. js" вы пытаетесь импортировать свои маршруты, верно? Сделав

const routes = require('./server/routes/index');

Но для этого вам нужно экспортировать эти маршруты раньше, затем go в ваш файл «index. js» и добавить «module.exports = router». Теперь вы можете использовать свой роутер, импортированный в ваш файл "app. js"!

Остаётся так:

const express = require('express');
const router = express.Router();
const pg = require('pg');
const path = require('path');
const connectionString = process.env.DATABASE_URL || 'postgres://postgres:postgres@localhost:5432/todo';

 Almost there, our service needs to listen to some port now


router.get('/', (req, res, next) => {
  res.sendFile(path.join(
    __dirname, '..', '..', 'client', 'views', 'index.html'));
});

router.get('/api/v1/todos', (req, res, next) => {
  console.log("HAHAHAHAHA")
  const results = [];
  // Get a Postgres client from the connection pool
  pg.connect(connectionString, (err, client, done) => {
    // Handle connection errors
    if(err) {
      done();
      console.log(err);
      return res.status(500).json({success: false, data: err});
    }
    // SQL Query > Select Data
    const query = client.query('SELECT name FROM world_heritage_sites.caravanserai ORDER BY iso ASC;');
    // Stream results back one row at a time
    query.on('row', (row) => {
      results.push(row);
    });
    // After all data is returned, close connection and return results
    query.on('end', () => {
      done();
      return res.json(results);
    });
  });
});

module.exports = router;

Теперь нашему приложению нужно прослушивать какой-то порт. У меня нет доступа к вашей структуре папок, поэтому я буду работать над этой идеей, используя только те два файла, которые вы нам представили. Внутри вашего "app. js" вы сказали, что ваше приложение должно обслуживаться через один порт, вы можете сделать это, набрав "app.listen (8000, () => console.log ('listening)))", так как вы Экспортируя свое приложение, вы можете импортировать и использовать его где угодно, но я уже говорил вам, я отработаю идею, ограниченную файлами, которые вы нам показали, поэтому ваше "приложение. js" будет похоже на эту проверку эти документы до: https://node-postgres.com/features/connecting

const express = require('express');
const path = require('path');
const logger = require('morgan');
const cookieParser = require('cookie-parser');
const bodyParser = require('body-parser');
const routes = require('./index');
// var users = require('./routes/users');

const app = express();

// view engine setup
// app.set('views', path.join(__dirname, 'views'));
// app.set('view engine', 'html');

// uncomment after placing your favicon in /public
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'client')));

app.use('/', routes);
// app.use('/users', users);

// catch 404 and forward to error handler
app.use((req, res, next) => {
  var err = new Error('Not Found');
  err.status = 404;
  next(err);
});

// error handlers

// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
  app.use((err, req, res, next) => {
    res.status(err.status || 500);
    res.json({
      message: err.message,
      error: err
    });
  });
}

// production error handler
// no stacktraces leaked to user
app.use((err, req, res, next) => {
  res.status(err.status || 500);
  res.json({
    message: err.message,
    error: {}
  });
});


app.listen(8000, () => console.log('listening'))

module.exports = app;

Хорошо, теперь наш сервис работает, go к вашему терминалу и введите: приложение узла. js

он должен напечатать «прослушивание» в вашей оболочке.

Теперь попробуйте получить доступ к http://localhost: 8000 / api / v1 / todos в вашем браузере, это должно вывести ошибку «pg. connect - это не функция "

Это потому, что вы не используете lib правильным способом, попробуйте что-то вроде этого

const express = require('express');
const router = express.Router();
const path = require('path');
const { Pool, Client } = require('pg')
const connectionString = 'postgres://postgres:postgres@localhost:5432/todo'
const client = new Client({
  connectionString: connectionString,
})
client.connect()

router.get('/', (req, res, next) => {
  res.sendFile(path.join(
    __dirname, '..', '..', 'client', 'views', 'index.html'));
});

router.get('/api/v1/todos', (req, res, next) => {
  const results = [];
  client.query('SELECT name FROM world_heritage_sites.caravanserai ORDER BY iso ASC;', (err, res) => {
    console.log(err, res)
    client.end()
  })
});

module.exports = router;

Но помните, что вам нужно запустить службу Postgres на вашем локальном хосте для подключения, используя эту строку подключения, которую вы используете. Если вы настроили службу Postgres и db правильно, она должна работать нормально, тогда вам просто нужно назвать свой маршрут "localhost: 8000 / api / v1 / todos" в вашем интерфейсе.

На самом деле есть Есть много вещей, которые вы должны проверить в своем коде, и, может быть, это хорошо, если вы получите некоторый опыт до начала этого проекта. Попробуйте несколько уроков для начинающих на YouTube и проверьте код другого разработчика. Удачи и хорошего кода, чувак! Надеюсь, я вам хоть немного помог:)

0 голосов
/ 11 февраля 2020

Я думаю, что @Molda говорит, что вы должны изменить methods=['GET'] на method='GET'. Можете ли вы также опубликовать окружение html?

EDIT

Хорошо, поэтому я думаю, что вы путаете javascript, запущенный на вашем сервере, и javascript, запущенный в браузере. Если вы собираетесь вызывать search() из обработчика событий onKeyUp(), то он будет запущен в браузере. Поскольку он будет работать в браузере, он не сможет напрямую обращаться к postgres. Он должен сделать ajax запрос к маршруту на сервере, который предоставляет ему результаты поиска в виде json (аналогично тому, что вы сделали с /api/v1/todos, вы можете определить /api/v1/search), который затем обрабатывается на странице как-то (возможно, с jquery). В этом случае вам даже не нужно определять method на вашем input.

...