cpursley
cpursley

Reputation: 182

Read JSON data from non-RESTful API with ajax in Ember

I'm building a little hacker news reader for a learning project where the API I'm reading is a bit non-standard (so ember-data is out of the question unless someone knows how to shoehorn it).

List of items are here: http://node-hnapi.herokuapp.com/news while an individual item is like this: http://node-hnapi.herokuapp.com/item/6696691

Here's what I have going on so far: http://jsbin.com/OFeCoR/22/edit?html,js,output

App = Ember.Application.create()

baseURL = "http://node-hnapi.herokuapp.com"
newsURL = "/news"
itemURL = "/item/"

App.Items = Ember.Object.extend(  
  id: ""
  title: ""
  url: ""
  points: ""
  user: ""
  time_ago: ""
  comments_count: ""
  slug: (->
    @get("id")
  ).property("id")
)

App.Items.reopenClass 
  all: ->
    Ember.$.getJSON(baseURL + newsURL).then (response) ->
      items = []
      response.forEach (n) ->
        items.push App.Items.create(n)
      items     

App.Router.map ->
  @resource "items", ->
    @route "item",
      path: ":slug"

App.IndexRoute = Ember.Route.extend
  beforeModel: ->
    @transitionTo "items"

App.ItemsRoute = Ember.Route.extend
  model: ->
    App.Items.all()

App.ItemsItemRoute - Ember.Route.extend
  model: (params) ->
    itemID = App.Items.findProperty("id", params.id)
    Ember.$.getJSON((baseURL + itemURL + itemID).then (response) ->
      item = []
      response.forEach (i) ->
        item.push App.Item.create(i)
      item
    )

Basically I'm trying to grab the ID from an "item" in items to use it for the slug and in the ItemsItemRoute, shove it into the URL to get the individual item properties. I think this is where I'm going wrong (ItemsItemRoute).

I think it might make sense to only get the individual item data when a link / action is clicked instead all of them from the start. Any thoughts on how to go about this?

Upvotes: 0

Views: 726

Answers (2)

Kingpin2k
Kingpin2k

Reputation: 47367

If you wanted to have a resource that's separate from the parents resource you should change your router to something like this:

App.Router.map ->
  @resource "items"
  @resource "item",
    path: ":slug"

But if you just wanna grab the already fetched model and keep the same look, there is no reason to refetch the data since you've already gotten it, you should just be using modelFor and grabbing it from the parent resource

http://jsbin.com/eCOzOKe/1/edit

App.ItemsItemRoute = Ember.Route.extend
  model: (params) ->
    itemsModel = @modelFor("items")
    item = itemsModel.findProperty("id", params.slug)
    item

Additionally, you don't need to use the word slug, you can just use :id and remove the computed property from your model that just returns the id as slug.

Upvotes: 1

Marcio Junior
Marcio Junior

Reputation: 19128

Your App.ItemsItemRoute have some errors:

# you are using minus (-) this is a assigment and a equals (=) is needed
App.ItemsItemRoute - Ember.Route.extend
  model: (params) ->
    # App.Items.findProperty don't exist and params.id isn't present just params.slug because you mapped your route with path: ":slug"
    itemID = App.Items.findProperty("id", params.id)
    Ember.$.getJSON((baseURL + itemURL + itemID).then (response) ->          
      item = []
      # this will return just one item, no forEach needed
      response.forEach (i) ->
        item.push App.Item.create(i)
      item
    )

I updated to the following:

App.ItemsItemRoute = Ember.Route.extend
  model: (params) ->    
    Ember.$.getJSON(baseURL + itemURL + params.slug).then (response) ->
      App.Items.create(response)

And added a {{link-to}} in each item to be able to transition to ItemsItemRoute

This is the updated jsbin http://jsbin.com/OlUvON/1/edit

Upvotes: 1

Related Questions