Ember routing, link-to and ember-data


#1

Hi,

In my ember app (I use ember-cli to generate stuff), I have several problems and questions. I am new to ember and I don’t have a frontend background.

//router.js
Router.map(function() {
  this.route('categories');
  this.route('category', { path: 'categories/:category_id' }, function() { });
});

//templates/application.hbs
{{outlet "header"}}
{{outlet "content"}}
{{outlet "footer"}}

//routes/categories.js
export default Ember.Route.extend({
  model: function() {
    return Ember.RSVP.hash({
      categories: this.store.filter('category')
    });
  },
  setupController: function(controller, model) {
    controller.set('categories', model.categories);
  },
  renderTemplate: function() {
    this.render('header', {
      into: 'application',
      outlet: 'header',
      controller: 'header'
    });
    this.render('categories', {
      into: 'application',
      outlet: 'content',
      controller: 'categories'
    });
    this.render('footer', {
      into: 'application',
      outlet: 'footer',
      controller: 'footer'
    });
  }
});

//routes/category.js
export default Ember.Route.extend({
  model: function(params) {
    return Ember.RSVP.hash({
      categories: this.store.filter('category'),
      category: this.store.fetch('category', params.category_id)
    });
  },
  setupController: function(controller, model) {
    controller.set('categories', model.categories);
    controller.set('category', model.category);
  },
  renderTemplate: function(model) {
    this.render('header', {
      into: 'application',
      outlet: 'header',
      controller: 'header'
    });
    this.render('category', {
      into: 'application',
      outlet: 'content',
      controller: 'category'
    });
    this.render('footer', {
      into: 'application',
      outlet: 'footer',
      controller: 'footer'
    });
  }
});

//templates/categories.hbs
{{categories-category categories=categories}}

//templates/components/categories-category.hbs
{{#each category in categories}}
  {{#link-to 'category' category}}
    <div>{{category.name}}</div>
    <img {{bind-attr src="category.getImage" alt="category.name"}}>
  {{/link-to}}
{{/each}}

//templates/category.hbs
{{#if category.hasChildren}}
    <h1>{{category.name}}</h1>
    {{category-category categories=category.children_ids}}
{{else}}
    NOT OK
{{/if}}

I also have a model category.js that uses REST to get the categories from an external API. When I access dev:4200/categories I can see my categories but if I click on their images the url changes to dev:4200/categories/10 but the text loaded is “NOT OK”, and it doesn’t do any ajax request. If I refresh this page, I have 2 ajax requests: api/categories and api/categories/10, also the category name and children are properly loaded and displayed.

  1. What am I doing wrong, why I have access to category only after I refresh the page? (maybe I misunderstood something with Ember)
  2. Also, I would like to have only one ajax request (the one for categories) and then filter by category_id to get the category every time, is this possible?
  3. I want to move the code to get the categories inside routes/application.js http://emberjs.com/guides/models/pushing-records-into-the-store/ “its model hook gets called once when the app starts up” I couldn’t find a way to make the application.categories available in my other routes, is this possible?

I want to state again that I’m using ember-cli with:

DEBUG: Ember      : 1.8.1
DEBUG: Ember Data : 1.0.0-beta.12
DEBUG: Handlebars : 1.3.0
DEBUG: jQuery     : 1.11.2

Thank you.

LE: On my first question, if if visit categories, then categories/10 and then I hit back and forward, the page will make the ajax request and have the category information (display right template…)


#2

If you put a console.log or degugger; line in your category route’s model hook, does it get hit without refreshing or hitting back then forward?


#3

model doesn’t get hit, setupController does get hit but with no model.


#4

First of all:

  • You donot need setupController hook. That is Ember’s default behaviour. Just return Ember.RSVP.hash from model hook and you’re good to go.
  • You might want to use this.store.find in your model hook. As filter is needed to apply a filter function which I don’t see you using.
  • You’re probably overdoing with rendering templates. You should ideally use Ember’s convention over configuration.

With that out of the way, the reason as to why your category call isn’t going is that you’ve already provided the model object in your link-to

{{#link-to ‘category’ category}}

So Ember thinks since you already have the model, it doesn’t need to execute the model hook again. Instead just pass the Id ({{#link-to 'category' category.id}}) and it’ll fire the model hook for category route.


#5

Hi @ankeetmaini thank you for your answer, the link-to works fine now, and my model hook is called. I used filter instead of find because I wanted to move categories inside the application route model hook (since I use them in both header menu and content), and if I also have it inside categories route (I don’t know how to use in my categories.hbs the categories from application route) the app makes two ajax requests for categories. Using filter it will make only one request. I left this part for later improvements, right now I want to make a MVP.