将Ember客户端连接到Node / Mongo后端时出错

时间:2016-06-07 21:55:12

标签: javascript node.js mongodb ember.js ember-data

我正在构建一个Web应用程序,它使用Ember作为客户端,Node作为服务器端。我使用的数据库是Mongo。一切都在服务器端工作(我可以使用Postman来获取,POST,PUT和DELETE用户。我想我几乎把所有东西都连接到了客户端,但当我导航到Ember时,Ember给我一个最后的错误/ users route:

ember.debug.js:28535 Error while processing route: users Assertion Failed: You must include an 'id' for user in an object passed to 'push' Error: Assertion Failed: You must include an 'id' for user in an object passed to 'push'

为什么会发生这种情况/如何解决这个问题?

以下是我的server.js文件的相关部分:

var User     = require('./models/user');

// configure app to use bodyParser()
// this will let us get the data from a POST
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());

// Add CORS headers
app.use(function (request, response, next) {
    response.header("Access-Control-Allow-Origin", "http://localhost:4200");
    response.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
    response.header("Access-Control-Allow-Resource", "*");
    response.header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
    next();
});

var port = process.env.PORT || 8080;        // set our port

// ROUTES FOR OUR API

var router = express.Router();              // get an instance of the express Router

// test route to make sure everything is working (accessed at GET http://localhost:8080/api)
router.get('/', function(request, response) {
    response.json({ message: 'hooray! welcome to our api!' });   
});

// more routes for our API will happen here

// REGISTER OUR ROUTES
// all of our routes will be prefixed with /api/v1
app.use('/api/v1/', router);

// START THE SERVER
app.listen(port);
console.log('Magic happens on port ' + port);


// more routes for our API will happen here

// on routes that end in /users
// ----------------------------------------------------
router.route('/users')

    // create a user (accessed at POST http://localhost:8080/api/v1/users)
    .post(function(request, response) {

        var user = new User();      // create a new instance of the User model
        user.name = request.body.name;  // set the user's name (comes from the request)
        user.email = request.body.email; // set the users's email property 
        user.password = request.body.password; //set the user's password property

        // save the user and check for errors
        user.save(function(error) {
            if (error)
                response.send(error);

            response.json({ message: 'User created!' });
        });
    })

    // get all the users (accessed at GET http://localhost:8080/api/v1/users)
    .get(function (request, response) {
        User.find(function (error, users) {
            if (error) response.send(error);
            response.json(users);
        });
    });

// on routes that end in /users/:user_id
// ----------------------------------------------------
router.route('/users/:user_id')

    // get the user with that id (accessed at GET http://localhost:8080/api/users/:user_id)
    .get(function (request, response) {
        User.findById(request.params.user_id, function (error, user) {
            if (error) response.send(error);
            response.json(user);
        });
    })

    // update the user with this id (accessed at PUT http://localhost:8080/api/users/:user_id)
    .put(function (request, response) {

        // use our user model to find the user we want
        User.findById(request.params.user_id, function(error, user) {
            if (error) response.send(error);

            // update the user info
            user.name = request.body.name;
            user.email = request.body.email;
            user.password = request.body.password;

            // save the user
            user.save(function(error) {
                if (error) response.send(error);
                response.json({ message: 'User updated!' });
            });
        });
    })

    // delete the user with this id (accessed at DELETE http://localhost:8080/api/users/:user_id)
    .delete(function (request, response) {
        User.remove({
            _id: request.params.user_id
        }, function(error, user) {
            if (error) res.send(err);

            response.json({ message: 'Successfully deleted' });
        });
    });

这是我的应用程序适配器(在Ember端):

import DS from 'ember-data';

export default DS.RESTAdapter.extend({
    host: 'http://localhost:8080',
    namespace: 'api/v1'
});

这是我的序列化程序(在Ember方面):

import JSONAPISerializer from 'ember-data/serializers/json-api';
import DS from 'ember-data';

export default JSONAPISerializer.extend({
    primaryKey: '_id'
});

export default DS.JSONSerializer;

这是我的模型(在Ember方面):

import Model from 'ember-data/model';
import attr from 'ember-data/attr';

export default Model.extend({
  name: attr('string'),
  email: attr('string'),
  password: attr('string')
});

这是我的users.js路线(在Ember方面):

import Ember from 'ember';

export default Ember.Route.extend({
    model() {
        return this.store.findAll('user');
    },
    actions: {
        createUser(newName, newEmail, newPassword) {
           this.store.createRecord('user', {
               name: newName,
               email: newEmail,
               password: newPassword
           }).save();
        },
        updateUser(user) {
            user.save();
        },
        deleteUser(user) {
            user.destroyRecord();
        }
    }
});

1 个答案:

答案 0 :(得分:0)

从您发布的代码中,您的Application适配器被定义为RESTAdapter,您的序列化器被定义为JSONAPISerializer。 Ember将期望在jsonapi ORG站点上定义JSON API格式

要解决你可以做两件事。使用此库以节点输出具有数据ID和属性格式的JSON api格式,例如:https://github.com/SeyZ/jsonapi-serializer或者只是确保为您的资源使用REST序列化程序和适配器。

尝试像这样定义应用程序序列化程序

import DS from 'ember-data';
export default DS.RESTSerializer.extend({
  primaryKey: '_id',
  serializeId: function(id) {
    return id.toString();
  }
});

确保JSON输出包含以下内容:

{   
  users: [
      {"_id": "13ac3f0d4e29d794d9f62898","name":"", "email": "" },
      {"_id": "13ac3f0d4e29d794d9f62899","name":"", "email": "" }
  ]
}

另一个小问题是服务器端的API端点创建,删除或更新用户返回消息而不是用户资源

user.save(function(error) {
            if (error) response.send(error);
            response.json({ message: 'User updated!' });
        });

您应该始终返回更新的资源,在这种情况下,您需要像在GET / users / ID路由中那样以正确的状态和错误代码返回用户,例如:

创建用户ember时,您希望返回201 CREATED状态代码和用户资源的json响应。对于DELETE和PATCH / PUT(更新),您需要返回状态代码200.在所有情况下,您需要使用response.json(用户)而不是输出消息。

如果您无法处理请求(例如,在已经创建用户电子邮件时),您应该回复422并返回正确的错误消息。请参阅此处理错误:http://emberjs.com/api/data/classes/DS.Errors.html

希望它有所帮助。