Using .findBy() with Ember-data-populated array controller

Beez picture Beez · Dec 27, 2013 · Viewed 18.5k times · Source

Background

I'm writing some functional tests to test that my router is navigating and loading my models correctly. So far, so good--even in light of this issue.

I've created a fiddle, for your enjoyment. It doesn't work--I've never had much luck with jsfiddle and ember, in spite of forking @wagenet. But it has more source code to help get an overall picture of what I have going on.

My Biggest Gripe

So my biggest gripe is that the following code doesn't work to retrieve an element with a known id from a controller:

var controller = App.__container__.lookup("controller:postsNew");
var type1Option = controller.get("controllers.types").findBy("TYPE1");

I've done something similar in the setupController hook and it worked. But that was within the context of my application, so it looked more like this:

setupController: function(controller, model) {
    this._super(controller, model);
    this.controllerFor("types").findBy("TYPE1");
}

But even that doesn't work anymore! I'm also working outside my app, now--in a qunit test. So I have to use App.__container__.lookup(), according to everything I've read.

The Root?

What I've found is that controller.length is undefined--which is causing .findBy() to fail. And the items exist in the array...at least, I can see them by doing controller.toArray().

The Temporary Solution

The following is what I have to do instead:

var controller = App.__container__.lookup("controller:postsNew");
var type1Option = null;
$.each(controller.get("controllers.types").toArray(), function(index, elm) {
    if (elm.get("id") === "TYPE1") {
        type1Option = elm;
        return true;
    }
});

This is obviously not as clean.

So, Questions

  • Is .findBy() broken?
  • Am I doing .findBy() wrong?
  • How do you use .findBy()??

Answer

Kingpin2k picture Kingpin2k · Dec 28, 2013

findBy takes 2 arguments, property key to test against, and value to find (it defaults to true if not passed in). Essentially you are searching for a model with a property TYPE1 that's true

You're probably looking to do this

findBy("id", "TYPE1")

http://emberjs.com/api/classes/Ember.Array.html#method_findBy

Returns the first item with a property matching the passed value. You can pass an optional second argument with the target value. Otherwise this will match any property that evaluates to true.