2017-04-22 4 views
0

Dieser Meteor-Server-Code versucht Meteor.userId() in öffentlicher Methode „sendemail“, zu verwenden, aber manchmal habe ich den Fehlerkorrekte Verwendung von Meteor.userId()

Fehler Meteor.userId kann nur geltend gemacht werden, in Methodenaufrufen. Verwenden this.userId

lib = (function() { 

    return Object.freeze({ 
    'sendEmail': function(msg){ 
     let userId = Meteor.userId(); 
     //do stuff for this user 
    }, 
    'otherPublicMethod': function(){ 
     //do other things then use sendEmail 
     lib.sendEmail(); // <---- Error Meteor.userId can only be invoked in method calls. Use this.userId 
    } 
    }); 
}()); 

// Now I call sendEmail from any where, or can I? 

Meteor.methods({ 
    'sendEmail': (msg) => { 
    lib.sendEmail(msg); // <---- NO error when this is called 
    }, 
}); 

Wie es behoben werden kann? thx

+0

'userId()' darf nicht in 'Publications' verwendet werden, aber es gibt keine Einschränkung, es innerhalb' Methods' zu verwenden. –

Antwort

0

i werde vorschlagen, dass Sie ersetzen die Nutzung von IIFE simuliert. Stattdessen können Sie ES16 modules nutzen, um Ihre allgemeinen Funktionen zu definieren.

Wie Sie angegeben haben, ist Meteor.userId() in Methodenaufrufen verfügbar, steht jedoch nicht in eigenständigen Funktionen auf dem Server zur Verfügung. Das Muster, das ich benutze, wenn solche Funktionen von einem Methodenaufruf aufgerufen werden, besteht darin, die userId (oder den tatsächlichen Benutzer) zu übergeben. z.B.

Importe/api/E-Mail/server/utils/emailUtils.js:

const SendEmail = function(userId, msg) { 
    // do stuff 
}; 

export {SendEmail}; 

Importe/api/E-Mail/server/emailMethods.js:

import {SendEmail} from '/imports/api/email/server/utils/emailUtils'; 

Meteor.methods({ 
    'sendEmail': (msg) => { 
     check(msg, String); 
     // other security checks, like user authorization for sending email 
     SendEmail(Meteor.userId(), msg); 
    }, 
}); 

jetzt haben Sie eine erneute - verwendbare SendEmail-Funktion, die Sie von einer beliebigen Methode aufrufen oder veröffentlichen können. Wenn Sie diesem Muster folgen, sind Sie dem Erstellen von testbarem Code einen Schritt näher. d. h., es ist einfacher, eine Funktion zu testen, in die Sie eine userId einfügen, als sie "this.userId" oder "Meteor.userId()" zu mocksen.

+0

Ein Grund, warum ich die IIFE über Module mag, ist, dass ich die öffentliche Methode wie funcName.methName aufrufen kann und weiß, welche ich anrufe, d. H. Weniger Kommentare zu schreiben. –

0

Wenn lib.sendEmail von einer beliebigen asynchronen Methode aufgerufen wird, stellen Sie sicher, dass Sie die Meteor-Umgebung z. überprüfen Code, unter dem der Asynchron-Verhalten sanft

lib = (function() { 
    return Object.freeze({ 
     'sendEmail': function (msg) { 
      let userId = Meteor.userId(); 
      console.log(userId); 
      //do stuff for this user 
     }, 
     'otherPublicMethod': function() { 
      //do other things then use sendEmail 
      lib.sendEmail(); // <---- Error Meteor.userId can only be invoked in method calls. Use this.userId 
     } 
    }); 
}()); 

// Now I call sendEmail from any where, or can I? 

Meteor.methods({ 
    'sendEmail': (msg) => { 
     //simulate async behaviour + bind environment 
     Meteor.setTimeout(Meteor.bindEnvironment(function() { 
      lib.sendEmail(msg); // <---- NO error when this is called 
     })); 
     //output : 
     // null - if user has not logged in else 
     // actual userId - if user is loggedin 

     //simulate async behaviour without binding environment 
     Meteor.setTimeout(function() { 
      lib.sendEmail(msg); // <---- error when this is called 
     }); 
     //output : 
     // Exception in setTimeout callback: Error: Meteor.userId can only be invoked in method calls. Use this.userId in publish functions. 
    }, 
});