Маршрут, возвращающий пустой массив, даже если вставка в базу данных работает - PullRequest
0 голосов
/ 13 февраля 2019

Я учусь использовать Sqlite3 с Node, и у меня возникает странная проблема.В componentWillMount() в главном App.js моего реагирующего я делаю запрос axios на маршрут /all, чтобы я мог заполнить список контактов.

Что странно, когда я нажимаю на другой маршрут, /add с другим запросом axios, когда я добавляю контакт, он достигает моего then() как такового,

axios
  .post('/add', contactData)
  .then(res =>
    console.log(`Contact ${contactData.name} added successfully`)
  )
  .catch(err => console.log('Error encountered: ', err));

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

Но когда я получаю прямой доступ к localhost:5000/all, я получаю пустой массив [] в качестве ответа.Я не уверен, что происходит.

Вот мой server.js

const express = require('express');
const sqlite3 = require('sqlite3');
const path = require('path');
const cors = require('cors');

const dbName = 'my.db';
const tableName = 'Contacts';
const dbPath = path.resolve(__dirname, dbName);

const app = express();

const port = process.env.PORT || 5000;

app.use(cors());

app.listen(port, () => console.log(`Server running on port ${port}`));

app.get('/all', (req, res) => {
  let db = new sqlite3.Database(dbPath);

  let sql = `SELECT number FROM ${tableName}`;

  db.run(
    `CREATE TABLE IF NOT EXISTS ${tableName}(name text, number text, address text)`
  );

  db.all(sql, [], (err, rows) => {
    if (err) {
      return res.status(500).json(err);
    } else {
      return res.json(rows);
    }
  });
});

app.post('/add', (req, res) => {
  let db = new sqlite3.Database(dbPath);

  db.run(
    `INSERT INTO ${tableName}(name, number, address) VALUES(${req.name},${
      req.number
    },${req.address})`,
    [],
    err => {
      if (err) return res.status(500).json(err);
    }
  );

  return res.json({ msg: 'success' });
});

Редактировать:

Я должен отметить, что при переходе к / всеЯ получаю это,

all

и когда я пытаюсь опубликовать / добавить, я получаю ошибку

Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client

Нет, куда я отправляю несколько ответов.

Ответы [ 3 ]

0 голосов
/ 13 февраля 2019
await  db.all(sql, [], async (err, rows) => {
    if (err) {
       await return res.status(500).json(err);
    } else {
     await return res.json(rows);
    }
  });
0 голосов
/ 13 февраля 2019

Я бы не стал инициализировать вашу базу данных и создавать вашу таблицу каждый раз, когда вы нажимаете /all.

Попробуйте:

// get this out of the `/all` route, no need to initialize the db object over and over again
let db = new sqlite3.Database(dbPath);

// also leave this outside the `/all` route:
// no need to create the table over and over again.
db.run(
  `CREATE TABLE IF NOT EXISTS ${tableName}(name text, number text, address text)`
);


app.get('/all', (req, res) => {
  let sql = `SELECT number FROM ${tableName}`;

  // according to the sqlite3 api, the second parameter is optional, so just leave it out:
  db.all(sql, (err, rows) => {
    if (err) return res.status(500).json(err); // if you use return,  you don't need 'else' because the code will never reach it.

    res.json(rows)
  });
});

Ваш маршрут /add также выглядит немного не так.Попробуйте это:

app.post('/add', (req, res) => {
  // let db = new sqlite3.Database(dbPath);  // remove this as you already defined it at the beginning of your code.

  db.run(
    `INSERT INTO ${tableName}(name, number, address) VALUES(${req.name},${req.number},${req.address})`,
    err => {
      if (err) return res.status(500).json(err);
      res.json({ msg: 'success' }); // put the success in the callback (after the query is run!), else, when you get an error, express.js will try to send an error message AND a success message giving you the error "Can't send headers after they are sent"
    }
  );

});
0 голосов
/ 13 февраля 2019

Вы можете решить эту проблему, используя Async-Await в Node.js.JavaScript асинхронен по своей природе, как и Node.Асинхронное программирование - это шаблон проектирования, который обеспечивает выполнение неблокирующего кода.

Неблокирующий код не препятствует выполнению фрагмента кода.В общем, если мы выполняем синхронно, то есть один за другим, мы без необходимости останавливаем выполнение тех кодов, которые не зависят от того, который вы выполняете.

Асинхронный выполняет в точности противоположное, асинхронный код выполняется беззависимость и нет порядка.Это повышает эффективность системы и пропускную способность.

Но в некоторых случаях нам нужно дождаться ответа.

 app.get('/all',async (req, res) => {
  let db = new sqlite3.Database(dbPath);
  let sql = `SELECT number FROM ${tableName}`;
 await db.run(
    `CREATE TABLE IF NOT EXISTS ${tableName}(name text, number text, address text)`
  );
 await  db.all(sql, [], (err, rows) => {
    if (err) {
      return res.status(500).json(err);
    } else {
      return res.json(rows);
    }
  });
});
app.post('/add',async  (req, res) => {
  let db = new sqlite3.Database(dbPath);
  await db.run(
    `INSERT INTO ${tableName}(name, number, address) VALUES(${req.name},${
      req.number
    },${req.address})`,
    [],
    err => {
      if (err) return res.status(500).json(err);
    }
  );
  return res.json({ msg: 'success' });
})
...