0

I'm just learning Meteor and I made a little app but I have a problem with find() and update() collection on server side

For example:

if (Meteor.isServer) {

    function getCollection1(){
        return collection_1.find({}).fetch({});
    }
    ....
    Meteor.methods({

        start: function(id) {

            datas = getCollection1();
            Collection2.update({_id:id}, {$set: {datas: datas}}); //sometimes it's ok(3/4)

        }
        ...

    }

Or when I await, I have an error

if (Meteor.isServer) {

    async function getCollection1(){
        return await collection_1.find({}).fetch({});
    }
    ....
    Meteor.methods({

        start: function(id) {

            getCollection1().then(function(datas){
                Rooms.update({_id: id}, {$set: {datas: datas}},function(err){
                    console.log(err);//error: Meteor code must always run within a fiber
                });
            });
        }
        ...

    }

What did I do wrong?

EDIT

it seems to work well with Fiber()

if (Meteor.isServer) {
    Fiber = Npm.require('fibers')     
        function getCollection1(){
            return collection1.find({}).fetch({});  
        }
        function setCollection2(id){
        Fiber(function() { 
            datas = getCollection1();               
                collection2.update({_id: id}, {$set: {datas: datas}},function(err){
                    console.log(err);
                });
        }).run();
        }
        ....
        Meteor.methods({

            start: function(id) {

                setCollection2(id);

            }
        ...

        }  
Dioux
  • 106
  • 6
  • Not really sure, but this might help: http://stackoverflow.com/questions/10192938/meteor-code-must-always-run-within-a-fiber-when-calling-collection-insert-on-s – Vasil Dininski Oct 12 '16 at 12:02
  • Do you know that you can run find/update in synchronous mode by not passing a callback? – MasterAM Oct 12 '16 at 13:39
  • there is another way that fiber ? – Dioux Oct 12 '16 at 13:48
  • What are you trying to do? Why not simply `const data = collection1.find().fetch(); collection2.update(id, {$set: {datas: data}});` or something similar? – MasterAM Oct 12 '16 at 15:55

2 Answers2

0

With the async/await version, you do not need to use Fiber. Instead you could this Meteor function: Meteor.bindEnvironment to make it work:

// ...     
getCollection1().then(Meteor.bindEnvironment(function(datas){
  Rooms.update(// ...);
}));
// ...

For a more understandable explanation, you could consult this video:

What is Meteor.bindEnvironment?

kkkkkkk
  • 7,628
  • 2
  • 18
  • 31
-1

Based on the code you provided, my guess is that for the first example the "Collection2.update" is taking place before GetCollection1() is completed. If this is indeed the case, then on the client side when you subscribe to the collection be sure to have a way to "wait" for the subscription to complete.

For example something like this on the client side where "start()" is called...

const handle = Meteor.subscribe( 'collection_1' );
  if ( handle.ready() ) {
    Meteor.call('start');   
} else {
    const allusers = Meteor.users.find().fetch();   
    onData( null, {allusers} );
}

Again, this is my best guess as you did not post the error you received with your first code chunk and I can't speak for the second you in which you've attempted to implement this.

Teedub
  • 372
  • 1
  • 7