JSONAPISerializer not returning underscore case to API - ember.js

I am trying to retrieve a single record by returning
singleGroup: this.store.findRecord('individual_group', group_id)
I am then getting this error in the console:
GET http://localhost:4200/api/v1/individual-groups/349 404 (Not Found)
where it seems to be dasherizing individual_groups to individual-groups
Now in the API documentation, an individual group is found by doing a GET request to api/v1/individual_groups/:id
I'm using the JSONAPIAdapter and already have a serializer set up as so:
export default DS.JSONAPISerializer.extend({
keyForAttribute: function(attr) {
return Ember.String.underscore(attr);
},
keyForRelationship: function(attr) {
return Ember.String.underscore(attr);
}
});
but it does not seem to be affecting this particular case.
Is there a way to make sure that when I call this.store.findRecord('individual_group', group_id) it will make the request to the API using
GET http://localhost:4200/api/v1/individual_groups/349
instead of
GET http://localhost:4200/api/v1/individual-groups/349

You should redefine pathForType adapter method. The default implementation uses dasherize:
//as is
pathForType: function(modelName) {
var dasherized = Ember.String.dasherize(modelName);
return Ember.String.pluralize(dasherized);
}
//to be
pathForType: function(modelName) {
var underscored = Ember.String.underscore(modelName);
return Ember.String.pluralize(underscored);
}

Related

emberjs find then filter

In emberjs, considering the following data
(only showing 1 record, normally there would be multiple records):
{ "service": [{
"service-_id":"service_5606ece79bdb05546479739866",
"service-_rev":"5-62dc477c13ef3ea92869bcdf1a67f1a6",
"service-company-name":"ABC co.",
"service-address":"1 2 3 Main Street",
"service-address-line-2":"",
"service-city":"asfd",
"service-state-current":"NY",
"service-zip":"12345",
"service-phone":"111",
"service-fax":"",
"service-email":"asdf#adsf.com",
"service-category-current":"web",
"service-type":"service",
"id":"service_5606ece79bdb05546479739866"
}]}
If I want to return all the records, I can simply do this:
App.ServicesRoute = Ember.Route.extend({
model: function(){
return this.store.find('service');
}
});
However, let's say I want to return all the records that have the current category as 'web'. So in the example data, there is this key: service-category-current
How would I adjust my model to find 'service' then filter where service-category-current = 'web' ?
The best way would be to make your API backend handle query params you send to it (so your records would be filtered on a backend, preferably query params could be used to query the database), so response from server would return only records that match your query. Example store.query call:
this.store.query('service', {
'service-category-current': 'web'
});
Which results in fetching records from URL:
http://api.com/services?service-category-current=web
And you're done. But, if you can't refactor your backend, you could filter records client-side:
model() {
return new Ember.RSVP.Promise(resolve => {
this.store.findAll('service').then(services => {
resolve(services.filterBy('service-category-current', 'web'));
});
});
}
Not ES2015 + using Ember.RSVP.Promise instead of native Promise (maybe will help you with Safari issue):
model: function() {
var that = this;
return new Ember.RSVP.Promise(function(resolve) {
that.store.findAll('service').then(function(services) {
resolve(services.filterBy('service-category-current', 'web'));
});
});
}

Unexpected end of input on ember .save(), empty responseText

