2016-06-07 100 views
0

我正在構建一個Web應用,該客戶端使用Ember,服務器端使用Node。我使用的數據庫是Mongo。一切都在服務器端工作(我可以使用Postman來獲得GET,POST,PUT和DELETE用戶,我想我幾乎已經把所有東西都連接到了客戶端,但是當我導航到Ember時,Ember會拋出一個最後的錯誤在/用戶路線:將Ember客戶端連接到Node/Mongo後端時出錯

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

這裏是我的串行器(在灰燼側):

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

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

export default DS.JSONSerializer; 

這裏是我的模型(在灰燼側):

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

是否有意使用DS.RESTAdapter而不是DS。使用JSONAPIerializer時的JSONAPIAdapter? – bmeurant

+0

另外,我不明白導出默認DS.JSONSerializer – bmeurant

回答

0

從您發佈的代碼中,您的應用程序適配器被定義爲RESTAd apter和你的序列化器被定義爲JSONAPISerializer。 Ember將期望JSON API ORG網站上定義的JSON API格式

要解決您可以做兩件事。使用此庫使數據標識和屬性格式成爲節點輸出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路由中那樣返回具有適當狀態和錯誤代碼的用戶,例如:

創建用戶餘燼時,您返回201 CREATE狀態碼和用戶資源的json響應。對於DELETE和PATCH/PUT(更新),您需要返回狀態碼200.在所有情況下,您都需要使用response.json(user)而不是輸出消息。

如果您無法處理請求(例如,在創建用戶電子郵件時已經採取),您應該回應422並返回適當的錯誤消息。看到這個處理錯誤:http://emberjs.com/api/data/classes/DS.Errors.html

希望它有幫助。