简体   繁体   中英

MEAN Stack, MongoDB record creation not working

I am developing a MEAN stack application. I am trying to simply create a record in MongoDB from a form. I have verified in the debugger that the data binding is working between the view and the controller. In the server side controller code, checking the req.body before trying to save the record returns "undefined" (see below in the code). In the Angular controller, I have examined the "results" value in the callback when the announcement.$save function is executed and it shows the heading and details values to be populated as they should. However, the data is not persisted to the database and I get the following error:

{ [ValidationError: Announcement validation failed]
  message: 'Announcement validation failed',
  name: 'ValidationError',
  errors:
   { details:
      { [ValidatorError: Path `details` is required.]
        properties: [Object],
        message: 'Path `details` is required.',
        name: 'ValidatorError',
        kind: 'required',
        path: 'details',
        value: undefined },
     heading:
      { [ValidatorError: Path `heading` is required.]
        properties: [Object],
        message: 'Path `heading` is required.',
        name: 'ValidatorError',
        kind: 'required',
        path: 'heading',
        value: undefined } } }

What am I missing? Here is my code:

The form in my html file:

  <form ng-submit="AnnouncementsVm.createAnnouncement()">
    <fieldset class="form-group">
      <label for="heading">Heading:</label>
      <textarea class="form-control" id="heading" rows="1"
        ng-model="AnnouncementsVm.announcementHeading"></textarea>
    </fieldset>
    <fieldset class="form-group">
      <label for="details">Details:</label>
      <textarea class="form-control" id="details" rows="3"
        ng-model="AnnouncementsVm.announcementDetails"></textarea>
    </fieldset>

    <p><input type="submit" value="Submit →"><p>
  </form>

The angular route for this page partial is defined as:

  $routeProvider.
    when('/announcements', {
      templateUrl: '/views/partials/announcements.html',
      controller: 'Announcements.Controller',
      controllerAs: 'AnnouncementsVm'
    });

Here is my controller code:

angular.module('app').
  controller('Announcements.Controller', AnnouncementsCtrl);

function AnnouncementsCtrl($log, $resource) {
  $log.debug('Executing AnnouncementsCtrl');
  var vm = this;
  var Announcement = $resource('/api/announcements');

  Announcement.query( function(results) {
    vm.announcements = results;
  });

  vm.announcements = [];

  vm.createAnnouncement = function() {
    var announcement = new Announcement({
      heading: vm.announcementHeading,
      details: vm.announcementDetails
    });
    announcement.$save( function(result) {
      vm.announcements.push(result);
      vm.announcementHeading = '';
      vm.announcementDetails = '';
    });
  };
}

The REST API route is defined as:

app.post('/api/announcements', announcementsController.create);

The server side controller (announcements-controller.js):

'use strict';

var Announcement = require('../models/Announcement.js');

module.exports.create = function(req, res) {
  var announcement = new Announcement(req.body);
  console.log(req.body); // returns "undefined"
  announcement.save( function(err, result) {
    if (err) console.log(err);
    console.log('Save Announcement Result: ' + result);
    res.json(result);
  });
};

module.exports.list = function(req, res) {
  Announcement.find({}, function (err, results) {
    if (err) throw err;
    res.json(results);
  });
};

And finally, I am using this Mongoose model (Announcements.js)

'use strict';

var mongoose = require('mongoose');

var AnnouncementSchema = new mongoose.Schema({
  heading: {type: String, required: true},
  details: {type: String, required: true},
  image: {type: String, required: false}
});

module.exports = mongoose.model('Announcement', AnnouncementSchema);

How is configured your routes in Angular? Are you passing the controller as 'AnnouncementsVm'?

Have you tried to access the values of the ng-models announcementHeading and announcementDetails from the controller?

Try to put

vm.createAnnouncement = function() {
 $log.log(vm.announcementHeading);
 $log.log(vm.announcementDetails);

});

};

And check if you are getting the correct values

Problem solved. I had not integrated the body-parser for the route so the request wasn't being populated correctly. Here is the updated ExpressJS route:

'use strict';

var bodyParser = require('body-parser');
var path = require('path');
var announcementsController = require('../controllers/announcements-controller.js');

module.exports = function(app) {

  // create application/json parser
  var jsonParser = bodyParser.json();

  // create application/x-www-form-urlencoded parser
  var urlencodedParser = bodyParser.urlencoded({ extended: false });

  app.get('/', function(req, res) {
    res.sendFile(path.join(__dirname, '../../client/views/index.html'));
  });

  // REST API
  app.get('/api/announcements', announcementsController.list);
  app.post('/api/announcements', jsonParser, announcementsController.create);
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM