Node.js

#javascript #mysql #node.js

Вопрос:

Я работаю с Node.js и подключил его к MySQL.

Моя проблема в том, SELECT что запрос не возвращает результат. Я использовал INSERT запрос, и он отлично работает!

Для SELECT проблемы с запросом.

Я хочу иметь отдельный файл с функциями, которые выполняют запросы к базе данных MySQL. Этот файл является database.js, который содержит следующий код:

 exports.connectionParams = {
    host: 'localhost',
    user: 'root',
    password: '*****',
    database: 'savitri_dev'
}

exports.getSchoolIdByName = (con, schoolName, callback) => {
    let sql = `SELECT id FROM School WHERE designation = '${schoolName}';`;
    console.log(sql);
    con.query(sql, (queryErr, result) => {
        if (queryErr) throw queryErr;
        callback(result[0].id);
        //return result[0].id;
    });
};
 

Теперь файл, в котором я вызываю запрос, является new_client.js (это файл маршрута):

 var express = require('express');
var router = express.Router();
var mysql = require('mysql');
var db = require('../bin/database');

router.get('/', (req, res, next) => {
    //res.send('respond with a resource');
    res.render('new_client', { 
        title: 'Clients - Add New Client',
        angular_app_name: 'clientsModule',
        angular_controller_name: 'AddClientController'
    });
});

router.put('/', (req, res, next) => {
    const dbConnection = mysql.createConnection(db.connectionParams);
    let data = req.body;
    let studentsDataList = [];
    console.log(data.studentsData);
    [...data.studentsData].forEach((s) => {
        const schoolId = db.getSchoolIdByName(dbConnection, s.school, function(result) {
            console.log(result);
            console.log((result != null || result != undefined));
            return parseInt(result);
        });

        console.log(schoolId);
        
        studentsDataList.push([
            s.name,
            s.year,
            schoolId,
            s.course,
            s.mainVoucherCode,
            s.megaIdentifier
        ]);

        
    });
    console.log(studentsDataList);
});

module.exports = router;
 

Я не понимаю, в чем проблема. Этот код выполняется без ошибок, имеющих в качестве вывода:

 [
  {
    name: 'M David',
    year: '3',
    school: 'Escola EB1,2,3/JI Quinta Nova da Telha',
    course: '',
    mainVoucherCode: '',
    megaIdentifier: ''
  }
]
SELECT id FROM School WHERE designation = 'Escola EB1,2,3/JI Quinta Nova da Telha';
undefined
[ [ 'M David', '3', undefined, '', '', '' ] ]
null
false
 

As you can see, what I want to do is, for each element in the list, I want to get from the database the id and add it to the new list.

I’ve already tried a lot of different thinks.

I’ve tried with async|await functions with a Promise :
database.js

 (...)
exports.getSchoolIdByName_new = (con, schoolName) => {
    return new Promise((resolve, reject) => {
        con.query(`SELECT id FROM School WHERE designation = '${schoolName}';`, (queryErr, result) => {
            return queryErr ? reject(err) : resolve(result[0].id);
        });
    });
};
(...)
 

new_client.js

 (...)
[...data.studentsData].forEach((s) => {
        (async () => {
            dbConnection.connect();
            const schoolId = await db.getSchoolIdByName(dbConnection, s.school);
            console.log(schoolId);
            dbConnection.end();
        });

        console.log(schoolId);
        
        studentsDataList.push([
            s.name,
            s.year,
            schoolId,
            s.course,
            s.mainVoucherCode,
            s.megaIdentifier
        ]);

        
    });
    console.log(studentsDataList);
(...)
 

выход

 [
  {
    name: 'M David',
    year: '9',
    school: 'Escola EB2,3 D. João I',
    course: '',
    mainVoucherCode: '',
    megaIdentifier: ''
  }
]
PUT /clients-add-client 500 172.545 ms - 11532
 

Я также пытался не использовать запрос из другого файла, т. Е. Использовать его forEach внутри new_client.js:
new_client.js

 (...)
[...data.studentsData].forEach((s) => {
        dbConnection.query(`SELECT id FROM School WHERE designation = '${s.school}';`, (queryErr, result) => {
            if (queryErr) throw queryErr;
            const schoolId = result[0].id;
        });

        console.log(schoolId);
        
        studentsDataList.push([
            s.name,
            s.year,
            schoolId,
            s.course,
            s.mainVoucherCode,
            s.megaIdentifier
        ]);

        
    });
    console.log(studentsDataList);
(...)
 

Это дало мне тот же 500 результат: PUT /clients-add-client 500 172.545 ms - 11532

Я не знаю, что делать дальше, чтобы это сработало.

Ответ №1:

Если вы используете await в цикле, используйте его следующим образом:

 dbConnection.connect();
await Promise.all([...data.studentsData].map(async(s) => {            
    const schoolId = await db.getSchoolIdByName(dbConnection, s.school);
    console.log(schoolId);  
        
    studentsDataList.push([
       s.name,
       s.year,
       schoolId,
       s.course,
       s.mainVoucherCode,
       s.megaIdentifier
    ]);
    return s
}));

dbConnection.end();
console.log(studentsDataList);
 

Комментарии:

1. для await|async функции вызова это работает идеально, спасибо !

Ответ №2:

Я еще не использовал свое продолжение в проекте, можете ли вы объяснить

  1. почему вы использовали null в качестве первого параметра при обратном вызове getSchoolIdByName
  2. И в new_client.js когда вы использовали db.getSchoolIdByName(), в 3-м параметре(обратный вызов результата) вы использовали только один параметр, который равен нулю, как я упоминал в 1 — м пункте

Комментарии:

1. На самом деле это не ответ… сделайте комментарий или отметьте вопрос, чтобы он стал более подробным.

2. Это была ошибка с моей стороны при написании вопроса, я отредактирую. Когда я использовал 2 параметра в функции обратного вызова, была еще одна попытка, похожая на просто обратный вызов(результат).