2016-06-21 17 views
2

ich mit Angular des $http Fragen zu erhalten, die ein Versprechen im Gegenzug erwartet, entweder success oder error:Wie kann ich eine Rückruffunktion zurückgeben?

Question.getQuestions().success(function (res) { 
    ... 
}).error(function (err) {}); 

In meiner Methode, ich brauche Token zu überprüfen, ob abgelaufen ist, wenn ja, zu aktualisieren, dann Machen Sie die Anfrage an /questions und geben Sie das Versprechen zurück. Andernfalls machen nur die Anforderung an /questions wie gewohnt:

getQuestions: function() { 

    // this is called by refreshToken but not returning the $http promise 
    var get = function() { 
     return $http({ 
      method: 'GET', 
      url: url + ver + '/questions', 
      ... 
     }); 
    }; 

    if (Auth.tokenIsExpired()) { 
     return Auth.refreshToken(get); 
    } else { 
     return get(); 
    } 
}, 

Die refreshToken andere $http ist, die auf ein Versprechen beruht, dann ruft die get() Rückruf.

Auth {... 

    refreshToken: function(callback) { 
     ... 
     _this.getAuth(OAuth).success(function (access_obj) { 
      //set token 
      callback(); 
     })... 

Wo getAuth ist ein weiterer $http promise:

getAuth: function(params) { 
      return $http({ 
       method: 'POST', 
       url: url + '/oauth/access_token', 
       ... 
      }); 
     }, 

Alle diese Methoden aufgerufen werden wie erwartet, aber bin immer Fehler:

Cannot read property 'success' of undefined

Dies liegt daran, Auth.refreshToken(get) nicht zurückkehrt der /questions $http Anruf wie es sollte. Wie kann ich das Versprechen von diesem zurück zum ursprünglichen Question.getQuestions() zurückgeben?

+0

so was '_this.getAuth'? – zerkms

+0

@zerkms siehe oben Bearbeiten – Growler

+0

sollten Sie nicht then() anstelle von success() verwenden, und warum Sie nicht _this.getAuth (...) zurückgeben und callback() zurückgeben; – progysm

Antwort

2

Hier ist ein Vorschlag, da Ihr Code übermäßig kompliziert aussieht.

Grundsätzlich refreshToken sollte das Token aktualisieren und eine Versprechung zurückgeben, wenn es fertig ist. Dann, wenn Sie die Fragen GET überprüfen Sie, ob das Token abgelaufen ist, wenn es so wäre, dann rufen Sie refreshToken und wenn sein getan (.success()/.then() heißt Sie tun, um die üblichen GET)

Sie können dies weiter vereinfachen und lassen Auth Griff Alle Token werden aktualisiert, indem Sie die Zeile Auth.tokenIsExpired() in die refreshToken-Methode verschieben.

Ein weiteres Beispiel:

getQuestions: function() {  
    return Auth.refreshToken().then(function(){ 
     return $http.get(url + ver + '/questions'); 
    }); 
} 

refreshToken: function() { 
    if (_this.tokenIsExpired()) 
    return _this.getAuth(OAuth).then(function (access_obj) { 
     //set token 
    }); 
    else return $q.resolve(/*value needed?*/); 
} 
+0

Ich frage mich, ob statt jeder $ HTTP-Anfrage in 'return Auth.refreshToken(). then (function() {', sollte ich '$ httpProvider.interceptors' nicht verwenden, um die Anfragen abzufangen, bevor sie ausgehen, überprüfen, ob Auth das Token aktualisieren muss, dann wird es weitergehen auf die "$ http" Anfrage? – Growler

+0

Das wäre die beste Approac h. meiner Meinung nach. –

0

Dies ist fehlgeschlagen, weil Sie beim Auffrischen des authToken nur das get aufrufen, aber nicht das Versprechen zurückgeben, das es zurückgibt.

Versuchen Sie folgendes:

refreshToken: function(callback) { 
    ... 
    _this.getAuth(OAuth).success(function (access_obj) { 
     //set token 
     return callback(); 
    })... 

aber ich würde nicht Rückrufe und Versprechungen mischen, würde stattdessen tun:

refreshToken: function(callback) { 
    var promise = $q.defer(); 
    _this.getAuth(OAuth).success(function (access_obj) { 
     //set token 
     promise.resolve(); 
    })... 

dann:

if (Auth.tokenIsExpired()) { 
    Auth.refreshToken().then(function() { return get() }); 
} else { 
    return get(); 
} 

Am stärksten bevorzugt diese aufzuräumen würde sei, um die Token-Prüfung eine Verheißung selbst zurückzugeben, die löst, sobald es den Token so bestätigt oder aktualisiert, so dass die endgültige w ould einfach sein:

Auth.checkToken().then(function() { return get() }); 
+0

Ich habe das versucht, gibt mir 'Kann nicht lesen Eigenschaft 'dann' von undefined' für 'Question.getQuestions(). Dann ...' – Growler

Verwandte Themen