【问题标题】:Error connecting Ember client side to Node/ Mongo backend将 Ember 客户端连接到 Node/Mongo 后端时出错
【发布时间】:2016-10-07 23:42:55
【问题描述】:

我正在构建一个 Web 应用程序,客户端使用 Ember,服务器端使用 Node。我使用的数据库是 Mongo。一切都在服务器端运行(我可以使用 Postman 来获取、发布、放置和删除用户。我想我几乎把所有东西都连接到了客户端,但是当我导航到时,Ember 向我抛出了最后一个错误/users 路由:

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();
        }
    }
});

【问题讨论】:

  • 在使用 JSONAPISerializer 时是否有意使用 DS.RESTAdapter 而不是 DS.JSONAPIAdapter ?
  • 另外,我不明白导出默认 DS.JSONSerializer

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


【解决方案1】:

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

要解决你可以做两件事。使用此库使节点输出 JSON api 格式以及数据 id 和属性格式,例如: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 已创建状态代码和用户资源的 json 响应。对于 DELETE 和 PATCH/PUT(更新),您需要返回状态码 200。在所有情况下,您都需要使用 response.json(user) 而不是输出消息。

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

希望对你有帮助。

【讨论】:

    猜你喜欢
    • 2022-01-24
    • 1970-01-01
    • 2014-12-16
    • 2015-10-27
    • 2015-05-16
    • 2023-03-04
    • 1970-01-01
    • 1970-01-01
    • 2022-11-07
    相关资源
    最近更新 更多