Understanding reactiveVar, reactiveDict and reactive helpers

Normally I work with reactive helpers: I return a cursor from my ddbb and this is reactive on my page. Nothing estrange here.

My doubt comes when I’ve got a view in which I need a non reactive cursor but with some reactive properties.
Clear example:

This a view with some recipes. Each recipe has some properties: the follow and like button, the picture and some info, etc. Imagine Twitter to be more clear if you wish.

If we have this data reactive every time an user push a new recipe we are going to reload the whole cursor and that’s not the right behavior’re looking for so this helper/cursor is a non reactive one for now.

So until here everything is correct, but what would happen if we want some properties of this helper as reactive properties? Right now, if we click on follow and like button we need to refresh the page to see the changes on this buttons. If we want to see this when clicking we have to remove the non reactivity property but we’ll refresh the whole thing every time we click.

So reading about reactiveVar and reactiveDict I think I could fix this but I’m not sure if I understood their implementation. Might this work?

Thanks in advance guys, really appreciated :slight_smile:

RESUMING: have in same helper properties reactives and non reactives

I’m confused why a reactive cursor isn’t the right option - are you concerned about performance or some UX issue?

That’s the main page with all recipes saved on the ddbb. Obviously I don’t send all recipes to client, has a limit and a lazy loading, but as I said if you are on that page every time another user push an image you are going to update your cursor and this new recipe is going to be pushed at begging of the pile, pushing the one you are reading down. Also when you click on follow or like button you’ll see a flash on that view refreshing the whole array and if you loaded many recipes it takes a while.

So yes, it would be both in fact: UX and performance issues

1 Like

the issue with simply marking the cursor as not reactive is that the data is still being populated, it’s just not rerendering the UI. So anything that causes a rerender will end up getting the new data anyway.

I think the best option in this case is to make a “snapshot” of the data currently being viewed, in a client side collection. There’s a detailed explanation of how to do that here: https://guide.meteor.com/ui-ux.html#pagination

I’d suggest reading that whole section, perhaps it will help.

Interesting article. I found a quite of few interesting points (the website they commented is amazing: http://blog.percolatestudio.com/design/design-for-realtime/).

But this is more related about how manage the UX in a good way, which it’s ok, but it’s a different scenario. I don’t need how to make this process more friendly for the user because I don’t need reactively on my data, only on 2 buttons (follow and like).

For example, this is my helper:

const food = Food.find({}).map(food => {
                        const owner = Meteor.users.findOne(food.owner, {fields: {username: 1, avatarS: 1, following: 1}});
                        food.avatarS = owner && owner.avatarS;
                        food.username = owner && owner.username;
// ...skipped

I create the recipe helper from 2 collections (Food and User). Right now it’s everything reactive so when I like the recipe, the heart icon changes and for the user everything works as expected.

But something happens when clinking this: I can see the console once per recipe. If we’ve got 10 the change for this is instantaneously updated but if we’ve got 50 recipes this takes too much because we are also changing (but with same value) the image and everything else.

So what I’d like to change is just 2 properties. I want to make the helper non reactive but these 2 properties, which belong to this helper, need to be reactive.

A few weeks ago I had a long conversation on Stackoverflow but that approach would be nice using 2 different helper (one reactive and another one non reactive) to create a new third one: