0

I'm trying make synchronous request to db and throw data to express. Here's code

app.get('/', (req, res) => {
  let db = new sqlite3.Database('./Problems.db');
  let sql = 'SELECT * FROM Problems ORDER BY problem_id';
  let data;
  db.all(sql, [], (err, rows, res) => {

    data = DBFetchingAllData(rows, db);
  });
  res.render('pages/index', { data });
});

Since db.all() is asynchronous function, res.renders catches undefined, it's my problem one. Second problem is in function DBFetchingAllData, I supposed it returns rows, but instead returns nothing. If somebody helps me make DBFetchingAllData returns rows properly and make db.all() synchronous, I'll be really appreciate.

function DBFetchingAllData(rows, db) {

    rows.forEach((row, index) => {
    // loop over the problem_questions_id
    // Array with answers
    row.answer = [];
    let row_with_id = _.split(row.problem_questions_id, ',');

    row_with_id.forEach((id) => {
      let sql = `SELECT * FROM QuestionsAndAnswers WHERE id = ?`;
      // use db.all not db.get to fetch an array of answers
      // this call is asynchronous so we need to check if we are done inside the callback
      db.get(sql, [id], (err, answer) => {
        // "answers" is an array here
        row.answer.push(answer);
        // if the index is one less than the length it's the last
        if (index === rows.length-1) {
          // we're done!
          return rows;
        }
      });
    });
  });
}

0

1 Answer 1

1

first problem's solution :

simply call res.render in all callback function

app.get('/', (req, res) => {
  let db = new sqlite3.Database('./Problems.db');
  let sql = 'SELECT * FROM Problems ORDER BY problem_id';
  let data;
  db.all(sql, [], (err, rows, res) => {

    data = DBFetchingAllData(rows, db);
    res.render('pages/index', { data });
  });

});

second solution : you forgot to return rows at the end of the function :

      function DBFetchingAllData(rows, db) {
         return Promise((resolve)=>{

            rows.forEach((row, index) => {
            // loop over the problem_questions_id
            // Array with answers
            row.answer = [];
            let row_with_id = _.split(row.problem_questions_id, ',');

            row_with_id.forEach((id) => {
              let sql = `SELECT * FROM QuestionsAndAnswers WHERE id = ?`;
              // use db.all not db.get to fetch an array of answers
              // this call is asynchronous so we need to check if we are done inside the callback
              (function(row,index){
                 db.get(sql, [id], (err, answer) => {
                   // "answers" is an array here
                   row.answer.push(answer);
                   // if the index is one less than the length it's the last
                   if (index === rows.length-1) {
                  // we're done!
                      resolve(rows)
                   }
                 });
              })(row,index)
            });

          });
        });
    }
Sign up to request clarification or add additional context in comments.

1 Comment

rows returns before rows.forEach(...) or rows.forEach() doesn't change array and returns original array

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.