简体   繁体   中英

Meteor 1.6 make synchronous call both client and server side

I'm currently working on a collection manager, which also manage foreign keys. It also generates some forms, and I have troubles to check foreign keys and get proper callbacks to the client.

I'm using wrapAsync method from meteor in order to use a synchronous version of method call.

First I'm declaring synchronous call to function in a "check fk" method.

declareCheckFKMethod(index){
        Meteor.methods({
             [this._collectionList[index]._prefix.replace(/\//g,"")+this._checkFKSuffix]:(fk)=>{
                var syncFunc = Meteor.wrapAsync(this.checkFKInDB.bind(this));
                return syncFunc(fk,index)
            }
        })
    }

Here is the target function :

checkFKInDB(fk,collectionIndex,callBack){
        try{
           var test = this._collectionList[collectionIndex].find({_id:fk}).fetch();
           if(test.length==1){
               return callBack(null,true);
           }
           else{
               return callBack(null,false);
           }
        }
        catch(e){
            return callBack(new Meteor.Error("DB error", e.message),null)
        }
    }

Then in my insert function I check all the FK fields both client and server side:

const check = Meteor.call(this._collectionList[index]._prefix.replace(/\//g,"")+this._checkFKSuffix,document[element.entryName]);
console.log(check)

And this is what I get when I insert a valid document :

Server side console log: true

Client side console log: undefined

I suspect that the client side is simply not waiting for the callback, but the server does. How could I fix that? ( BTW I tried await/async keywords, but it just gives me errors...)

Your client side function always needs to pass a callback in order to receive the async result:

Meteor.call(this._collectionList[index]._prefix.replace(/\//g,"")+this._checkFKSuffix,document[element.entryName], (err, check) => {
  console.log(err, check);
});

Edit: For your notice, the Meteor method will resolve the values in the method Promise style (read more on how Fibers work) while your client will receive the result or error always in callback style. So the idea to have some kind of async / await style pattern on the client when calling methods may not work out that way.

I actually found a solution, but I'm not sure why it works, if someone could clearly explain :

I just had to make a "checkFKInDB" server and client function like this :

checkFKInDB(fk,collectionIndex,callBack){
    if(Meteor.isClient){
        try{
           var test = this._collectionList[collectionIndex].find({_id:fk}).fetch();
           if(test.length==1){
               return true;
           }
           else{
               return false;
           }
        }
        catch(e){
            throw new Meteor.Error("DB error", e.message);
        }
    }
    if(Meteor.isServer){
        try{
           var test = this._collectionList[collectionIndex].find({_id:fk}).fetch();
           if(test.length==1){
               return callBack(null,true);
           }
           else{
               return callBack(null,false);
           }
        }
        catch(e){
            throw new Meteor.Error("DB error", e.message)
        }
    }
}

Then:

try{

      test = Meteor.call(this._collectionList[index]._prefix.replace(/\//g,"")+this._checkFKSuffix,document[element.entryName]);
}
catch(e){
      throw new Meteor.Error("DB error",e.message)
}

If someone could explain why callback is needed on server side but not on the client that would be great!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM