无法读取POST json对象上的属性

时间:2019-03-21 15:47:50

标签: javascript node.js json express

我遇到错误

TypeError: Cannot read property 'tasks' of undefined

当我在api上尝试新的POST请求时,以下是我要制作的请求正文

{
    "name": "tecnica1",
    "description": "tecnica ensino1",
    "rules": ["Regra1", "Regra2"],
    "delivery_mode": ["Face to face", "Blended"],
    "interaction": ["Group based", "One to many"],
    "interrelationship": "High",
    "motivation": "High",
    "participation": ["Medium", "Low"],
    "performance": ["Low", "None"],
    "scope": ["Open ended", "Close ended"],
    "feedback_use": "Low",
    "target_audience": [15, 17],
    "learning_objectives" : [
        {
            "knowledge_category": "Factual",
            "behaviour": "Comparing",
            "subject_matter": "teste",
            "conditions": "teste",
            "degree": "teste"
        },
        {
            "knowledge_category": "Procedural",
            "behaviour": "Explaining",
            "subject_matter": "teste"
        }

    ],
    "affective_objectives": "teste",
    "social_objectives": "teste",
    "structure": {
        "modules": [{
            "name": "teste",
            "phases": [{
                "name": "teste",
                "tasks": [{
                    "type": "tipo1",
                    "description": "teste",
                    "role": "Student",
                    "resources": ["Recurso1", "Recurso2"]
                }]
            },
            {
                "name": "test2",
                "tasks": [{
                    "type": "tipo1",
                    "description": "teste",
                    "role": "Student",
                    "resources": ["Recurso1", "Recurso2"]
                },
                {
                    "type": "tipo1",
                    "description": "teste",
                    "role": "Student",
                    "resources": ["Recurso1", "Recurso2"]
                }]
            }]
        }]
    }
}

该错误是指结构/模块/阶段下的嵌套对象“任务”

这是描述我要发布的对象的模型以及处理该对象的控制器函数。

Tecnica.js

const mongoose        = require('mongoose');
const Schema          = mongoose.Schema;
const idValidator     = require('mongoose-id-validator');

const EVAL  = ['High', 'Medium', 'Low', 'None']

let TaskSchema        = new Schema({

  type  : {
    type      : String,
    required  : true
  },

  description  : {
    type      : String,
    required  : true
  },

  role  : {
    type      : String,
    required  : true,
    enum      : ['Student', 'Staff']
  },

  resources : [String]

});

let PhaseSchema       = new Schema({

  name  : {
    type      : String,
    required  : true
  },

  tasks  : {
    type  : [TaskSchema],
    validate  : {
      validator: function(v){
        return v.length >= 1;
      },
      message : 'At least one task should be defined.'
    }
  }
});

let ModuleSchema      = new Schema({

  name  : {
    type      : String,
    required  : true
  },

  phases  : {
    type  : [PhaseSchema],
    validate  : {
      validator: function(v){
        return v.length >= 1;
      },
      message : 'At least one phase should be defined.'
    }
  }
});


let EstruturaTecnicaSchema   = new Schema({

  modules : {
    type      : [ModuleSchema],
    validate  : {
      validator: function(v){
        return v.length >= 1;
      },
      message : 'At least one module should be defined.'
    }
  }
});

let LearningSchema    = new Schema({
  knowledge_category : {
    type     : String,
    required : true,
    enum     : ['Factual', 'Conceptual', 'Procedural', 'Metacognitive']
  },

  behaviour : {
    type     : String,
    required : true
  },

  subject_matter : {
    type     : String,
    required : true
  },

  // Optinal/if any
  conditions  : String,
  degree      : String
});


/*
  Technique defined by:
  Init Data + Tlt Data.
  Init Data consists of name, description and set of rules.
  Tlt Data is defined by context and structure

*/
let TecnicaSchema     = new Schema({

  //Init Data
  name  : {
    type     : String,
    required : true
  },

  description  : {
    type     : String,
    required : true
  },

  rules : [String],

  //Context
  delivery_mode : {
    type     : [String],
    required : true
  },

  interaction : {
    type     : [String],
    required : true
  },

  // Perception
  // interrelationship, motivation, participation, performance

  interrelationship : {
    type     : [String],
    required : true,
    enum     : EVAL
  },

  motivation : {
    type     : [String],
    required : true,
    enum     : EVAL
  },

  participation : {
    type     : [String],
    required : true,
    enum     : EVAL
  },

  performance : {
    type     : [String],
    required : true,
    enum     : EVAL
  },

  scope : {
    type     : [String],
    required : true
  },

  feedback_use : {
    type     : [String],
    required : true,
    enum     : EVAL
  },

  target_audience : {
    type     : [Number],
    required : true
  },

  learning_objectives : {
    type      : [LearningSchema],
    validate : {
      validator: function(v){
        return v.length >= 1;
      },
      message : 'At least one learning objective should be defined.'
    }
  },

  affective_objectives : {
    type  : [String]
  },

  social_objectives : {
    type  : [String]
  },

  structure : {
    type      : EstruturaTecnicaSchema,
    required  : true
  },

  psychologist : {
    type      : mongoose.Schema.Types.ObjectId,
    ref       : 'User',
    required  : true
  }
});

TecnicaSchema.plugin(idValidator);


module.exports = mongoose.model('Tecnica', TecnicaSchema);

tecnicas.controller.js

function create(req, res) {

  let tecnica                   = new Tecnica();
  let learning_objectives       = req.body.learning_objectives;
  let structure                 = req.body.structure;
  let modules                   = req.body.structure.modules;
  let phases                    = req.body.structure.modules.phases
  let tasks                     = req.body.structure.modules.phases.tasks;

  phases.tasks                  = tasks.map(t => { return t; });
  modules.phases                = phases.map(p => { return p; });
  structure.modules             = modules.map(m => { return m; });

  tecnica.name                  = req.body.name;
  tecnica.description           = req.body.description;
  tecnica.rules                 = req.body.rules;
  tecnica.delivery_mode         = req.body.delivery_mode;
  tecnica.interaction           = req.body.interaction;
  tecnica.interrelationship     = req.body.interrelationship;
  tecnica.motivation            = req.body.motivation;
  tecnica.participation         = req.body.participation;
  tecnica.performance           = req.body.performance;
  tecnica.scope                 = req.body.scope;
  tecnica.feedback_use          = req.body.feedback_use;
  tecnica.target_audience       = req.body.target_audience;
  tecnica.learning_objectives   = learning_objectives.map(l =>  {
    return  l;
  });
  tecnica.affective_objectives  = req.body.affective_objectives;
  tecnica.social_objectives     = req.body.social_objectives;
  tecnica.structure             = req.body.structure;
  tecnica.psychologist          = req.user;

  tecnica.save()
  .then(t => {
    return res.status(201).json(t);
  })
  .catch(utils.handleError(req, res));

}

如何解析任务?

我已经在使用带有选项的body-parser

  app.use(bodyParser.urlencoded({ extended: true }));
  app.use(bodyParser.json());

1 个答案:

答案 0 :(得分:0)

modulesphasestasks是数组。你不能打电话 req.body.structure.modules.phases.tasks

req.body.structure.modules是一个数组 req.body.structure.modules.phases不存在,并且是undefined

分配此类属性的更好方法:

function create(req, res) {

  let tecnica                   = new Tecnica();
  Object.assign(tecnica, { ...req.body });
  tecnica.psychologist          = req.user;

  tecnica.save()
  .then(t => {
    return res.status(201).json(t);
  })
  .catch(utils.handleError(req, res));

}