Method callback can't find new document after insertion - why?

I’ve got a fairly typical client -> method -> insert -> client router.go situation, but sometimes (not always), the method callback can’t find the new document (Groups.findOne(groupId) is undefined).

Client:

"click #createGroup":function(e,t){
	Meteor.call("createGroup", "Click here to rename", function(err, groupId){
		console.log(groupId);
		var group = Groups.findOne(groupId);
		console.log(group)
		if(typeof group !== 'undefined'){
			Router.go('/group/'+Groups.findOne(groupId).uuid);
		} else {
			console.log("createGroup method returned undefined");
		}
		if(err){
			console.log("Error creating Group: "+err);
		}
	});
},

server/methods.js:

createGroop:function(name){
	check(name, String);
	var groupId = MyApp.createGroup(name);
	return groupId;
},

server/myapp.js:

MyApp.createGroop = function(name){
  ...
  var groupId = Groops.insert({
    ...
  });
  
  Meteor.users.update(Meteor.userId(), {$addToSet:{"groups":uuid}});

  return groupId;
};

To the best of my knowledge, all of this should be blocking by default (unless the use of a function from a separate package changes things?). And like I said, it doesn’t always fail. In fact, it seems to not fail when there are no group documents yet (i.e. it’s the first one), but fails when there are already documents…

What am I missing? Thanks in advance!

Your Meteor method callback will be triggered after the Groups insert and the Meteor.users.update function is complete. However, that doesn’t mean that the new data has been synced with the client yet. So you have the new groupId on the client, and you query minimongo based on that groupId, but that data isn’t yet available there.

If all you need is that uuid from a group, then I suggest returning that from the Meteor method so that it’s available immediately on the client. Then when you send the client to the new route, it should show a loading screen until the Group data to becomes reactively available on the client.

By the way… you misspelled Groups as Groops in server/myapp.js

Right, I figured out that it was the client not synced yet, I just wasn’t sure what to do about it. Using just the id should be fine though—good idea! Thank you! And yes, I caught the typo :wink:

What, though, would be the canonical / “correct” solution in this case? Detecting that the subscription is now invalidated? I’m actually not clear on how that works.

1 Like

I suppose you may run the router go within the method (under .client() block), since the method would also run on client and should get the same ID as the validation on server. I’m speculating.

there’s also meteor.error object which I’m not aware of how helpful it is.