Issue with $unset on client


#1

In my project, wherever I use the “$unset” command, the client interface is not updating based around the client until reload, when using a subscription.

For example, if I have a collection with 3 variables:

MyCollection.update( { item._id},
{ $unset: { var1: “”, var2: “”, var3: “”}});

and the client simply has

{{#each item}}

{{var1}}

{{var2}}

{{var3}}

{{/each}}

Prior to unset, if the output is:

A
B
C

After using a method with the $unset command, the client will still say A/B/C.

If I check the database, the data IS properly being removed from the database. It seems the client itself is not updating the subscription.

If I reload the page, it displays properly.

I attempted to run the subscribe command to see if that would force an update of the collection, and had some strange results.

After using subscribe in callback function of unset, the output is:

A
C

Even if I put a delay on the subscribe command, same results.

Any advice?


#2

Spyro, it’s hard to diagnose the problem with the example you’ve posted. If you posted some of your actual source code, that would help us help you.

Off the top of my head though, the vars in your list might not be registered correctly as reactive vars, so they’re not being updated properly in the view. There shouldn’t be any need to re-run your subscription because those documents are already subscribed to and watched in your minimongo.

Maybe check out the Tracker or Blaze docs to see if you’re setting things up properly.


#3

Thanks for the response.

This one is a bit hard to do exact code, because it’s literally just a regular subscription. The only thing exact code would show is our private security for our app.

Basically, if a subscription set it to ANY value, then the reactivevar works correctly. For example, if I run a function that update a value from “A” to “B”, it works perfectly.

But if I use $unset on that same variable, it will still list as “A”, until I reload the page. Then it will properly show nothing.

It’s not an exclusive issue that’s happening only on one collection, this has been a persistent issue in our project since the beginning.


#4

Is the update operation being run on the client or on the server? Also if you have meteor dev tools installed do you see the changed message come in?


#5

Update is being run securely on the server.

I do not have meteor dev tools installed, but doing a find.fetch shows the data has updated properly, as well as being modified by RoboMongo.

Is this not a common issue? I assumed it was a Meteor issue, but I’m starting to wonder if it might be a package issue…


#6

Probably not? If you’re seeing the change in the db but it’s not updated in the view, it’s a reactive variable issue, I’m pretty sure. If you can’t share the code though, it’s hard to point to exactly what the problem is with the way you’ve set it up.

Maybe put some console logs in the subscription callback so you can verify that the data has updated in minimongo, then you can know for sure it’s just an issue with your vars not updating properly.


#7

Not a Meteor issue. I’ve just run a simple demo to check. It works exactly as you’d expect.

What packages are you using that might interfere with the expected behaviour?


#8

Just to narrow the field of possible culprits I would suggest to temporarily switch to a publication which publishes the whole collection (ie just return MyCollection.find({});) and see if it changes things.


#9

@leosco - yes I can confirm minimongo is updating properly

@robfallows - hmmm… I’m thinking either viewmodel, or materialize?

@vooteles - nope… seems the subscription and minimongo are working fine. Just the interface is not updating when $unset


#10

Ah, you using viewmodel? Then try to put the var1, var2 and var3 inside another template.


#11

Just to be clear, do you mean create another template that does NOT use viewmodel, just for displaying the data, and it should automatically update properly?


#12

I mean something like this:

<template name="itemList">
  ...
  {{#each items}}
    {{> itemDetails}}
  {{/each}}
  ...
</template>

<template name="itemDetails">
  ...
  {{var1}}
  {{var2}}
  {{var3}}
  ...
</template>
Template.itemList.viewmodel({
  items() {
    return MyCollection.find()
  }
});

Template.itemDetails.viewmodel({
  ...
});

#13

Thanks for your advice.

Sadly, I attempted this and it didn’t work. I tried creating the detail template as a basic template/regular javascript. I also tried creating it as viewmodel. Neither way had any luck.

All changes to the data work 100% correctly, EXCEPT for if the data is $unset or if it’s updated to “” (which removes the variable the same as unset). In this case, the data still is visible on the client until reloading the page, at which point is correctly disappears.

So if I input “test”, and run a method that updates the variable to “test” on the server, my minimongo is updating to “test”, and the client page is displaying “test”.

Then if I input an empty string and submit it through the same method, my minimongo unsets the variable (it’s completely removed from the document), but the client page is still displaying "test’.

If I reload the page, the client page is properly displaying nothing.


#14

Can you get a minimal git repository reproducing the issue?


#15

As @hluz has requested, a repo would help. I cannot reproduce your problem in my code - $unset works as expected, including reactively updating the client.


#16

I just came across this issue in Meteor 1.5.2. I’m trying to $unset a document field from the client. The database accepts the change, but the client doesn’t. Upon refreshing, the $unset has occurred and the client reflects it.

I was thinking this was probably a redis-oplog issue because I use that package, but in my repo it happens with redis-oplog removed too.

I’ve posted the repo and directions to reproduce the bug in the following issue:

https://github.com/meteor/meteor/issues/3086