I am trying to retrieve record from model using store in Ember. I am doing like this
var rec = this.store.find(App.Recipient);
console.log(rec);
When I am outputting this I am getting this result
Class {toString: function, __ember1397122062151_meta: Object, __ember1397122062151: "ember497", _super: undefined, constructor: function…}
My purpose is to get all records so that I can send them to the server. Also any views on how to iterate over them in the controller?
store.find return a promise so the way to get the records is this:
this.store.find('recipient').then(function(recipients){
recipients.forEach(function(recipient) {
var zip = recipient.get('zip');
})
});
Related
I have this action. Data comes from a form after a createRecord, and it is saved perfectly in the database.
App.ShowController = Ember.Controller.extend({
actions: {
createShow: function() {
var self = this;
var onSuccess = function(res) {
alert('CREATED OK ' + res.get('alias'));
};
var onFail = function() {
alert('err ' + res);
};
self.get('model').save().then(onSuccess, onFail);
}
}
});
The id is generated in the database (Postgres), and I return it in a perfectly formatted json response from the app (made in Mojolicious) {"serverResponses":{"last_id":"500"}} along with a '200' status.
I can see the network response in the console, with the json data.
But how can I access the last_id value in the callback function onSuccess????
In "res" I have the original data I sent to the server, but, obviously its "id" attribute is undefined.
My idea es to "set" the returned id from the database in the "id" of the model.
I have seen a lot of questions about the returning format of the son, serialize problems, and so on, but what I really want to know is WHERE, in WHICH variable or object is the returned data?
Obviously, in case of Fail, I have the same problema. I return a perfectly formatted json with root for ember, but can't find it in the callback function onFail.
Can someone point me in the right direction?
Regards
When you create the record on the server you can return the json of the record, including ID (the same way you would return the json for a GET request). Ember data will then automatically use that response to update the model in its store. Then the argument passed to onSuccess will contain the updated model with the generated ID.
If it's not possible to change the REST api, you'll have to look into extending RESTSerializer to extract the id from the payload.
You need to configure properly your model, for example if you have an x model inside your controller create show action
//create your model locally
//acquisition is for the name of your model
//product_id is just whatever attributes you declare in your model spec
var newAcquisition = this.store.createRecord('acquisition', {
'product_id': this.get('id'),
});
//with save it calls to the server and creates the new model and retrieves a response
newAcquisition.save().then(function(response){
console.log('success - json '+response);
}, function(response){
console.log('fail - err '+response);
});
After this, you don't need to catch response to put and id, if your json response is correct, Ember will handle that response and update your newly created object with that new ID
You can save data in route to controller in setupController function
App.ShowRoute = Ember.Route.extend({
setupController: function(controller, model){
//setup form data
controller.set('formData', data);
},
actions:{
}
});
I have a model with a hasMany relationship:
var Bus = DS.Model.extend({
model: DS.attr('string'),
passengers: DS.hasMany('passenger', {async: true})
});
This seems to work, in that I am able to iterate through the passengers in my template.
Now I want to have an action in my controller that will do something with the passengers. It involves some business logic, and I'll need to iterate through the list of passengers.
My problem is that when I get the passengers from the model in the controller, it is not an array, it is some sort of object. How do I get an array from this object?
Here's what I have tried:
export default Ember.ObjectController.extend({
actions: {
start: function() {
var bus = this.get('model');
var passengers = model.get('passengers');
passengers.then(function(passengerArray) {
var stuff = passengerArray.get('content');
console.log('The thing that I wish were an array of passengers',passengerArray);
console.log('The type of that thing',typeof(passengerArray));
});
}
}
});
It gives me the type object, and it is clearly something wrapped in emberness in a way that is inscrutable to me.
what's the output in the console of a console.log(passengerArray) if you use a decent browser you will get more than just object and actually beeing able to get informations on your object.
Some how when you use model.get("passengers") you get a PromiseArray of your "passengers" . using then is the correct way to get the datas, you will get an object which implements Ember.Array as the parameter of the function called in the then.
If you want a " raw js Array" you can get it by using passengerArray.toArray() function, if your goal is to iterate or get the lenght or what ever you can use the methods provided by emberArray => http://emberjs.com/api/classes/Ember.Array.html
And as you can see in the documentation above content property is at least not public or may even not exist :) (you can also try a passengerArray.get("[]")) to retrieve the "content"
Apart from if it is required/desirable. This would do:
var bus = this.get('model');
var passengersPromise = bus.get('passengers');
passengersPromise.then(function(passengers) {
console.log('RecordArray', passengers);
var passengerArrayWithRecords = passengers.toArray();
console.log('array with records', passengerArrayWithRecords);
var passengerArray = passengers.map(function(record) {
return record.toJSON();
});
console.log('plain array with javascript objects', passengerArray);
});
See it in action here: http://emberjs.jsbin.com/mapiyafaxa/2/edit?html,js,output
Reference:
Ember.Map: http://emberjs.com/guides/enumerables/#toc_map
DS.RecordArray: http://emberjs.com/api/data/classes/DS.RecordArray.html
What you are getting is a promise, since its an async relation. to access the actual array just do:
bus.get('passengers').then(function(passengers) {
// passengers is the actual array
});
When I tried it out using fixtures (so data is already in the store), I was able to get the array using
var bus = this.get('model');
var passengers = model.get('passengers').get('currentState');
I was then able to use passengers[0].get('content') (which is what I assume you want(?)). My guess is that for fetching the data from the server, you will want to use
var bus = this.get('model');
var passengers = model.get('passengers');
passengers.then(function(passengerArray) {
var passengerContent = passengerArray.get('currentState')[0].get('content')
});
I've created a computed property that relies on all records in the store.
I've tried making the property update on adding/removing records with .property('todos.#each.id'), .property('model.#each.id'), .property('#each.id'), .property('#each') and other combinations, no luck so far. :( When i create new records, existing recrods' property would not update.
Here's a fiddle: http://jsbin.com/UDoPajA/211/edit?output
The property is otherTodos on the Todo controller. This property is used by the <select> dropdown list on the page (via {{view Ember.Select}}).
You're out of scope of the collection. You'll need to get access to the todos controller in order to have a computed property based off of its model. needs will handle this use case. http://emberjs.com/guides/controllers/dependencies-between-controllers/
Additionally to make an easy to access alias to the todos controller's model we use computed.alias. http://emberjs.com/api/#method_computed_alias
Todos.TodoController = Ember.ObjectController.extend({
needs:['todos'],
todos: Ember.computed.alias('controllers.todos.model'),
....
foo: function(){
}.property('todos.#each.id')
});
PS note of caution, in your code you are creating multiple instances of Ember Data filter, filter collections are meant to be live collections that are long living and update as records are added/removed from the store. You might just want to grab the model from todos and filter over it instead of creating a new store filter (which then avoids the async code as well, not that that is an issue).
Here's an implementation that would avoid that (no point in using it as a setter, you are only getting from it):
otherTodos: function() {
var model = this.get('model'),
thisId = model.get('id');
var todos = this.get('todos').filter(function (todo) {
return todo.get('id') !== thisId;
});
var selectContent = todos.map( function(todo){
var selectContent = {
title: todo.get('title'),
id: todo.get('id')
};
return selectContent;
});
return selectContent;
}.property('todos.#each.id'),
Here's an updated jsbin of your code: http://jsbin.com/UDoPajA/216/edit
I am trying to set the content of an another controller but my model returns undefined. I've tried everything I could think of to get the queried results prior to trying to set the other controller's model.
Mapmaker.CategoriesController = Ember.ArrayController.extend({
needs: ['filters'],
actions: {
setCategories: function(item) {
var content = this.getFilters(item.id);
console.log(content.fulfillmentValue._data.objects);
this.get("controllers.filters").set('model', content.fulfillmentValue._data.objects);
}
},
getFilters: function(id){
//trying to force sync
return Mapmaker.Tile.fetch('?categories=' + id);
}
});
Any thoughts? let me know if I need to show more code.
I am using ember-model's restful adapter to query the results.
I am getting results but they are just isLoaded:false the second I try to set the controller's model.
fetch in ember model returns a promise, not a model, use the promise
var promise = this.getFilters(item.id);
promise.then(function(content){
console.log(content);
this.get("controllers.filters").set('model', content);
}
I've a simple app that has posts and comments.
If I create a new comment within a post and save it: Ember's default behaviour is to post the new Comment as JSON to "/comment".
I like to have it posted to "/posts/38/comment" and thought about I overwriting the buildURL-method of a Model-Specific RESTadapter to change the URL.
But the buildURL methods signature is only (type, id). Type is just a string of the model name an id undefined for a new comment.
So how can I access the "to be saved" model's content? Or is there another poper way to get the post-id to build the URL? In this example - How to get access to the number 38 within buildURL.
Or am I on the wrong path and there is a better way to archive it?
Define an App.Comment-specific adapter, and customise the createRecord method there:
App.CommentAdapter = DS.RESTAdapter.extend({
createRecord: function(store, type, record) {
var data = {};
var serializer = store.serializerFor(type.typeKey);
serializer.serializeIntoHash(data, type, record, { includeId: true });
// Custom stuff
var postId = record.get('post.id');
var url = this.buildURL(type.typeKey, postId) + '/comment';
return this.ajax(url, "POST", { data: data });
}
});