Ember 2.5
I have a page that displays a list of all types of commutes (/commutetypes). To create a new commute type, I go to commutetypes/new.
Once I save the new commute type and transition back to /commutetypes. The new commute type does not display on the list. Can I refresh the model to display it?
// save action in route.
save: function() {
var _this = this;
var com = this.store.createRecord('commutetype', {
name: document.getElementById('nameInput').value,
description: document.getElementById('descriptionInput').value
});
com.save().then(function(){
_this.transitionTo('commutetypes');
});
}
Added model for commutetypes route.
model: function(params) {
return Ember.RSVP.hash({
commutetypes: this.store.query('commutetype', params)
});
},
Can you try to pass in your model inside transitionTo. Also make sure that you endpoint returns a 201 with model instance
com.save().then(function(data){
_this.transitionTo('commutetypes', data);
}
I would also need to make sure that from server side you get instance of model back to ember.
Can you post your route code commute types...maybe you are not loading data there properly
hope it helps
Related
I have an Ember app that uses server-side storage. In the products route, I have a list of products that I display in my product route (which are fetched in the usual way upon entering the route)
{{#each item in sortedProducts}}
{{/each}}
....
fetch
App.ProductRoute = Ember.Route.extend({
model: function(){
return Ember.RSVP.hash({
store: this.store.find('product'),
//other code ommitted
})
}
})
In the controller, I do the sorting
sortProperties: ['date:desc'] //dated added
sortedProducts: Ember.computed.sort('model', 'sortProperties'),
This works, however, I give the user the option to filter the records displayed. Upon clicking a button, an action is called that queries the server for a subset of records (it doesn't just filter the records that are already in the store cache)
actions: {
filterByPriceAndColor: function(){
this.store.find('product', {price: pricevariable, color: colorvariable});
}
}
This queries and returns the desired records, but the list on the page isn't updated i.e. the list on the page still displays all the records that are fetched upon application load.
Question: how do I get the page to update with the new records fetched from the server without a route change, (and will the solution integrate with the computed sort that already exists for ordering the entries by date)
To update your model from an action (or anywhere else) you simple need to set a new value for it and Ember will to the hard work for you.
In your case it should look like this:
actions: {
filterByPriceAndColor: function() {
var promise = this.store.find('product', {price: pricevariable, color: colorvariable});
var self = this;
promise.then(function(data) {
self.set('model', data);
});
}
}
Here is a JSBin demonstrating how it works: http://emberjs.jsbin.com/walunokaro/3/edit
For reasons beyond the scope of this question, I have to populate an Ember data model named Activity in my SearchRoute using Ember.$.getJSON in the model hook like this:
App.SearchRoute = Ember.Route.extend({
model: function (params) {
// Create a promise to return to the model hook. The promise will return a DS.RecordArray.
var modelPromise = new Ember.RSVP.Promise(function (resolve, reject) {
// Make the AJAX call to retrieve activities that match the search criteria
Ember.$.getJSON('/services/activities?query=' + params.q).then(function (data) {
data.activities.forEach(function (activity) {
// If the current activity does not already exist in the store...
if (!this.store.hasRecordForId('activity', activity.id)) {
// add the activity to the store
this.store.createRecord('activity', {
id: activity.id,
title: activity.propertyBag.title
});
}
}.bind(this));
resolve(this.store.all('activity', { query: params.q }));
}.bind(this));
}.bind(this));
// Return the DS.RecordArray as the model for the search route
return modelPromise;
}
});
Then, in my SearchController I do some model sorting and filtering before returning the results from a computed property that is bound to a template that displays the results, like this:
App.SearchController = Ember.ArrayController.extend({
filteredActivities: function () {
var model = this.get('model');
// complete various model sorting and filtering operations
return model;
}.property('model')
});
Here's the template:
<script type="text/x-handlebars" data-template-name="activities">
{{#each item in filteredActivities}}
{{item.title}}
{{/each}}
</script>
Every time a search is executed, the model hook in the SearchRoute is refreshed, the AJAX request is made, and the store is updated with new Activity records, if necessary.
The problem is, even if I do create new records in the store using createRecord and return the new store query results to my model hook, the filteredActivities property does not get fired and the template does not update.
I would think that because I'm returning a newly updated DS.RecordArray to the model hook, that Ember would consider my model as having changed and fire any computed properties watching for changes to the model, but I must be missing something.
Does anybody have any ideas?
Sorry for the long post, and thank you so much for taking the time to consider my issue!
Don't use createRecord. Use push.
http://guides.emberjs.com/v1.10.0/models/pushing-records-into-the-store/
Do you try model.[] or model.#each.propertyNameToObserve in computed property filteredActivities?
Examples with #each: http://guides.emberjs.com/v1.10.0/object-model/computed-properties-and-aggregate-data/,
http://guides.emberjs.com/v1.10.0/controllers/representing-multiple-models-with-arraycontroller/
Since adding a param to our route's model, we can no longer add new items in our Documents ArrayController:
Old Route:
model: function(params) {
return this.store.find('document');
}
New Route:
queryParams: {
owner: {
refreshModel: true
}
},
model: function(params) {
var ownerID = this.get('ownerID')
return this.store.find('document', {owner : ownerID});
}
ArrayController:
actions: {
addItem: function() {
this.store.createRecord('document');
}
The code still loads the documents, but when the addItem action is called, the newly created record is not added to the ArrayController's content. In the old code, clicking addItem immediately added a new document to those on screen. I have confirmed that the server is returning an array, so am not sure why new documents can no longer be added. Any help would be greatly appreciated.
Background
The setup is that a user has documents,but can also view documents of other users. This is the reason why we need to dynamically change the ownerID in the url of documents so we can easily display documents belonging to a specific user.
Find by query (which is what find('foo', {bar:'baz'}) is not a live record set. It only shows the records which were returned by the call to the server.
When you create a new record client side, Ember doesn't know whether or not that server side criteria matches. You either need to use filter with server side and client side criteria (which will make a call to the server and also keep filtering all client side records by the client side filter)
this.store.filter('documents', {document : 'asdf'}, function(record){
return record.get('title') == 'So I Married an Axe Murderer';
});
or if you just want it to always show all client side records you can do this
// make the call
model: function(params){
this.store.find('document', {owner : params.ownerID});
return this.store.all('document');
}
I want to save a record and add to an existing list in emberjs.
I use two forms to simulate multiple models with the same property. But the main focus is on the 2nd one with books.
http://jsbin.com/pexolude/46
I use books: store.find('book',{}) where i dont really know whats the empty object is for but it prevents to have the book record to appear on the list. I only want to have it after the save.
Is it possible to set mockjax's respons accordingly the posted data, so i sont have to use a hardcoded JSON?
Ember-form doesn't appear to handle switching models out underneath it. When you do store.find('foo',{}) you're tricking Ember into finding by query. When it finds by query it only includes the records returned in the results in the collection. When you do find('foo') it returns a live collection that updates when any record is added or removed from the store. You can do a find, then toArray to avoid having it be a live collection. Then you can manually add the record to the collection, and swap out the currently editing model with a new record. Unfortunately, as stated before Ember-forms doesn't update the binding and keeps using the same record.
App.IndexRoute = Ember.Route.extend({
model: function() {
var store = this.store;
return store.find('book').then(function(books){
return {
books: books.toArray(),
book:store.createRecord('book'),
person: store.createRecord('person'),
category: [{id:1,"name":"Fantasy"},{id:2,"name":"Drama"}]
}
});
}
});
App.IndexController = Ember.Controller.extend({
actions: {
some_action: function() {
var self = this;
this.get('model.book').save().then(function(record){
var newRecord = self.store.createRecord('book');
self.get('model.books').pushObject(record);
self.set('model.book', newRecord);
console.log(newRecord);
}, function(error){
console.log('fail');
});
}
}
});
http://jsbin.com/pexolude/48/edit
I am trying to add model to a hasmany relationship. In my route I have:
App.CourseRoute = Ember.Route.extend({
model: function(){
return this.store.find('course','-JNPcfHFQC8FNwyt_-Wh');
}
});
and in my controller I have a save action:
App.CourseController=Ember.ObjectController.extend({
actions: {
save: function() {
var _this = this;
var course = this.get('model');
_this.get('session').get('user').get("courses").pushObject(course)
_this.get('session').get('user').save()
}
}
});
The session property refers a global sessions object that is injected into the controller. This project is using firebase and emberFire data adapter. No errors are being thrown and no data is updated on the firebase backend. I can't seem to figure out what is going on.
Breakpoint your code before the save call and you'll probably see that this.get('session').get('user') has an isDirty property of false. So the save becomes a no-op. You can try to solve that by callingthis.get('session').get('user').notifyPropertyChange('courses').