I'm doing a PUT request with ember .save() method. Returned status is 200, but I keep getting the "unexpected end of input error". I think it might be because request is returning and empty json responseText as shown here :
http://gyazo.com/6cbb68c1de8fd79a6ec90e6f122dc132
Do you have any ideas how I can solve this problem or the exact reason I get this error?
The RESTAdapter sets the jQuery $.ajax option dataType to json. This causes all responses to be treated as JSON and parsed.
I believe your getting that error because the response is not valid JSON.
There are two ways to fix this:
1. Change the Server Response
Change the server to it returns a valid JSON string and it will stop you getting that error.
2. Implement a Custom Ember Data Adapter
You can implement a custom adapter that sets the dataType option to text when you call .save()`
App.MyAdapter = DS.RESTAdapter.extend({
// By default, the RESTAdapter sets 'dataType'
// to JSON - causing the response text to be
// treated as a JSON resulting in an error
// for responses that are not valid JSON.
// We want to override this if we are not
// expecting JSON from the server
ajaxOptions: function(url, type, options) {
// get the default RESTAdapter 'ajaxOptions'
var hash = this._super(url, type, options);
// override if it's a PUT request
if (type === 'PUT') {
hash.dataType = 'text';
}
return hash;
},
ajaxSuccess: function(jqXHR, data) {
if (typeof data === 'string') {
// return an empty object so the Serializer
// handles it correctly
return {};
} else {
return data;
}
}
});
I've created a JSBin that demonstrates this. When you click the save button the mocked ajax response returns the same string (' ' - looks like one space character?) that your server is returning.
http://emberjs.jsbin.com/durugo/5/edit?js,output

Ember Data use different URL for requests

I am beginner for ember.js. I am tried to use ember data for restful api. However there is some convention on the path. For example App.Post.find() corresponding to http://www.example.com/posts.
However due to my application current pattern, all my list of data is listed under /post/list, what shall i do? here i am using post not posts and not using /posts but /post/list.
Please help.
It's simple enough to change how the adapter builds the url. You just extend the current adapter and override the methods that build the url. In your case I am setting the application adapter (meaning it would apply to all types). I wasn't positive how the url should have been built when you supply a particular id, but I'm pretty sure this is enough to get you started, and you can play the string manipulation game from this point.
App.ApplicationAdapter= DS.RESTAdapter.extend({
pathForType: function(type) {
var camelized = Ember.String.camelize(type);
return camelized; //Ember.String.pluralize(camelized);
},
buildURL: function(type, id) {
var url = [],
host = Em.get(this, 'host'),
prefix = this.urlPrefix();
if (type) { url.push(this.pathForType(type)); }
url.push('list');
if (id) { url.push(id); }
if (prefix) { url.unshift(prefix); }
url = url.join('/');
if (!host && url) { url = '/' + url; }
return url;
}
});
Example: http://emberjs.jsbin.com/OxIDiVU/690/edit

Ember-Data custom adapter for Rhom - FindAll Not working

I am writing an Ember-Data adapter for the Rhom API. I have written the code. I am using it in a simple Todo App. When I create a new item, it gets into the SQLite db. But when I start the app, the already existing ones donot get loaded in the store.
I wrote a console.log in the findAll of my adapter and I can see that it gets an object array from the Rhom API and returns a promise with those results. But why does it not load into the store?
I used the localstorage-adapter as an example and did this. Here is my findAll:
extractVars: function(rhomRecord) {
return rhomRecord.vars();
},
sourceIdToId: function(record) {
record["id"] = record.source_id;
return record;
},
findAll: function(store, type) {
var records = Rho.ORM.getModel(this.model).find('all');
var results = records.map(this.extractVars);
var results = results.map(this.sourceIdToId);
console.log(results);
return Ember.RSVP.resolve(results);
},
As you can see, the console.log prints the following out and its just an array of objects that contain what I need. When I tried with the locastorate, it also returned a same kind of objects.
What do I do?
PS: The extractVars and sourceIdtoId are auxillary to propery extract the objects from the records returned by Rhom.
I'm not really sure if this will help you but I guess just because .find() returns a promise you should use the .then() callback to resolve your model:
findAll: function(store, type) {
return Rho.ORM.getModel(this.model).find('all').then(function(records) {
var results = records.map(this.extractVars);
var results = results.map(this.sourceIdToId);
console.log(results);
return Ember.RSVP.resolve(results);
});
}
Hope it helps.

Ember.JS: Your server returned a hash with the key id but you have no mapping for it

Consider this Ember JS Model:
App.User = DS.Model.extend({
firstName: DS.attr('string')
});
I am able to successfully save the model on the server using this as an XHR request:
{
"user": {
"first_name":"dude"
}
}
but for some reason it gives me an error while returning this XHR response:
{
"id":1,
"user":{
"first_name":"dude"
},
"createdAt":"2013-04-12T03:13:52.382Z",
"updatedAt":"2013-04-12T03:13:52.382Z"
}
The error says: Your server returned a hash with the key id but you have no mapping for it
Ember expects the output to look like:
{
"user": {
"id":1,
"first_name":"dude",
"createdAt":"2013-04-12T03:13:52.382Z",
"updatedAt":"2013-04-12T03:13:52.382Z"
}
}
I think the problem lies in the request itself, but I'm not sure.
Note that I'm using the Sails API as my backend.
You can use a controller to marshal the data format to whatever you need-- but this raises an interesting question about adding support for different front-end conventions to the API blueprints. Right now, Sails.js API blueprints support Backbone out of the box, but obviously that doesn't do you a lot of good if you're using Ember :) I created an issue for that here https://github.com/balderdashy/sails/issues/317.
Here's a hacky example of how you'd use a custom controller to send back data in this format using Sails today:
// api/controllers/UserController.js
module.exports = {
// Create action: (e.g. using default route, you'd POST to /user/create)
create: function (req,res) {
// Grab attributes from request using Ember conventions
var newAttributes = req.param('user');
// Create the user object in the datastore
User.create(newAttributes, function (err, newUser) {
// If there was an error, handle it
if (err) return res.send(err,500);
// Respond with the user object using Ember conventions
res.json({
user: newUser
});
});
}
};
That's a weirdly formatted JSON response. Do you have access to the server?
Ember expects the response as a a hash with root keys
{
"user": {
"id":1,
"first_name":"dude",
"createdAt":"2013-04-12T03:13:52.382Z",
"updatedAt":"2013-04-12T03:13:52.382Z"
}
}