1

my api api/customers return:

{
    "value": [
        {
            "CustomerID": "ALFKI",
            "CompanyName": "Alfreds Futterkiste",
            "ContactName": "Maria Anders",
            "ContactTitle": "Sales Representative",
            "id": "b0d16ed0-c901-4ca3-ba41-7fc74c96909f"
        },
        {
            "CustomerID": "ANATR",
            "CompanyName": "Ana Trujillo Emparedados y helados",
            "ContactName": "Ana Trujillo",
            "ContactTitle": "Owner",
            "id": "3f8ac226-9f78-42df-b337-0505f69792c3"
        },
        {
            "CustomerID": "ANTON",
            "CompanyName": "Antonio Moreno Taquería",
            "ContactName": "Antonio Moreno",
            "ContactTitle": "Owner",
            "id": "09d31df6-69f4-43e4-9cc6-7faa5b8b5e3b"
        }
    ]
}

but ember(/customers) should expects:

{
    "customers": [
        {
            "CustomerID": "ALFKI",
            "CompanyName": "Alfreds Futterkiste",
            "ContactName": "Maria Anders",
            "ContactTitle": "Sales Representative",
            "id": "b0d16ed0-c901-4ca3-ba41-7fc74c96909f"
        },
        {
            "CustomerID": "ANATR",
            "CompanyName": "Ana Trujillo Emparedados y helados",
            "ContactName": "Ana Trujillo",
            "ContactTitle": "Owner",
            "id": "3f8ac226-9f78-42df-b337-0505f69792c3"
        },
        {
            "CustomerID": "ANTON",
            "CompanyName": "Antonio Moreno Taquería",
            "ContactName": "Antonio Moreno",
            "ContactTitle": "Owner",
            "id": "09d31df6-69f4-43e4-9cc6-7faa5b8b5e3b"
        }
    ]
}

I find this answer: GET unconventional JSON with Ember-data

so I try(in my app/serializers/customers.js):

export default DS.RESTSerializer.extend({
  extractArray: function(store, type, payload, id) {
    var newpayload = { customers: payload.value };
    return this._super(store, type, newpayload, id);
  },
});

and in the app/routes/customers.js

export default Ember.Route.extend({
  model: function() {
    return this.store.find('customer');
  }
});

in the app/models/customer.js

export default DS.Model.extend({
  CustomerID: DS.attr('string'),
  CompanyName: DS.attr('string'),
  ContactName: DS.attr('string'),
  ContactTitle: DS.attr('string'),
});

and in the app/templates/customers.hbs:

{{#each}}
    {{CustomerID}}({{ContactName}}
{{/each}}

I open the browser, but it's empty, and no error message, so why it doesn't work?

Community
  • 1
  • 1
ChiangDi
  • 85
  • 1
  • 7
  • you might need to use `{{model.CustomerID}}` unless you are using `ObjectController` with is depreciated – Jakeii May 10 '15 at 12:58

2 Answers2

2

Override typeForRoot in the serializer:

typeForRoot: function(root) {
    if (root === 'value') root = 'customers';
    return this._super(root);
}

The problem here is that the "root" key (the top-level key in the JSON, which Ember Data uses to figure out what model this is supposed to be) is wrong, so you need typeForRoot to patch that up.

(extractArray does something different: it handles array-valued properties. Anyway, it won't work to fix up app/serializers/customers.js (probably should be customer.js) because Ember has no way at this point in time of even knowing that the customer model is involved.)

  • Hello, @torazaburo, i read the source code of typeForRoot https://github.com/emberjs/data/blob/v1.0.0-beta.16.1/packages/ember-data/lib/serializers/rest-serializer.js#L550 It return the singularize name, but i need plural name(I need `customers` not `customer`), so your answer doesn't work. – ChiangDi May 10 '15 at 15:09
  • Models should have singular names. Since yours doesn't (I suggest you change it to reduce future pain), just return `customers` directly from `typeForRoot` without calling `_super`. –  May 10 '15 at 16:04
0

I would do it this way in JavaScript

var apiCustomers = {
"value": [
    {
    "CustomerID": "ALFKI",
    "CompanyName": "Alfreds Futterkiste",
    "ContactName": "Maria Anders",
    "ContactTitle": "Sales Representative",
    "id": "b0d16ed0-c901-4ca3-ba41-7fc74c96909f"
},
{
    "CustomerID": "ANATR",
    "CompanyName": "Ana Trujillo Emparedados y helados",
    "ContactName": "Ana Trujillo",
    "ContactTitle": "Owner",
    "id": "3f8ac226-9f78-42df-b337-0505f69792c3"
},
{
    "CustomerID": "ANTON",
    "CompanyName": "Antonio Moreno Taquer?a",
    "ContactName": "Antonio Moreno",
    "ContactTitle": "Owner",
    "id": "09d31df6-69f4-43e4-9cc6-7faa5b8b5e3b"
}]
};

var emberCustomers = {"customers": []};

emberCustomers.customers = apiCustomers.value;
console.log(JSON.stringify(emberCustomers));

If you are getting your JSON with something like this then here.

App.ApplicationRoute = Ember.Route.extend({
model: function() {
    return Ember.$.getJSON('https://api.github.com/repos/emberjs/ember.js/pulls').then(function(data) {
        var emberCustomers = {"customers": []};
        emberCustomers.customers = data.value;
        return emberCustomers;
    });
}
});
  • Do this where exactly? –  May 10 '15 at 16:05
  • Much easier to do this in the serializer via the example above – David Duncan May 10 '15 at 19:33
  • But now the retrieved data will not be available in the store, for easy use from other parts of you app. So you probably want to do `pushPayload` or the equivalent to get it into the store. At that point, you are duplicating the great majority of work that Ember Data already does for you--issuing the ajax call, and storing the data--but without any of the other things that Ember Data does for you, such as setting headers on the request or supplying the namespace. Far better to simply use Ember Data as it's meant to be used and tell it how to map the root key using `typeForRoot`. –  May 11 '15 at 03:50
  • You are right. There is a good explanation of this method here [link](http://emberjs.com/api/data/classes/DS.RESTSerializer.html#method_typeForRoot) – Steve Bucknall May 11 '15 at 03:57