0

In a CLI-based Ember app, using cli-api-stub to serve static test JSON, I have a Route search action which gets and sets hotel reservation JSON data on controller.model. A View loops the items with {{#each item in model itemController="reservations/-item"}}, and the reservation item gets passed to a 'modifyReservation' action with {{action "modifyReservation" item}}. This action then passes the reservation to this.transitionTo('find-booking.summary', reservation) where the reservation ID should appear as a dynamic segment, but I'm getting undefined for it (../find-booking/undefined).

The JSON:

"ResGlobalInfo": {
  "HotelReservationIDs": {
    "HotelReservationID": [
      {
        "@ResID_Value": "HG34A2"

In ../app/router.js:

this.route('summary', {path: "/:ResGlobalInfo.HotelReservationIDs.HotelReservationID.firstObject.@ResID_Value"}, function(){

In the action function, I can console out the ID with (reservation.ResGlobalInfo.HotelReservationIDs.HotelReservationID[0]['@ResID_Value']), but with (reservation.ResGlobalInfo.HotelReservationIDs.HotelReservationID.firstObject.@ResID_Value) I get a broccoli build error. It doesn't seem to like the @. Of course with this accessor/path as a dynamic segment path I also get undefined. I've tried a few syntax variations and none of them work.

How can I code my router path dynamic segment so it pulls the reservation ID 'attrib' from the JSON object passed to the Route?

albertjan
  • 7,739
  • 6
  • 44
  • 74
bobvan
  • 251
  • 3
  • 9

2 Answers2

0

The route's path definition isn't supposed to have a path that corresponds to your JSON. You should use something like:

this.route('summary', {path: "/:reservation_id" });

Then in your route's model hook:

import Ember from 'ember';

export default Ember.Route.extend({
  model: function(params, transition) {
    // Your code to return the model
    // Sounds something like the following:
    var data = this.controllerFor('search').get('model').findBy('crazy_path', params.reservation_id);
    return ???
  }
)};

But your question is feeling very..... un-Ember-y. This does not feel elegant, and Ember is very elegant.

mpowered
  • 13,162
  • 2
  • 15
  • 18
  • The code was developed by 3rd party Ember experts. I'm just dealing with what we have and am migrating it to Ember CLI since we're not engaged with them anymore. The transitionTo call passes a whole object because the FindBookingSummaryRoute setupController needs a whole model object passed to it. Router is just supposed to pick off the ID as a dynamic segment along the way. This Route has a few entry paths so am not sure what would happen if I add a 'model' hook to go and get reservation by ID. – bobvan Apr 15 '15 at 17:42
  • I suppose that in 'setupController' I can add logic where if model object contains just a reservation ID, then do lookup by ID, otherwise use the normal object. Or in the Route 'modifyReservation' action, I might be able to set the data object on the target controller model before transitioning to it. – bobvan Apr 15 '15 at 17:43
  • Sounds like you're dealing with some really old Ember. A lot of the old conventions like `setupController` are used less and less these days, as ember data or similar persistence libraries make it really easy to just ask for a record and it will either be fetched from the store or from the server if it hasn't been persisted yet. The common model hook in one of my applications would look like `return this.store.find('summary', params.reservation_id);`, and Ember Data decides what to do with it – mpowered Apr 15 '15 at 17:49
  • So in short, my answer is probably not the best for you in light of some pretty crazy other stuff going on :-) – mpowered Apr 15 '15 at 17:50
0

Thanks for your suggestions. The app is based around EAK conventions from about a year ago and while upgrading and migrating, I've been reworking some of the deprecated practices.

Regarding my issue with transitionTo and setupController, it appears that the developer who tried to access the ID from the model/obect in the dynamic segment, must have been experimenting because I don't think this is supported. While I'm not able to find an elegant solution, your mention of the Model hook pointed me to a workaround.

After switching to passing just the ID into 'transitionTo', I then had problems with the destination route/controller/view not having the Model data they need. If I lookup the destination route and set its model (with my reservation object), then when I transitionTo it I get 'this.model is not a function' from the route deserialize hook (because this operation expects the object to be serialized, which it isn't in this case and I don't know how to pass it in that way). After hours of trying every variation on a syntax I could find or think of, I came up with a workaround where I added a 'proxyModel' property to the destination route, which I lookup and set in the origination route. Then in the destination route Model hook, I return 'this.proxyModel'. With this the destination route and controller have the model data they need and the issue with the 'undefined' ID in the router dynamic segment is gone. So this workaround works in the 'find-booking' and 'lookup-booking' routes and has no negative effect on the 'new-book' route, all of which transition to a 'summary' View (but via different routes and controllers).

We haven't got off api-stub test json (now cli-api-stub) to a real webservice and REST API so don't know to what extent we'll have to rework the Model handling when we do that. Ember Data was in beta when this app was done, but I'm sure we'll look into leveraging it when we switch to a real data service.

bobvan
  • 251
  • 3
  • 9
  • Glad to hear it's working for now, but I'm really concerned that you're just piling on technical debt by using Ember in ways it wasn't meant to be used. I know you inherited the code, but I would really take a look at the new documentation and rework some of your old constructs. I promise you won't regret it :-) – mpowered Apr 16 '15 at 19:19
  • Well right, but 'ember data' is still beta and I'm not sure why I need to find a data object by ID when I just passed it into my action - though if I were to bookmark the URL and come back, I expect it should then go get it. But as I say, the projects are unfinished and I'm just getting them into a state where we can set them up with real data services and continue to get on track with the practices the community recommends. I'll be revisiting this workaround/hack later but now have about 100 deprecated warnings to deal with and also how to set up a karma test runner setup in CLI. – bobvan Apr 16 '15 at 21:30
  • Gotcha. Ember Data isn't as beta as you might think, I would give it a shot. You hit the nail on the head with passing your object to the action--if you hit refresh on that route, your app needs to load the model without relying on the action's context. The typical pattern is to deserialize the URL and pass it to the model hook via `params`, and the app should be able to either request it from your persistence layer, or load it from somewhere in the app that has it already. Good luck with the updates! It's a rough road, but it feels pretty good in the end :-) – mpowered Apr 17 '15 at 18:21