Use collection insert inside meteor method (server side)

Hello !
I’m actually trying to make a parsing script in server side (Can’t say more about the script, but it doesn’t change anything)

Actually, I have a collection and a model like that :

Tags = new Mongo.Collection(‘tags’);

var Schemas = {};

Schemas.tags = new SimpleSchema({
	tag: {
		type: String,
		unique: true
	}
});

Tags.attachSchema(Schemas.tags)

Tags.allow({
  insert: function(userId, tag) {
    return true;
  },
  update: function(userId, tag, fields, modifier) {
    return true;
  },
  remove: function(userId, tag) {
    return true;
  }
});

Then, in my script, I’m trying to insert a new tag inside the collections. Like that.

                        Console.log('Before insert');
			Tags.insert({tag: item}, function(err, idTag){
				if (err) {
					var tagFind = Tags.findOne({tag : item});
					def2.resolve(tagFind._id);
					console.log("ALREADY FOUND TAG " + tagFind);
				} else {
					console.log("Creation of " + item + "in DB" + idTag);
					def2.resolve(idTag);
				}
			});
                       console.log('After insert');

In the console, ‘Before the insert’ is display, and then, nothing more, and the program don’t go further…
And if a try to insert something in client side, everything works well.

I have to finish this app for tonight… And I’m stucked into this dumb problem.
Thanks for you help.

return tag; ← did you mean that? It should be true or false.

1 Like

Oh crap, no, I didn’t mean that at all. Changed, and edited.

But this doesn’t change anything. Still doesn’t work.

You have made Tags available to your file with an import?

1 Like

Yes, I tried to make a second methods with only an insert and it worked.
I have the feeling that this is linked to a forEach and the lot of data that I send inside this function.

This is all my function, and my function is also in a second forEach

	function sendDB (frenchArray) {
		var def1 = Q.defer();
		var promises = [];

		_.forEach(frenchArray, function(item) {
			console.log(item);
			console.log(typeof(item));
			var def2 = Q.defer();
			Tags.insert({tag: item}, function(err, idTag) {
				if (err) {
					var tagFind = Tags.findOne({tag : item});
					def2.resolve(tagFind._id);
					console.log("ALREADY FOUND TAG " + tagFind);
				} else {
					console.log("Creation of " + item + "in DB" + idTag);
					def2.resolve(idTag);
				}
			});
			promises.push(def2.promise);
		 });

		Q.all(promises).then(function(data) {
			def1.resolve(data);
		});

		return def1.promise;
	}

Are you using Meteor’s inbuilt Promises or something like Bluebird?

I am using Q, that I installed with

meteor npm install --save q 

Check this thread:

That conversation continued over several PMs. The conclusion was that Meteor’s inbuilt Promises work as expected with fibers/futures, but other Promise libraries don’t play well. If you really cannot use Meteor’s Promises, your best bet will be to use the standard npm module methods (without callbacks) which Meteor uses under the hood: these return Promises. So, instead of doing a normal Meteor insert like this:

function sendDB (frenchArray) {
  ...
  Tags.insert(...);

you would do something like

async function sendDB (frenchArray) {
  ...
  const idTag = await Tags.rawCollection().insert(...);

or use a standard doThing().then(doOtherThing) promise chain.

You should then be able to use Q (never tried Q, but I was able to get Bluebird to work this way). Note that the syntax of these methods is not quite the same as the exposed Meteor methods. Check the docs for more information :slight_smile:

1 Like

I’m gonna check all that, but I think that’s the solution.

Thanks you, let’s get back to work.

1 Like