After I learned that the BasicAdapter in Ember Data has been removed, I decided to switch from Ember Data to Ember Model because the API I work with is not totally RESTful (and I need more flexibility in general).
I'm wondering how to "translate" some parts of my code that used to work with the FixtureAdapter from Ember Data.
Here for example, I get a list of profiles but I want to directly redirect to the first one. That means, accessing /profiles will redirect me to something like /profiles/123.
How can I do that with Ember Model? (using the FixtureAdapter, as a starting point).
App.ProfilesIndexRoute = Ember.Route.extend {
redirect: ->
App.Profile.find().then (profiles) =>
#transitionTo 'profile', profiles.objectAt(0)
}
When I do that with Ember Model, I have the following error showing up in my console:
Uncaught TypeError: Object [object Object] has no method 'then'
Thanks for your help!
Try using:
App.Profile.fetch().then(profiles)
The fetch() function will give you a promise that you can call then() on
Related
router.js
this.route('claim', function() {
this.route('new');
this.route('edit', { path: '/:claim_id' });
});
claim.new -> redirect to claim.edit with an empty model. this.transitionTo('claim.edit', model);
Initially, because the model is not saved we get: index.html#/claim/null
When we save the model, it continues to display as index.html#/claim/null instead of say index.html#/claim/87
Is there a way to force the url to refresh?
The only way to force the URL to refresh is to force the route/page to refresh. You can use the refresh method in your route to do that.
To understand why it doesn't update automatically, you have to understand how routes work and how Ember is separate from Ember Data (or any data persistence library).
First, you have to remember that Ember has no knowledge of Ember Data and the specifics of its object model. It just sees plain Ember objects. Ember Data models are more important than other models to you, but Ember isn't aware of that distinction.
Second, the routing in Ember is binding/observer aware. It doesn't watch for changes and update URL state accordingly. It calculates the URL once using the serializer hook, then it leaves it as that. It's not going to recalculate if your model changes in any way. It will only recalculate when it's refreshed.
Short story long, the part of your application that changes the ID of your model and the part that calculates the URL to use aren't aware of each other. You'll have to manually sync them up. Using the refresh method is probably easiest way to do that.
UPDATE: As Kitler pointed out, you can also transition to your route using the new model. It won't fire the model hook so it won't have to do any asynchronous work, but it will still update the URL.
I am trying to figure out how to get data from a custom api. I am using Ember 1.8.1, Ember Data 1.0.0-beta.12 and Ember CLI
In my router i have the following resource
this.resource("communities", {path: '/communities/:community-id/follow-ups'}, function() {});
I have my model defined for the correct response. In my communities router I am trying to get the data from the api like so
this.store.find('community', params['community-id']);
The problem I am having is that I am trying to retrive data from the api endpoint
/communities/{community-id}/follow-ups
But the app is trying to grab the data from
/communities/{community-id}
How do I define the custom resource route to pull from the follow-ups
The router path isn't going to change where the API makes the call to, that just helps Ember change the browser path.
You might want to consider using an adapter if you really need it to hit .../follow-ups.
You'd want to make a CommunitiesAdapter I think. ember g adapter communities, or community, not sure offhand.
And I think the function on it you're looking for is pathForType.
Check it out at http://guides.emberjs.com/v1.10.0/models/customizing-adapters/
You can create a custom adapter for your model in particular but deep nesting on routes can be tricky in Ember and not worth the time if you are in a rush.
Try setting the model of the route directly with a get json
App.NAMERoute = Ember.Route.extend({
model : function(params){
return Ember.$.getJSON(window.apiHost+'/communities/'+params.group_id+'/follow-ups');
}
});
Sometimes simple solutions is what you need
I'm adapting an old JS (no framework) + Rails app as an Ember learning exercise. The idea of the application is that I'm producing a pdf from some data input. In the initial version, there was no user persistence - you could modify the data provided to you in the tables, and then download the PDF of it.
As part of this, I decided to run with a decidedly non-standard ember framework - I'm essentially using Ember Data to load the initial value of the tables. Ember has been a really natural fit for the models I have on the Rails side, and it's made a lot of the more complicated calculations a lot easier. The issue I have is that my initial idea was that when I came to download the PDF, I'd respond to the "save" action on Ember Data with binary data (with an application/pdf header), which I could then use something like FileSaver.js to serve up to the client. Then, I found that EmberData needs JSON return value.
So I base64 encoded my PDF response and fired it back..but it didn't fit the model schema. I thought I'd then do a manual AJAX save -
CalculateYourTV.RostersShowController = Ember.ObjectController.extend({
actions:{
download: function(){
var roster = this.get("model");
var team = roster.get('team');
return this.ajax('*URL GOES HERE*', record.toJSON(), "PUT").then(function(data) {
console.log('called')
console.log(data)
});
},
}
})
And this is where I'm currently stuck. Is there any way to access the URL that EmberData is posting to? I could hard-code a route in the Rails side of things, but I don't like hardcoding routes in here, and I'd like to keep it as reusable as possible (I'm planning to eventually allow data persistance).
Just open chrome dev tools (or firebug) and monitor what's going on in the network tab. You should see any ajax request your application sends out, including the EmberData's save request.
You can change the URL that a specific model will hit by creating custom Ember Data adapters per model.
For example, say you have a person model that needs to not hit the default /persons URL.
App.PersonAdapter = App.ApplicationAdapter.extend({
pathForType: 'special/custom/endpoint/for/folks'
});
That said, Ember Data may not be the best tool here for your PDF "model". You can always use Ember Data for the majority of your models, but use a quick $.ajax for other stuff that doesn't fit your definition of a true model.
You can ask the adapter to build a URL for you -
adapter = #store.adapterFor('application')
url = adapter.buildURL(type, id)
where type is the name of the model, and id is its id.
If want to look up the adapter directly in the container it is
#container.lookup('adapter:application')
Ember has find() method to issue GET towards the server. You can do it with id or without.
I am looking at the official guide and I'm missing something important:
I cannot find the methods which suppose to make my life easier, what are the methods which invoke PUT/POST and DELETE?
I'm using FixtureAdapter, I want to make sure the methods for add/delete and edit, that I'm writing now, will be functional with the RESTAdapter when my server side will be completed.
The fixture adapter doesn't make any calls back to the server, so it's harder to see, but if you look in the restadapter code you can see the calls that do the put/post/delete.
updateRecord: This exsits on the adapter itself, really you should call save on a model and allow ember data to choose the updateRecord on its own. model.save()
createRecord: this should be called from the Class App.KewlKidz.createRecord({id:3, name:"me"});
deleteRecord: call this bad boy on the model. model.deleteRecord()
Rest Adapter
Ember Data Model
I am developing an Ember app. I am serving the API and the ember app from the same server on localhost.
I am pretty sure my API conforms to Ember specifications (although I'm not sure, because conflicting information is given here and here. The second site is linked to from this Ember blog post, and is supposed to be a formalization of Ember's conventions). My API follows the style of the second link, so requesting host/api/users/1, for instance, returns:
{
"users": [{
"username": "jojo"
etc..
}]
}
I know my API is working because I can test it with curl. My problem is that Ember data doesn't seem to be making requests. The Chrome developer tools network tab shows that no request to load the data is being sent when I run App.User.find(). I do however get back this:
Here is the coffeescript code where I define the store:
App.Store = DS.Store.extend
revision: 13
url: 'http://localhost:9292/'
adapter: DS.RESTAdapter
DS.RESTAdapter.reopen
namespace: 'api'
And here is where I define the model, controller, and route for 'User':
App.UsersRoute = Ember.Route.extend
model: ->
App.User.find()
App.UsersController = Ember.ArrayController.extend()
App.User = DS.Model.extend
username: DS.attr 'string'
url: DS.attr 'string'
projects: DS.hasMany 'App.Project'
query_instances: DS.hasMany 'App.QueryInstance'
Am I missing something important here? I am new to Ember and client-side development in general-- perhaps there are obvious solutions here but I'm not aware of them. I'd appreciate if anyone could give a few tips on debugging Ember in general.
Since the framework is very jung there are still not so much tools besides the browser console and a debugging affiniti to debug ember applications, but some stuff exists that can help out with this task.
1. Not nearly ready for prime time but very usefull to inspect ember.js app's is the ember extension for chrome.
2. Since this PR it exists the possibility to set the flag LOG_ACTIVE_GENERATION to get information about what get's generated by ember under the hood. The active generation logging can be simply enabled with:
App = Ember.Application.create({
LOG_ACTIVE_GENERATION: true
});
3. For debugging only but very usefull is the __container__, one can inspect everything ember-data knows about it's models with ease like this:
App.__container__.lookup('store:main').recordCache
This will give you access to the store's recordCache, e.g. all the loaded records.
To inspect more in detail you can access specific records like this:
App.__container__.lookup('store:main').recordCache[7].get('data.attributes')
4. One more thing might be also usefull is to define/override the global error handler to catch all errors happening inside an ember app:
Ember.onerror = function(error) {
console.log(error);
}
5. There is also the possibility to log records directly in your templates by using the log handlebars helper
{{log post}}
or simply set a debugger breakpoint to inspect further
{{debugger}}
Hope this information helps you debug successfully your app.
I was able to solve this problem by upgrading to more recent versions of Ember and Ember data. I think that I was using incompatible versions. I initially generated my project using the Yeoman ember generator. I seriously doubt that this generator would actually give you incompatible versions, so I'm not quite sure what the problem was. It may have been:
An issue with my bower cache
An incorrect statement of the revision number in the DS.Store declaration, which I may have changed because I was unclear as to whether this needed to be included. It is not needed in the latest version, but that's not what the Yeoman generator was providing. So I may have deleted it, then added it back with the wrong version number.
In any case, for anyone else having similar problems I advise you to upgrade your versions of Ember and Ember Data and ensure that they are compatible.