如何正确解决此knex.js承诺?

时间:2018-11-07 08:10:29

标签: javascript knex.js

我正在使用knex,这是从数据库请求后获取question_info对象的代码。

let question_info = knex.select('id', 'question', 'pre_question', 'response_options_id').from('_questions').whereNot({'progress': 100}).andWhere({'school_id': school_id}).orderBy('date_created', 'asc')
        .map((question) => {
            //going through all possible questions
            helpers.debug("Question", question);
            //checking if there are responses
            return knex('_responses').where({'question_id': question.id, 'student_id': event.user.id}).first()
                .then((response) => {
                    //if no responses, return question_info object
                    if(!response){
                        return knex.select('options_json').from('_response_options').where({'id': question.response_options_id}).first()
                            .then((options) => {
                                return {
                                    question_id: question.id,
                                    question: question.question,
                                    pre_question: question.pre_question,
                                    response_options: JSON.parse(options.options_json)
                                }
                            });
                    }
                });     
        }).catch((e) => {
            console.error('Error', e);
        });

当第一个问题已经回答时,我的返回值显示为null。我如何正确地使用knex使返回的数组不包含null。

[
  null,
  {
    "question_id": "2",
    "question": "What is second question?",
    "pre_question": "Hey!!",
    "response_options": [
      {
        "title": "Yes",
        "value": "Yes"
      },
      {
        "title": "Maybe",
        "value": "Maybe"
      },
      {
        "title": "No",
        "value": "No"
      }
    ]
  },
  {
    "question_id": "3",
    "question": "Third Question?",
    "pre_question": "Yo",
    "response_options": [
      {
        "title": "Yes",
        "value": "Yes"
      },
      {
        "title": "Maybe",
        "value": "Maybe"
      },
      {
        "title": "No",
        "value": "No"
      }
    ]
  }
]

1 个答案:

答案 0 :(得分:1)

看起来您的问题是,如果第二个查询确实返回了response,那么您什么都不返回。

// this part of your code seems to be wrong
if (!response) {
  // return choices because there was no response found
  return knex('choices')...
}

应该是这样的:

// this part of your code seems to be wrong
if (!response) {
  // return choices because there was no response found
  return knex('choices')...
} else {
  return response;
}

编辑这将或多或少地说明如何通过单个查询和联接来完成相同的工作(我没有对此进行测试,因此它可能不起作用,但是应该给出实现该方法的一般思路):

let question_info = knex('_questions as q')
  .select(
     'id', 
     'question', 
     'pre_question', 
     'response_options_id',
     'r.id as r_id',
     'options_json'
  )
  .join('_responses as r', builder => {
    builder
      .on('q.id', 'r.question_id')
      .onVal('r.student_id', event.user.id);
  })
  .join('_response_options as ro', 'q.response_options_id', 'ro.id')
  .where('q.school_id', school_id)
  .whereNot('q.progress', 100)
  .whereNull('r.id')
  .orderBy('q.date_created', 'asc')
  .map(notAnsweredQuestion => {
    return {
      question_id: notAnsweredQuestion.id,
      question: notAnsweredQuestion.question,
      pre_question: notAnsweredQuestion.pre_question,
      response_options: JSON.parse(notAnsweredQuestion.options_json)
    };
  }).catch((e) => {
    console.error('Error', e);
  });