8

I have an existing service written with the .NET Web API.

As an example, this service returns JSON in the following format:

[
  { "id": 1, "name": "John" },
  { "id": 2, "name": "Jane" }
]

However, as per the Ember.js Rest Adapter documentation, Ember would expect JSON in the following format:

{
  "persons": [
    { "id": 1, "name": "John" },
    { "id": 2, "name": "Jane" }
  ]
}

Because of this, Ember is returning the following error: Your server returned a hash with the key 0 but you have no mapping for it

By no means do I plan on changing my service API and how it returns data.

Would it be possible to get Ember.js (latest version) to work with the existing data my service is returning? And, if so, how can I implement that?

MilkyWayJoe
  • 9,082
  • 2
  • 38
  • 53
Tyson Nero
  • 2,048
  • 5
  • 26
  • 36

3 Answers3

5

Ember is very flexible in that sense, giving the ability to extend the adapter and serializer in order to integrate your app with any backend API.

You should get the WebAPIAdapter, which is part of the Ember.js Template for Web API.

Additionally, you might wanna take a look into this project I wrote as an example, based on that same template (with some modifications I did on my own). It's still under development and it doesn't feature all the best practices (yet), but I'd say it's a valid example.

You should also take a look into this repo / library (You can install it via NuGet too), which allows you to pre-compile your Handlebars templates directly into Ember.TEMPLATES collection.

MilkyWayJoe
  • 9,082
  • 2
  • 38
  • 53
  • Thanks! In your Ember-Contact-Management-WebAPI, are you doing any special adapting or serialization of data to work with Ember? I noticed your ContactController returns IEnumerable or ContactDto for gets. This is pretty much what my Web API controller exposes, however, the format is not correct on my end. – Tyson Nero Apr 05 '13 at 17:36
  • 1
    Check [this directory](https://github.com/MilkyWayJoe/Ember-Contact-Management-WebAPI/tree/master/Ember-Contact-Management-WebAPI/Scripts/app), you'll see the definition of the Web API Adapter & WebAPISerializer, which handles the JSON payload integration with Ember-Data. These classes are extending the built-in RESTAdapter and RESTSerializer. – MilkyWayJoe Apr 05 '13 at 17:43
  • That's exactly what I needed. For some reason however, using DS.WebAPIAdapter, Ember now hits my REST service url as a singular noun. For instance, before using the RestAdapter, it would hit http://localhost/api/things. Now it hits http://localhost/api/thing. Any ideas? – Tyson Nero Apr 05 '13 at 18:04
  • You should set `plurals` in your adapter. [This](http://stackoverflow.com/a/12206277/54364) syntax was valid for revision 4, but we're currently in revision 12. I honestly don't know if this part of the API has changed – MilkyWayJoe Apr 05 '13 at 18:12
  • I know it's weird, but most APIs in .NET don't pluralize controllers, that's why the [`WebAPIAdapter#pluralize`](https://github.com/MilkyWayJoe/Ember-Contact-Management-WebAPI/blob/master/Ember-Contact-Management-WebAPI/Scripts/app/webapi_adapter.js#L218-L220) simply returns the name of the model the way it is defined, just lower cased. You can either remove this method from the WebAPIAdapter (fallback to RESTAdapter#pluralize) or edit it to return `+ 's'`... – MilkyWayJoe Apr 05 '13 at 18:21
  • Last on this. The [guides](http://emberjs.com/guides/models/the-rest-adapter/#toc_pluralization-customization) talk about this as well. – MilkyWayJoe Apr 05 '13 at 18:42
  • I got the plurals working. However, I'm still bombing out in the sideload function of ember-data.js with the same error as my original post b/c I have no root JSON property. I'm installing VS12 now to install those templates and fire up your project. – Tyson Nero Apr 05 '13 at 20:16
  • You should use that on VS12 with the "update 1" (i haven't tested the update 2). – MilkyWayJoe Apr 05 '13 at 20:18
0

in the web api just return new { object }

var persons = _personbService.GetPeople;
        return new { persons };

this will wrap your object in an object of the same name. If you need to call the object something else just do

new { SomeOtherName = persons; }
racamp101
  • 506
  • 2
  • 12
  • This works only if you are returning a single object from what I can tell. If you have relationships (ex BlogPost/Comments) then the comments are returned inside of BlogPost which seems to break the defaults. The ember web api package takes care of it https://www.npmjs.com/package/ember-web-api – Adam Tuliper Jan 11 '16 at 06:32
0

I was having this issue in ember and found the best solution for me was to build a new serializer and override the normalizePayload method. code below:

export default DS.RESTSerializer.extend({
normalizePayload: function(payload) {
var root = "posts";
var output = {};
output[root] = payload;
return output;

} });

This wraps the initial response and adds the root to it, hope it helps!