如何使用强大的包和mongoose处理POST结果?

时间:2017-04-04 14:20:37

标签: javascript json node.js mongoose formidable

我做了一些关于使用node.js处理POST请求的研究,所以现在正在运行,有点像。 我也知道如何使用mongoose将新的JSON对象保存到mongoDB集合。 我觉得我很接近解决方案,但我找不到答案。

具体问题

现在,我需要一些帮助才能将这两者放在一起。

处理POST请求[ok + - ] => 转换为JSON对象/猫鼬对象 [not okay] =>将其保存到收藏[ok + - ]

控制器代码

这是我正在使用的代码。基本功能有用:

  • 处理已发布的字段并将其“保存”到对象

  • 渲染字段(“字段”对象)

代码:

// controller function for adding a ressource
var post = function(req, res){
  // incoming form
  var form = new formidable.IncomingForm();
  var fields = {};

  console.dir('ceci est bien un post');
  // everytime an field is parsed...
  // This is the place where I should do validation and throw errors if needed
  form.on('field', function (field, value) {
      console.log(field);
      console.log(value);
      fields[field] = value;
  });


  // Once the form is parsed completely
  form.on('end', function () {
      // testing the output
      var ressources = util.inspect(fields, {showHidden: false, depth: null});
      console.dir(util.inspect(fields, {showHidden: false, depth: null}));

      // here save it in mongodb collection
      var ressource = new Ressource(fields);

      // ressource.save(function (err, ressource, isSuccess) {
      //       if (err) {
      //         res.status(400);
      //         res.send('Error occured ' + err);
      //       }
      //       else if (isSuccess === 1) {
      //         res.status(201);
      //         res.send(ressource);
      //       } 
      //       else {
      //         res.status(400);
      //       }
      //     });

      // rendering the page with the results
      res.render('addRessourceView', {
                  title: 'Ressources',
                  fields: ressources
              });
  });

  form.parse(req);
};

这是猫鼬模型:

var mongoose = require('mongoose'),
Schema = mongoose.Schema;

var ressourceModel = new Schema({
  title: { type: String },
  descr_short: { type: String },
  m_visual: { type: Boolean, default: false },
  m_writing:{ type: Boolean, default: false },
  m_moving: { type: Boolean, default: false },
  m_speaking:{ type: Boolean, default: false },
  m_music:{ type: Boolean, default: false },
  age: String,
  minAge: { type: Number }, 
  maxAge: { type: Number }, 
  prerequisite:{ type: Array,
            items: { type: String },
            uniqueItems:  true},
  language: { type: String },
  source: { type: String },
  intra_identify: { type: Boolean, default: false },
  intra_expression: { type: Boolean, default: false },
  intra_comprehension: { type: Boolean, default: false },
  intra_regulation: { type: Boolean, default: false },
  intra_utilisation: { type: Boolean, default: false },
  theme_impulsivity: { type: Boolean, default: false },
  theme_violence: { type: Boolean, default: false },
  inter_identify: { type: Boolean, default: false },
  inter_expression: { type: Boolean, default: false },
  inter_comprehension: { type: Boolean, default: false },
  inter_regulation: { type: Boolean, default: false },
  inter_utilisation: { type: Boolean, default: false },
  details:{ 
    type: Object,
    properties: {
      goals: {  type: Array,
                items: { type: String },
                uniqueItems:  true},
      preparation: String,
      exercices: {  type: Array,
                    items: { type: Object }},
      reflexion: String
    }
  },
  upload:{  type: Array,
          items: { type: Object }}
});

module.exports = mongoose.model('Ressource', ressourceModel);

注意:evrything是“boolean”是一个复选框输入

因此所有这些字段也都在表单中(我刚刚没有实现文件上传)。 基本上我需要帮助的是:

  • 将帖子字段调整为我可以使用mongoose并保存的内容
  • 可能有一些帮助,如何添加一些验证(比如确保minAge小于maxAge或其他东西)
  • 如果您有时间或想要,如何处理文件上传

我真的在这里学习,我只是一个初学者,我试着用我的问题尽可能清楚,我希望你们能够帮助我!

谢谢, Xogno

1 个答案:

答案 0 :(得分:0)

昨天,我花了一整天的时间来研究它,然后我按照自己的意愿来实现它!实际上,在进行了一些研究之后,这并不是很困难:它只需要一些好的逻辑并花时间去做。

免责声明 :我正在使用'formidable'软件包来处理帖子请求,并使用this tutorial了解它。

我首先开始添加带注释的结构,只是为了记下我的代码背后的逻辑思维。然后我开始逐个实现每个字段的代码。每次解析一个字段时都会执行form.on('field'....){},这样我就可以逐个处理它们。为此,我使用了switch(true)倍数cases ... : ... break;。 我添加了所需的验证,向对象添加了一个错误,这样所有字段都被逐个添加到JSON对象中。

关于错误,我在html页面中使用EJS模板显示它们。

然后,一旦一切正常(处理POST字段和处理错误),我唯一要做的就是使用mongoose中的.save方法将其链接(保存)到mongodb集合。

所以这在服务器端发生,并且不会动态发生。也许以后我会用ajax或其他一些框架(Vue.js?)将它重新编码为动态工作,所以它不需要重新加载整个页面并且效率更高。

这是代码,以防它可能有所帮助!

处理发布请求的代码

form.on('field')//逐个处理每个字段

form.on('field', function (field, value) {
        console.log(field);
        console.log(value);



        switch (true) {
            //check if title is not empty, if empty, throw error
            case field === 'title':
                if(value == ''){
                        // then error
                        console.log('titre vide')
                        fields.error = ['title-empty'];
                        fields[field] = value;
                    }
                    else{
                        fields.error = [];
                        fields[field] = value;
                    }
                break;
            // check if description is not empty
            case field === 'short_descr':
                if(value == ''){
                        // then error
                        console.log('titre vide')
                        fields.error = ['descr-empty'];
                        fields[field] = value;
                    }
                    else{
                        fields[field] = value;
                    }
                break;
            // when receiving minAge or maxAge, save it as number
            case (field === 'minAge' || field === 'maxAge') :
                if(field === 'maxAge'){
                    var maxAge = value;
                    if(Number(maxAge) < Number(fields.minAge)){
                        // then error
                        console.log('Error :  maxAge plus petit que minAge')
                        fields.error.push('maxAge<minAge');
                    }
                }
                fields[field] = Number(value);
                break;
            // if 'objectives'
            case field === 'objectives':
                console.log('hey we have an objectif!')
                // when receiving an objective, verify if there's already one
                if('objectives' in fields.details){
                    //then there is already an objective object
                    console.log('adding an objective to the list');
                    fields.details[field].push(value);
                } 
                // then we create the objective entry in fields.details
                else {

                    fields.details[field] = [value];
                    console.log('ajouté aux détails');
                }

                break;
            // if 'materials'
            case field === 'materials':
                console.log('hey we have an material!')
                // when receiving an objective, verify if there's already one
                if('materials' in fields.details){
                    //then there is already an objective object
                    console.log('adding an material to the list');
                    fields.details[field].push(value);
                } 
                // then we create the objective entry in fields.details
                else {

                    fields.details[field] = [value];
                    console.log('ajouté aux détails');
                }

                break;
            // when receiving an exercice, verify if there's already an exercice that exists
            // if there's already an exercice that exists, and this one isn't null, add this one as another exercice
            // verify also if ex_time is a number
            // and insert it under 'details.exercices' (array of objects : {ex_descr: '', ex_time:''})
            // renvoyer une erreur si le temps est vide ou si pas un nombre
            case field === 'exercices':
                console.log('hey we have an exercice!')
                // when receiving an objective, verify if there's already one
                //first check if it's not empty

                if('exercices' in fields.details){
                    if(value === ''){
                        //it's empty, add an error
                        fields.error.push('Empty-' + field + '[' + j + ']');
                        console.log('exercice is empty');
                    }

                    //then there is already an objective object
                    console.log('adding an exercice to the list');
                    var object_exercices = {};
                    object_exercices.ex = value;
                    fields.details.exercices.push(object_exercices);
                    j++;

                } 
                // then we create the objective entry in fields.details
                else {
                    if(value === ''){
                        //it's empty, add an error
                        fields.error.push('Empty-' + field + '[' + j + ']');
                        console.log('exercice is empty');
                    }

                    var object_exercices = {};
                    object_exercices.ex = value;
                    fields.details.exercices = [object_exercices];
                    console.log('ajouté aux détails');
                    j++;
                }

                break;

            //if it's an exercice_time we need to add it to the exercice object in the exercice array
            case field === 'exercices-time':
                console.log('hey we have an exercice-time!')
                // when receiving an exercice-time, verify if there's already an exercice existing
                if ('exercices' in fields.details){
                    if(isNaN(value) || value === ''){
                        // if it's not a number, push a new error
                        fields.error.push('NaNexercice_time[' + i + ']');
                        console.log('but its not a number or is empty ' + i);

                        //recuparate the object of the exercice
                        var object_exercices = {};
                        object_exercices = fields.details.exercices[i];
                        object_exercices.exercice_time = value;
                        // add the value of ex_time to it
                        fields.details.exercices[i] = object_exercices;
                        i++;
                    } else {
                    // if it's a number
                    // and then there is already an exercice object
                    console.log('adding an exercice-time to the last exercice ' + i);

                    //recuparate the object of the exercice
                    var object_exercices = {};
                    object_exercices = fields.details.exercices[i];
                    object_exercices.exercice_time = Number(value);
                    // add the value of ex_time to it
                    fields.details.exercices[i] = object_exercices;
                    i++;
                    }
                }

                break;

            // if "preparation" add it to details.preparation
            case field === 'preparation':

                fields.details[field] = value;
                console.log('ajouté aux détails');
                break;

            case field === 'intra_identification' || field === 'intra_regulation' || field === 'intra_understanding' 
                || field === 'intra_utilisation' || field === 'intra_expression' || field === 'inter_identification' 
                || field === 'inter_expression' || field === 'inter_utilisation' || field === 'inter_regulation' 
                || field === 'inter_understanding':

                //to see if they've at least checked one competence
                fields[field] = value;

                break;

            // otherwise it's a basic input
            default:
                fields[field] = value;
        }
    });

form.on('end')//一旦整个表格被解析

// Once the form is parsed completely
    form.on('end', function () {
        // last error handling

        //test if they've at least added one competence
        if(!fields.intra_identification && !fields.intra_regulation 
        && !fields.intra_understanding && !fields.intra_utilisation 
        && !fields.intra_expression && !fields.inter_identification 
        && !fields.inter_expression && !fields.inter_utilisation 
        && !fields.inter_regulation && !fields.inter_understanding) {
            fields.error.push('No competence selected');
                            console.log('No competence selected');
        }

        // testing the output
            console.dir(util.inspect(fields, {showHidden: false, depth: null}));

        //time to save
        // see if there were errors
        if(fields.error.length < 1){
            //no errors
            //then save it in the database
            console.log('no errors');

            // save it in mongodb collection
            var ressource = new Ressource(fields);

            ressource.save(function (err, ressource, isSuccess) {
                  if (err) {
                    res.status(400);
                    //res.send('Error occured ' + err);
                    res.render('addRessourceView', {
                                title: 'Ressources',
                                fields: fields,
                                saved: false
                            });
                  }
                  else if (isSuccess === 1) {
                    res.status(201);
                    //res.send(ressource);
                        // render the page with save success
                        res.render('addRessourceView', {
                                title: 'Ressources',
                                fields: fields,
                                saved: true
                            });
                  } 
                  else {
                    res.status(400);
                    res.render('addRessourceView', {
                                title: 'Ressources',
                                fields: fields,
                                saved: false
                            });
                  }
                });


        } else {
            console.dir(fields.error);

            // render the page with save success
            res.render('addRessourceView', {
                    title: 'Ressources',
                    fields: fields,
                    saved: false
                });
        }


    });
    form.parse(req);