2013-04-20 9 views
5

Pracowałem z Meteorem i pakietem pasków, aby spróbować zrobić klienta. Więc po pierwsze mam kodu po stronie klienta, który wywołuje metodę na serwerze, tak po kliknięciu mam w client.js:Wywołanie meteorów w celu zwrócenia odpowiedzi na pasek rozłożenia

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

więc ten wywołuje metodę na 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(); 
    } 

}); 

Teraz to działa i tworzy klienta, kiedy loguję się na desce rozdzielczej stripe.com, ale próbuję uzyskać odpowiedź zwróconą klientowi, przynajmniej na razie, na identyfikator klienta i wydrukować go w konsoli. Tutaj nie mogę sprawić, żeby działało. Będzie logował się niezdefiniowany, gdy wykonam console.log (wynik). Jakieś pomysły?

EDYCJA: Teraz wstawiam klucz światłowodowy i pasek jako zmienne globalne i nie otrzymuję błędu, ale zwroty nie wydają się zwracać żadnych wartości. więc po stronie klienta mam:

'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); 
    }, 
}); 

więc już zostały uruchomione kilka testów console.log i wydaje się, że wykonuje meteor.call i leci w dół. Console.log zarówno zwrotów testid, jak i cusid są niezdefiniowane, ale kilka sekund później otrzymuję konsolę.log z wynikiem i ciąg "meteor call" z wnętrza meteor.call. Czy istnieje sposób oczekiwania na zakończenie połączenia meteorów, a następnie uruchomienie reszty funkcji mojego kliknięcia? więc wyjście konsola trafi jak:

  • "cześć"
  • "poza wezwanie"
  • Test id niezdefiniowany
  • cusid niezdefiniowanej
  • "Call meteor"
  • "Wynik"

Odpowiedz

9

Należy pamiętać, że pasek API nie używa włókien. Musisz umieścić to ręcznie. Oddzwanianie nie dociera do klienta, ponieważ do tego czasu byłaby już dostępna odpowiedź (jego asynchronizacja). Można użyć czegoś podobnego, aby poczekać na wynik wywołania zwrotnego w pasku, zanim wynik zostanie zwrócony klientowi:

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(); 

tu Future jest używany i czeka na wynik być odbierane z paskiem zwrotnego przed efektem jest zwracany do klienta.

Więcej informacji można znaleźć na włókien/Futures & Synchroniczne oddzwaniania incuding jak go o nich & kiedy je stosować:

  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

To działało świetnie, ale kiedy poszedłem do innej metody, które na przykład by usunąć klient zgłasza Błąd z ("Przyszłość rozwiązano więcej niż jeden raz"). Więc teraz ktoś kliknie przesłać pobiera wszystkie informacje z formularza i tworzy stripe.customer następnie utworzyć Meteor.user, ale powiedz, że Accounts.createUser zgłasza błąd Uruchomę metodę, aby usunąć klienta pasków. Po wywołaniu mojej metody stripe del daje błąd. – asiammyself

+0

Czy mógłbyś opublikować zaktualizowany kod? Potrzebuję trochę więcej, ale wydaje mi się, że zapewne istnieje wiele zwrotów, więc musisz upewnić się, że fut.ret działa tylko raz. Zaktualizowany kod: – Akshat

+0

. Made Future a global var. Nie wiem, czy byłby to właściwy sposób postępowania, ale działa na razie. Funkcja nadal wydaje się nie czekać na powrót patrz edytowany post. – asiammyself

1

Oto coś prostszego.Meteor ma teraz Meteor.wrapAsync() dla tego rodzaju sytuacji:

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 

     }); 
    } 
}); 

znalazłem ten post bardzo pomocne: Meteor: Proper use of Meteor.wrapAsync on server

+0

Jak mogę dowiedzieć się na temat klienta, co się dzieje? Po wywołaniu tej metody serwera uzyskuję nieokreślone wyniki. – quape