Having some trouble with a computed in a component


#1

I have an items route that renders a event-item component in an each block like so

{{#each model key="id" as |item|}}
	{{event-item item=item}}
{{/each}}

On the component I am defining it’s tag to be a div with the class I need for CSS. I also want this components tag to have a class name binding that observes a high_bidder_id on it’s model and will mark it as winning if it’s the same as the logged in user. I’ve tried a couple variations on this (the user id is being stubbed in for now)

classNameBindings: ['winning'],
    winning: Ember.computed('item.high_bidder_id', function(){
        return this.get('item').get('high_bidder_id') == 29;
})

But I can’t seem to get anything to work.

Along with this in the component, when I click on it it will transition to an item route where I will want to observe that winning computed on the corresponding component and do something based on it being true in the item template, should I redefine the winning computed in the item route file or is it possible and an okay practice to observe the winning computed on the component?


#2

You seem to be on the right track. I don’t know what it’s not working for you. I made a JSBin based on the described use case. Hopefully that might help: http://emberjs.jsbin.com/wixufiyihu/1/edit?html,css,js,output . It may not be obvious, but the “+” and “-” chars are increment and decrements.

I think it depends on what the “do something” is. If you’re talking about an animation, then I would use an observer in the component to handle this (observers should be used sparingly as they can lead to performance issues, but animations and other manual DOM manipulation are a valid use cases). If you’re talking about making an AJAX call or doing other kind of setup, I would recommend doing it in the setupController hook on the route.


#3

I’m having trouble getting your implementation to work

One problem I’m having is item.high_bidder_id is undefined when I log it to the console from the computed.

The other I should have mentioned before, I am reading this user data from the localstorage using ember-local-storage so I don’t have a service setup. I tried making a service that had a user_id property on it trying to read from the localstorage but it seems the library can’t read the localstorage from the service the same way it does from a route.


#4

Without seeing a reproducible example, there isn’t much advice I can give you. Is possible that the computed property might be firing multiple times and you’re seeing the undefined from the first call. This is common when there are multiple dependencies. Maybe check to see if item is null/undefined. If it is, it’s probably an upstream issue from the computed. If it’s not null/undefined, then it’s probably an issue with the model.

You definitely don’t have to use a service. This was just an example of how you might make the current bidder’s ID globally available. You can use local-storage too.

That’s odd that it doesn’t work. Given their examples, it seems like you should be able to do it with a service instead of a controller. Maybe you could try to open a bug their with a reproducible example?

If it were me, I’d use a service that wraps localstorage. That way all of your components/controllers/routes don’t end up having to have explicit knowledge of the ember-local-storage API. But that’s just my opinion.


#5

Ehem… So it was a small oversight, I added the high_bidder_id later and forgot to add it to the model. I forgot in order to access a property on the model it has to be defined in the model and not just on the object it’s defining. I’m starting to get the hang of this for sure. Thank you for your help! I may end up breaking out the local storage into a service because you have a good point on that, I can inject it where ever I need basically and have much easier access to the user being saved.