just started to play with emberjs.dont know if this is stupid question or good one, but I am stuck in this for some days and cant figure out why.
in my router.js
Router.map(function() {
this.resource('posts', {path: '/'});
..........
});
.....
this.resource('post', {path: 'posts/:post_id'});
});
and in the route folder i have posts.js setup as following.it has simple js varible used to hold id , title, and body of articles.
export default Ember.Route.extend({
model: function(){
var posts = [
{
id:'1',
title:'lipsome vesicle',
body:"A liposome is a spherical vesicle"},
{
id:'2',
title:'another lipsome vesicle',
body:"A liposome is a another vesicle"}
]
//console.log(posts)
return posts;
}
});
In posts.hbs, the title of each post is shown as link to the to post. of course by looping through each model as |post| and print link-to post.title.
my post.js file simply get the model for posts and returns it.
export default Ember.Route.extend({
model: function(params) {
return this.modelFor('posts').findBy('id', params.post_id);
}
});
In my template for post.hbs I wanted to simply show the title and body for the post .It would have been more redable if it was like post.title or something like that. but i saw some tutorials that does following.
<h1>{{title}}</h1>
<h1>{{body}}</h1>
the url goes to the localhost:4200/post/1
but I cannot see the title and body
when I checked the value in console for
this.modelFor('posts').findBy('id', params.post_id).title , it prints the title
but view is blank.
I have read somewhere, that the controller is the one that is responsible to get the value from model. in that case too, I dont know how to access the returned model in that controller.
I have watched many tutorials, including the raffler example by railscast, since I have background in rails. but those tuts including lot other seems preety outdated. So for all new learners this is frustating and confusing too. Is there good fresh resources except the emberjs guide?
since the title was being printed in console, after many trials when i tried this trick, i finally managed to get my title in individual post.using Ember inspector plug in when i clicked $E console gave me all the post.so i put that object in array and returned that array.
model: function(params) {
// console.log("hell")
console.log(this.modelFor('posts').findBy('id', params.post_id).title);
var post = [this.modelFor('posts').findBy('id', params.post_id)];
return post;
}
then in my view I looped through the array as:
<ul>
{{#each model as |post|}}
<li>{{post.title}}</li>
{{/each}}
</ul>
but I would like to know better way for this.
Related
I've been recently playing with Ember.js utilizing Ember CLI and I am running into an issue with a very simple application I cannot seem to get around.
I have set up an Ember Data fixture adapter with a simple model "Post" which contains two string properties--title & content. I've then proceeded to map a route like so:
Router.map(function() {
this.resource('posts', {path: '/'});
});
Then create a router for posts which simply returns the model data:
export default Ember.Route.extend({
model: function() {
this.store.find('post');
}
});
My template simply iterates through all the posts in the model like so:
{{#each post in model}}
<h3>{{post.title}}</h3>
<p>{{post.content}}</h3>
{{/each}}
The Ember browser extension properly shows my two test posts in the Data tab like so:
But for some reason the template simply will not render the model data. My application.hbs file does contain the appropriate {{outlet}} which I've tested by adding some dummy text into the post.hbs file. This text shows up properly.
Any idea why my model will not display properly would be greatly appreciated. Thanks!
Unless you made an error while typing your code into StackOverflow, your issue is that you're not actually returning anything in your model hook. Change this:
this.store.find('post');
To this:
return this.store.find('post');
I'm pretty new to Ember so hopefully I'm just doing something stupid, but I've been running into a lot of random issues with data not displaying properly and I now see in the Ember Debugger that my data does not exist until I hit a specific model data endpoint. For instance, I have a template to display all products, here's the route:
App.ProductsRoute = Ember.Route.extend({
model: function() {
return this.store.find('product');
}
});
the controller:
App.ProductsController = Ember.ArrayController.extend({
itemController: 'product'
});
the template:
<script type="text/x-handlebars" data-template-name="products">
<div class="row">
{{#each}}
{{name}}
{{/each}}
</div>
</script>
Hitting the endpoint '/products' displays nothing initially, but if I go to '/products/1' I can see the product data in the view (and in the Ember debugger), and then if I navigate back to '/products' that particular product's data (but no other data) displays properly. So I'm super confused as to what I'm doing wrong. As the title suggests, I'm using the DjangoRESTAdapter if that helps narrow things down and here's my app.js as well
window.App = Ember.Application.create({});
window.api_location = 'http://localhost:8000/api';
App.ApplicationAdapter = DS.DjangoRESTAdapter.extend({
host: api_location,
pathForType: function(type) {
return Ember.String.underscore(type);
}
});
App.ApplicationSerializer = DS.DjangoRESTSerializer.extend({
});
App.Store = DS.Store.extend();
Thanks in advance for any help, and let me know if other code snippets would help.
Okay, I finally figured this out: it's an issue with pagination. I was not aware that we had pagination set up for our Django REST Api, so instead of returning a list of objects, it was returning a result object, with the list of products buried in a 'results' attribute. So until I can convince the other devs to turn off pagination I can modify all my queries:
this.store.find('product', {page_size:0});
to override our default page size.
Edit: I'm also trying out modifying the json response on the server side rather than using the djangorestadapter with this library: https://github.com/ngenworks/rest_framework_ember . Hopefully this saves some people some digging...
I'm looking at Ember to see whether it is suitable. One issue that came up is that we have many 'narrow' api calls - these calls return a list with the minimal data to create a list and then the user clicks on a link which goes to the detail view. Due to how link-to helper works, this will bypass the model method in the route. This question has the same issue: Transition from one route to another with a different model in Emberjs But I honestly don't understand the answer he provided. Specifically, he provides this code:
<a {{bindAttr href="somePropertyInYourModel"}}>{{someTextProperty}}</a>
and says:
The property somePropertyInYourModel is a property containing the url to the new page. If the url is in the ember routes it will be as if you where typing that address in the address bar and pressing enter, but without the full reload of the page.
I don't really understand what he's saying (my fault on this). I tried putting in <a {{bindAttr href="{{post}}"}}>{{someTextProperty}}</a> and <a {{bindAttr href="{{post}}"}}>{{someTextProperty}}</a>
but to no avail. Say I have this model:
Hex.Post = Ember.Object.extend({
id: null,
body: null,
isEnabled: null,
createdAt: null
});
How could I get this to work? What is he telling us to do?
thx for help, ember looks really cool but has a lot to know
edit #1
Here's the whole Router list. I want to have a posts view and when the user clicks, it goes to the post view which will be populated to the right. The problem is that the link-to bypasses the model so we really need to reload the model at that point. This would allow us to repurpose much of our existing api. Thx for help
Hex.Router.map(function() {
// put your routes here
this.resource('index', { path: '/' });
this.resource('users', { path: 'users' });
this.resource('loginslogouts', { path: 'loginslogouts' });
this.resource('locations', { path: 'locations' });
this.resource('flaggedcontent', { path: 'flaggedcontent' });
this.resource('posts', function(){
this.resource('post', { path: ':post_id' });
});
this.resource('comments', { path: 'comments' });
});
ahhh, send the id instead of the model, that will retrigger the model hook. Sending a model to the hook makes ember think you have the model, sending an id tells ember to hit the model hook with that id.
{{#link-to 'post' post.id}}{{post.name}}{{/link-to}}
Posted this on the emberjs forums, but SO seems more appropriate.
Hi! I have two routes called classyears and classyear. They're nested like so:
this.resource('classyears', function(){
this.resource('classyear', { path: '/classyear/:classyear_id'});
});
Posterkiosk.ClassyearsRoute = Ember.Route.extend({
model: function() {
return Posterkiosk.Classyear.find();
}
});
Posterkiosk.ClassyearRoute = Ember.Route.extend({
model: function(model) {
return Posterkiosk.Classyear.find(model.classyear_id);
}
});
My templates are:
Classyears:
<div class="yearList">
{{#each item in model}}
{{#linkTo 'classyear' item}}{{item.id}}{{/linkTo}}
{{/each}}
</div>
{{outlet}}
Classyear:
<div class="transformContainer">
{{trigger sizeComposites}}
{{name}}
{{#each students}}
{{partial student}}
{{/each}}
</div>
(The "trigger" helper is from another SO post. The issue was happening prior to adding it, though)
I'm using the Ember-model RESTAdapter. When I load /classyear/:classyear_id, it looks like classyear is rendering its data twice. Once with the correctly-loaded data, and once with no data loaded. The order appears to be random. If the no-data option happens last, it wipes out the correctly-loaded data, leaving a blank page. Vice-versa, and the page content displays just fine.
Any thoughts?
/edit 2: More info:
It looks as though the 0-record reply is from classyears loading. So, it's likely that the zero-record reply is actually just zero records in my hasMany field "students".
If I load /classyears (no class year specified), it only loads once, to get the class year options. If I then click on a class year, it doesn't reload classyears unless I refresh the page, at which time, it loads both, and if the classyears load (a findall) finishes second, it displays no data on the page (other than the classyears template, correctly populated, at the top).
So... maybe my classyears model isn't handling the hasMany field correctly?
I feel like I'm getting closer, but still not sure what's up.
First of all you need to specify a model for a Student, like so:
Posterkiosk.Student = Ember.Model.extend({
id: Ember.attr(),
name: Ember.attr(),
imageUrl: Ember.attr(),
gradyear: Ember.attr()
});
Posterkiosk.Student.adapter = fixtureAdapter;
Now, in your example you are setting the key for the has many to students, but students is an array of objects, not id's, so create a property called student_ids, and pass an array of ids, now that is your key.
Posterkiosk.Classyear = Ember.Model.extend({
students: Ember.hasMany('Posterkiosk.Student', {key: 'student_ids'})
});
If you set embedded: true, then your Classyears server response should come back like this:
{
classyears: [
{..},
{..}
],
students: [
{..},
{..}
]
}
Otherwise, EM would make a separate call to the endpoint on the Student model, and get that data based on the student_ids property.
See the working jsbin.
Tip: RC.7+ removed the underscore from partials, plus the partial name should be in quotes..
As most Emberists would know, I am in the middle of tearing my hair apart at the moment, trying to overcome this vertical wall that EmberJS has so that I can get to the paradise at it's peak.
Here is what I have at the moment:
<script type="text/x-handlebars" data-template-name="dogs">
<h2> Pick a stack to view its cards </h2>
<ul class="nav">
{{#each model}}
<li>{{#linkTo 'dog' this}} {{name}} {{/linkTo}}</li>
{{/each}}
</script>
My routes are defined like this :
App.Router.map(function(){
this.resource('dogs);
this.resource('dog', '/:dog_id');
});
And accordingly, the Model hook for DogRoute is defined as this :
App.DogRoute = EmberRoute.Extend({
model: function(params){
return App.Dog.find(params.id);
}
});
And finally the model is pretty basic in itself:
App.Dog = DS.Model.extend({
name = DS.attr('string')
});
DS is a bunch of fixtures in my case, so I am not going to bother writing this down. However, this doesn't work and I don't know why. Here is the error I keep getting when I visit dogs route, and expect a bunch of links to dog being rendered:
ember-...rc.5.js (line 356)
uncaught exception: More context objects were passed than there are dynamic segments for the route: dog
Can anybody point out what is being done wrong here ?
Note: If I remove the dynamic segments and simply render a dog route inside of my dogs handlebar, (this from handlebar gets taken off) then the links (dog names) do get rendered. However, I need these routes to be dynamic segments and not just hyperlinks with unique ids autogenerated by ember/handlebars.
Your router declaration is wrong. It should me more like this:
App.Router.map(function() {
this.resource('dogs');
this.resource('dog', {path: '/:dog_id'});
});
The error you get
ember-...rc.5.js (line 356) uncaught exception: More context objects were passed than there are dynamic segments for the route: dog
might be related to your route mappings. You should rather define the routes like this:
App.Router.map(function() {
this.resource('dogs', function() {
this.resource('dog', {path: '/:dog_id'});
});
});
And furthermore since this is ember's default behaviour, (see here under dynamic models):
App.DogRoute = EmberRoute.Extend({
model: function(params){
return App.Dog.find(params.id);
}
});
you don't need to define it explicitly, so you can remove it.
The rest seams to be correct as far I can see.
I've also put togheter a working jsbin, have a look.
Hope it helps.