New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Meteor 0.8.0: joinWithOtherCollection helper is non-reactive? #2046

Closed
dbismut opened this Issue Apr 10, 2014 · 8 comments

Comments

Projects
None yet
3 participants
@dbismut

dbismut commented Apr 10, 2014

Hi,

I'm making a join as described by Chris Mather in one of his EventedMind tutorial.
https://www.eventedmind.com/feed/meteor-make-a-reactive-join-in-the-ui (around 7'20")

In the html file:

{{#with joinWithOtherCollection}}
    {{> item}}
{{/with}}

In the js file:

joinWithOtherCollection: function() {
    var item = this,
    otherItem = OtherItems.findOne({_id: item.otherItem_id});
    return _.extend(item, _.omit(otherItem, '_id'));
}

Until 0.8.0, the join was working reactively, meaning the template {{> item}} was updated when the OtherItems collection was updated. Now with 0.8.0 it looks like joinWithOtherCollection is indeed executed when OtherItems is updated, but the template {{> item}} doesn't update.

Here is a minimal repo that reproduces the issue between 0.8.0 and 0.7.2:
https://github.com/dbismut/meteor-join-test

@avital

This comment has been minimized.

Contributor

avital commented Apr 10, 2014

Thanks for the report @dbismut, this indeed looks like a bug. Turns out, if you don't use {{#with}} and instead do something like:

<div>OtherItem id: {{joinWithOtherCollection.otherItem_id}}, 
     OtherItem value: {{joinWithOtherCollection.value}}</div>

then reactivity works as expected. We'll investigate more.

@avital avital added Blaze labels Apr 10, 2014

@dbismut

This comment has been minimized.

dbismut commented Apr 11, 2014

Hi @avital, interesting, thanks. But that means that I'm not getting the properties in this as in this.value?

@scmart

This comment has been minimized.

scmart commented Apr 16, 2014

I'm having a similar issue with collections and a custom block helper. Just passing the collection to the block helper, ie:

myHelper: function() { MyCollection.find({}) }

{{#myBlockHelper myHelper}}

Does't trigger reactivity.

What I'm finding is that myHelper doesn't even get rerun when the Collection changes.

@scmart

This comment has been minimized.

scmart commented Apr 16, 2014

Let me know if I should open a new issue for this. But I did some more testing and I think the issue is with the Collection not invalidating the computation when it's data is updated.

If I save of the current computation while in the helper, and then later call invalidate() on it, it updates the block helper correctly.

@avital

This comment has been minimized.

Contributor

avital commented Apr 17, 2014

@scmart Your issue is not the same as discussed on this thread.

Calling collection.find() doesn't register a dependency. collection.find().fetch() does. (find() is used with .observe() to get fine-grained added/removed/moved/updated callbacks).

If you have more issues with this, please continue the conversation on meteor-talk.

@scmart

This comment has been minimized.

scmart commented Apr 17, 2014

I had some very confusing sentences in my first post, I've edited them out, and I'll clarify.

What I'm seeing that I think should be working but isn't is that the cursor is passed to the block helper, and inside the block helper, count() is called on the cursor, and it doesn't seem to be registering a dependency.

How ever, if I simply call count in the initial helper, while still returning the cursor, everything works.

@avital avital closed this in 95aaa99 Apr 19, 2014

@avital

This comment has been minimized.

Contributor

avital commented Apr 19, 2014

Fixed, but take note that in your joinWithOtherCollection helper you're mutating the data context. That means you'll have a different data context when different helpers run in the same block, which could be confusing if you do anything other than simply adding properties (that is -- your particular example is probably fine)

If you want to stop mutating the data context, you could replace _.extend(item, _.omit(otherItem, '_id')) with _.extend({}, item, _.omit(otherItem, '_id')).

@avital

This comment has been minimized.

Contributor

avital commented Apr 19, 2014

@scmart I don't think your issue is related to this one. If you're still having problems, please start a new thread on meteor-talk, or if you have a reproduction file a new issue with an app repository.

martijnwalraven pushed a commit that referenced this issue Feb 22, 2016

Fix {{#with}} over a data context that is mutated
In `Spacebars.With` we embox the data context. This commit makes
that emboxing happen modulo `safeEquals`. So now if you
{{#with}} over a helper that returns an object, any time
that helper gets invalidated we re-run the computations in the block.

Fixes #2046 (though notably that example mutates the data context
from within a helper, which could lead to other types of unintended
behavior; it's probably in this particular example -- the data context
just gets added properties)

martijnwalraven pushed a commit that referenced this issue Feb 22, 2016

Fix {{#with}} over a data context that is mutated
In `Spacebars.With` we embox the data context. This commit makes
that emboxing happen modulo `safeEquals`. So now if you
{{#with}} over a helper that returns an object, any time
that helper gets invalidated we re-run the computations in the block.

Fixes #2046 (though notably that example mutates the data context
from within a helper, which could lead to other types of unintended
behavior; it's probably in this particular example -- the data context
just gets added properties)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment