2013-04-20 13 views
5

Ho lavorato con Meteor e il pacchetto stripe per provare e creare un cliente. Quindi, prima ho il mio codice lato client che chiama un metodo sul server in modo che quando si fa clic ho nel Client.js:Ottenere la chiamata di meteor per restituire la risposta ai pagamenti stripe

Meteor.call('usersignup', function (error, result) { 
    console.log (result); 
}); 

Quindi questo chiama il metodo sui server.js:

var Future = Npm.require('fibers/future'); 
var stripe = StripeAPI('my key'); // secret stripe API key 

Meteor.methods({ 

    usersignup: function(cusEmail){ 
     var fut = new Future(); 

     stripe.customers.create(
      { email: cusEmail }, 
      function(err, customer) { 
       if (err) { 
        console.log(err); 
        fut.ret; 
       } 
       fut.ret(customer); 
      } 
      ); 
     return fut.wait(); 
    }, 

    userfail: function(cusid){ 
     var fut = new Future(); 

     stripe.customers.retrieve(cusid, function(err, result) { 
      if(err){ 
        console.log(err); 
        fut.ret; 
       } 
       fut.ret(err, result); 
      }); 
     return fut.wait(); 
    } 

}); 

Ora questo funziona e crea un cliente quando accedo al dashboard stripe.com ma sto cercando di ottenere la risposta restituita al client bene almeno l'ID cliente per ora e stamparlo nella console. Questo è dove non riesco a farlo funzionare. Registrerà undefined quando eseguo console.log (risultato). Qualche idea?

EDIT: Così ho messo la fibra e la chiave a strisce come variabili globali ora e non ottengo un errore ma i ritorni non sembrano restituire alcun valore. così sul lato client che ho:

'click #signupsubmit': function (event) { 
    console.log("hello"); 
    var whatis = getVal(); // function gets value of forms and returns object 
    var testid; 
    var cusid = Meteor.call('usersignup', whatis.email, function (error, result) { 
     if (error) { 
      console.log(err.message); 
      return; 
     } 
     console.log(result); 
     console.log("meteor call"); 
     testid = result; 
     return (result); 
    }); 
    console.log("outside call"); 
    console.log(testid); 
    console.log(cusid); 
    }, 
}); 

Così ho corso alcuni test console.log e sembra esegue il meteor.call e continua ad andare giù la linea. Console.log sia di testid che di cusid restituiscono undefined ma un paio di secondi dopo ricevo il file console.log del risultato e la stringa "meteora" dall'interno di meteor.call. C'è un modo per aspettare che la chiamata di meteore finisca poi eseguire il resto di ciò che è nella mia funzione click? così l'output su console andrà come:

  • "ciao"
  • "chiamata esterna"
  • prova id indefinito
  • cusid indefinito
  • "meteora chiamata"
  • "risultato"

risposta

9

Ricordare che l'API stripe non utilizza le fibre. Devi metterlo manualmente. Il callback non raggiunge il client perché a quel punto avrebbe già ricevuto una risposta (la sua asincronia)

È possibile utilizzare qualcosa come questo per attendere un risultato dal callback stripe prima che un risultato sia restituito al client:

var stripe = StripeAPI('mykeygoeshere'); // secret stripe API key 
var Future = Npm.require('fibers/future'); 

var fut = new Future(); 

stripe.customers.create(
    { email: '[email protected]' }, 
    function(err, customer) { 
     if (err) { 
      console.log(err.message); 
      fut.ret; 
     } 
     fut.ret("customer id", customer.id); 
    } 
); 
return fut.wait(); 

Ecco un Future viene utilizzato ed è aspetta per un risultato di essere ricevuti dal callback striscia prima che un risultato viene restituito al client.

Maggiori informazioni si possono trovare su fibre/Futures & richiamate sincroni incuding come andare su di loro & quando utilizzarle:

  1. Meteor: Calling an asynchronous function inside a Meteor.method and returning the result
  2. https://github.com/laverdet/node-fibers
  3. https://gist.github.com/possibilities/3443021
+0

Questo ha funzionato grande, ma quando sono andato a fare un altro metodo che per esempio potrebbe eliminare il cliente viene generata Errore con ('Futuro risolto più di una volta'). Quindi in questo momento qualcuno fa clic su invia tutte le informazioni dal modulo e crea una stripe.customer quindi crea un Meteor.user ma dice che Accounts.createUser genera un errore. Eseguo un metodo per eliminare il cliente stripe. Dopo chiamo il mio metodo stripe del dà l'errore. – asiammyself

+0

Potresti pubblicare il codice aggiornato? Ho bisogno di un po 'di più per andare avanti, ma penso che ci siano forse più ritorni forniti, quindi devi assicurarti che fut.ret funzioni solo una volta il codice aggiornato – Akshat

+0

. Made Future una varietà globale. Non so se questo sarebbe il modo corretto per gestirlo ma funziona per ora. La funzione sembra non attendere il ritorno vedi post modificato. – asiammyself

1

Ecco qualcosa di più sempliceMeteor ha ora Meteor.wrapAsync() per questo tipo di situazione:

var stripe = StripeAPI("key");  
Meteor.methods({ 

    yourMethod: function(callArg) { 

     var charge = Meteor.wrapAsync(stripe.charges.create, stripe.charges); 
     charge({ 
      amount: amount, 
      currency: "usd", 
      //I passed the stripe token in callArg 
      card: callArg.stripeToken, 
     }, function(err, charge) { 
      if (err && err.type === 'StripeCardError') { 
       // The card has been declined 
       throw new Meteor.Error("stripe-charge-error", err.message); 
      } 

      //Insert your 'on success' code here 

     }); 
    } 
}); 

Ho trovato questo post veramente utile: Meteor: Proper use of Meteor.wrapAsync on server

+0

Come faccio a sapere sul cliente cosa sta succedendo? Sto ottenendo risultati non definiti solo dopo aver chiamato questo metodo server. – quape

Problemi correlati