Search code examples
ember.jsmodelember-dataember-cli

How to configure Ember-data to combine dependents with parent object?


I have following resources

  1. Question /api/v1/questions/{questionID}
  2. Category /api/v1/categories/{questionID}
  3. Comment /api/v1/comments/{questionID}
  4. Recommendations /api/v1/recommendations/{questionID}
  5. Pattern answers /api/v1/patternanswers/{questionID}

The API is made to deliver children objects by parent object ID, and I don't see that compatible with Ember-data out-of-the-box (or without hacking, only proper configuration).

Question resource gets me JSON like this:

{
    "errors": [],
    "data": {
        "created": 1439832769693,
        "updated": 1440012378723,
        "userID": 20,
        "user": {
            "password": null,
            "created": null,
            "updated": null,
            "photoID": null,
            "photo": null,
            "email": "notsoimportant@host.com",
            "emailConfirmed": false,
            "phoneNumber": null,
            "phoneNumberConfirmed": false,
            "accessFailedCount": 0,
            "id": 20,
            "userName": "qwerty"
        },
        "categories": [], // does not exist in json
        "addCategoriesIDs": [],
        "removeCategoriesIDs": [],
        "recommendations": [],
        "removeRecommendstionIDs": [],
        "patternAnswers": [],
        "removePatternAnswerIDs": [],
        "comments": [], //does not exist in json
        "hint": null,
        "version": 1,
        "commonVersion": 8,
        "id": 7,
        "questionText": "What is your name?",
        "weight": 0,
        "answerType": 0,
        "status": 0,
        "estimatedTime": null,
        "private": false
    }
}

Properties "patternAnswers", "recommendations" are in the question, but "comments" and "categories" are not. More over I don't get Question with listed properties filled with IDs of dependent objects. I wish I could get

{
    "errors": [],
    "data": {
        "comments" : [11,12,13,14],
        "categories" : [21,22,23,24],
        "recommendations": [1,2,3,4],
        "removeRecommendstionIDs": [],
        "patternAnswers": [5,6,7,8],
        "removePatternAnswerIDs": [],
        "hint": null,
        "version": 1,
        "commonVersion": 8,
        "id": 7,
        ....
    }
}

.. but they are empty :(

I would like to configure my Question Model and Question Serializer to grab all that dependent objects asynchronously.

I would like to get everything just issuing

var QuestionModel = this.store.find('question',7);
var comments = QuestionModel.get('comments');
var categories= QuestionModel.get('categories');
var recommendations= QuestionModel.get('recommendations');
var patternAnswers= QuestionModel.get('patternAnswers');

How is it feasible?


Solution

  • If you want this to work out-of-the-box, you should set up your API according to ember guides (http://guides.emberjs.com/v2.0.0/models/the-rest-adapter/). That said, endpoints must be:

    1. Question /api/v1/questions/{questionID}
    2. Category /api/v1/categories/{categoryID}
    3. Comment /api/v1/comments/{commentID}
    4. Recommendations /api/v1/recommendations/{recommendationID}
    5. Pattern answers /api/v1/patternanswers/{patternanswerID}

    And payload from GET /api/v1/questions/{questionID} should look like:

    {
        "question": {
            "categories": [], // an array of ids
            "recommendations": [], // an array of ids    
            "patternAnswers": [], // an array of ids
            "comments": [], // an array of ids
            "id": Number, // question id
            ... // others
        }
    }
    

    Otherwise, you need to change the default behavior of DS.Model or/and RESTAdapter, or use QuestionController with attached models of Category, Comment, etc. Or you can pack all things in model and setupController hooks of route represented that data.

    I suggest you to answer yourself these questions:

    1. Do you really need such a complex model at the client side? The only reason you might need model is the requirement to create/change data in that set all at once.
    2. Can you change the API? It's better to change API in regard to REST specifications, to not maintain spaghetti at client side.
    3. How far you can go with changing the API? There is another but similar scheme:

      Question /api/v1/questions/{questionID}

      Category /api/v1/questions/{questionID}/categories/{categoryID}

      Categories /api/v1/questions/{questionID}/categories

    It's a bit easier to configure in Ember then your version.