1

I have an object route in the router (using ember-data with standard REST backend) with connectOutlets that simply deserializes and loads the object and plugs it into the outlet.

  # inside router 
  action: Ember.Route.extend
    route: 'object/:object_id'

    connectOutlets: (router, object) ->
      unless object.get('isLoaded') # What goes here to tell if the object wasn't found?
         #
         #  handle this case (e.g., redirect)
         #
      else # otherwise proceed as normal
        router.get('applicationController').connectOutlet('object', object) 

When I navigate to localhost/#object/object_that_doesnt_exist, the router deserializes the url, attempts to load the object (server logs show a HTTP GET request for localhost/objects/object_that_doesnt_exist), gets a 404, and instead creates a new object with id set to object_that_doesnt_exist.

I want to detect this and handle the case. Right now, I am checking the isLoaded property, which does differentiate between existing models and nonexisting models, but I'm not sure this is the best way.

Ideally, there would be a method similar to Rails' new_record?.

sly7_7
  • 11,961
  • 3
  • 40
  • 54
Sherwin Yu
  • 3,180
  • 2
  • 25
  • 41

2 Answers2

2

Have a look at the source code: https://github.com/emberjs/data/blob/master/packages/ember-data/lib/system/model/model.js#L15

isError: retrieveFromCurrentState,
isNew: retrieveFromCurrentState,
isValid: retrieveFromCurrentState,

Haven't tried myself but isNew might be what you are looking for.

Alexander Zaytsev
  • 2,744
  • 1
  • 16
  • 8
2

You don't want to do this in connectOutlet because it will require the application to wait while it checks the DB for the record.

Personally I would use a custom find method in my adapter and handle the 404 error from there.

find: function(store, type, id) {
  var root = this.rootForType(type);

  this.ajax(this.buildURL(root, id), "GET", {
    success: function(json) {
      this.didFindRecord(store, type, json, id);
    },
    statusCode: {
      404: function() {
        # I can never remember the exact semantics, but I think it's something like this
        this.trigger('didNotFindRecord');
      }
    }
  })
}


connectOutlets: (router, object) ->
  router.get('store').addObserver('didNotFindRecord', this, 'handle404')
  router.get('applicationController').connectOutlet('object', object) 

handle404: ->
     # 
     #  handle this case (e.g., redirect)
     #

You will have to be careful to tear down the observers correctly though.

Bradley Priest
  • 7,438
  • 1
  • 29
  • 33
  • Thanks for the answer -- I don't think 'waiting for the application to check the DB for the record' is a relevant objection for not doing this in connectOutlets because I'm using ember-data and by the time connectOutlets is called, the app has already attempted to fetch the object (whether it exists or not in the DB). I'm using ember-data for my adapter -- I'm assuming I don't need to tinker with it too much out of the box. – Sherwin Yu Dec 11 '12 at 02:13
  • Sherwin: I think asynchronous UIs should be an important part of any modern web app, and that waiting for an AJAX call to complete is an incredibly relevant objection. That being said, if you're just hacking together something for fun, go for it. As for tinkering with ember-data, I believe a better way of handling this will be added to the library as soon as it stabilizes, so it's just adding non-existent features – Bradley Priest Dec 11 '12 at 03:03