Uncaught TypeError when trying to get JSON to properly parse in a Ember nested route


#1

A question from an Ember noob…

I’m trying to load content onto my Ember app from a local JSON file, using a MAMP setup as a dev environment. Content is loading fine on a top-level route but I am having trouble getting things to work in a nested route.

my JSON file looks like this:      //books.json { “books”: [ { “id”: 1, “title”: “1984”, “author_name”: “George Orwell” }, { “id”: 2, “title”: “The Shining”, “author_name”: “Stephen King” } ]   }

Then I have an app.js file in the same directory as books.json that looks like this:      // lots of code like Ember.Application.create() removed for brevity…      // The router that defines both the top-level and nested route looks like this: App.Router.map(function() { this.resource(“books”, function(){ this.resource(“book”, { path: “:book_id”}); }); });

// returns the entire list of books
App.BooksRoute = Ember.Route.extend({
  model: function() {
    return $.getJSON("/js/books.json").then(function(data){
      return data.books.map(function(book) {
        book.body = book.title;
        return book;
      })
    });
  }
});

// returns a single book App.BookRoute = Ember.Route.extend({ model: function(params) { return $.getJSON("/js/books.json?id="+params.book_id).then(function(data){ data.book.body = data.book.title; return data.book; }); } });

The template where a single book gets passed to looks like this:

<script type="text/x-handlebars" id="book">
  <article>
    <p>{{body}}</p>
  </article>
</script>

The problem is, when I load nested route into a browser and then refresh it, I get the following error:

Uncaught TypeError: Cannot read property 'title' of undefined   I’ve been using the Ember screencast tutorial here as a guide and also reviewed the JSON API spec looking for an answer but haven’t found one.  Any ideas?

Thanks much!!!


#2

Hey, could you log and inspect the value of data? It says the book property isn’t defined on the data object, so I’m curious what kind of response you get from $.getJSON("/js/books.json?id="+params.book_id)

As an alternative, since you already load all the books in the parent route, you can access this model in child routes. The parent route models are always resolved first when navigating to child routes. You could pull a particular book out of the parent’s model like so:

App.BookRoute = Ember.Route.extend({
  model: function(params) {
    // Get the books model from the parent route
    var books = this.modelFor('books');
    // Extract a particular book
    return books.findBy('id', params.book_id);
   }
});

#3

Hi macu. Thanks VERY much for taking the time to reply to my question…I really appreciate it!

I don’t get a console response to data if i click on a nested route. i.e. if i go to books\1, the console spits nothing out.

But if I refresh while at the books\1 state, the console returns my data object twice. i.e. something like Object {books: Array[2]}.

I did try your other option where I access the model in the child routes. The error disappeared but when I refreshed things, the content that was passed to {{body}} disappears.

So when books\1 initially loaded, the rendered HTML looked something like:

<script type="text/x-handlebars" id="book">
    <article>
      <p>1984</p>
    </article>
  </script>

But when refreshed, the rendered HTML looked something like:

<script type="text/x-handlebars" id="book">
  <article>
    <p></p>
  </article>
</script>