findByAttribute inside ObjectController

Im using Ember v1.0.0, Ember-Data v1.0.0-beta.3 and building using Ember-tools.

Inside my order_controller, I’ve got an action called: delivered. Once triggered, I want to make some changes to the current object (no problems here) – but I also want to query an object from this same model and make some changes to it.

Heres my ObjectController:

var OrderController = Ember.ObjectController.extend({
actions: {
	edit: function(){
		this.transitionToRoute('order.edit');
	},
	delivered: function(){
		// orders are sorted by "sequence" attr.
		var current_sequence = this.get('sequence');

		// find the next order in pipeline
		var next_sequence = current_sequence+=1;

		// HERE is the challenge!
		var next_order = App.Order.find({sequence: next_sequence});

		this.set('up_next', false);

		next_order.set('up_next', true);

		this.transitionToRoute('order', next_order.id)

	}
}

});

module.exports = OrderController;

Im using FIXTURES:

Order.FIXTURES = [
	{
		id: 1,
		name: "John Doe",
		email: "john@doe.com",
		telephone: "263663636",
		address: "123 Example Rd.",
            ......
		sequence: 4,
		done: false,
		up_next: false
	},

Basically Im looking for a way to query records from inside the ObjectController with more specific attributes than just ID.

Thanks!

The API of the find methods has changed. Instead of the above, you should write

this.get('store').find('order', { sequence: next_sequence })

All calls to find return a promise, so you should add a then call to work with the result, when it is resolved:

this.get('store').find('order', { sequence: next_sequence }).then(function(order) {
  // Do something with the result
}, function(error) {
  // Handle the error
});

For other API changes, see the TRANSITION doc.

Awesome, thank you!

I’ll add a couple gotcha’s I faced, in case someone else experiencing the same issue is reading this:

  1. The results come as an array, even though I know there is only one result, to retrieve it i do:

    this.get(‘store’).find(‘order’, { sequence: next_sequence }).then(function(order) { // to get the first object var next_order = order.get(“firstObject”);

    // then I can directly manipulate it like so:
    next_order.set("up_next", true);
    

    }

  2. The rest of my delivered action runs before the function inside the .then() block does so if I need to do anything with info retrieved from this query, it better be inside the then() block!

  3. I now had to run the this.transitionToRoute() inside .then(), the scope of this is no longer accurate. To solve it i simply declared

    //outside of the .then() block var that = this

and then:

//from inside the .then() block
that.transitionToRoute("order", next_id);

A couple of quibbles.

  1. I would use orders as the name of the variable with the response data: order.get("firstObject") is weird to read. Expanding on that, if sequence numbers serve as ids in your app, I think there is a way to set that up as primary key with ember-data. That would make more clearer.

I would probably put everything inside the resolved branch (so inside the then(function(order) { ... }), otherwise some changes that the code outside it cause might happen before what’s inside and that’s probably not what you want.

Quoting the Ember Doctor proposal:

1 Like

Small question regarding point #3.

Do you mean to move it to a Route as an actions:{} like I would inside an ObjectController ?

Or with something like a afterModel: hook?

In either case, how would I trigger this transition to occur only after my delivered action is fired?

Within an actions object on the route. The semantics are the same whether you define your action handler on the controller or on the route.

I’m not sure I understand. If you just move the whole delivered handler to the route, it is going to be triggered there, no extra setup is needed.

1 Like