2017-03-06 1 views
3

Ich arbeite an einem persönlichen Angular-Projekt.Methode in Angular 2 ist entweder nicht definiert oder nicht aufrufbar

import { Injectable } from '@angular/core'; 
import { CanActivate, Router } from '@angular/router'; 

import { LoginService } from './login.service'; 

@Injectable() 
export class LoggedInGuard implements CanActivate { 

    constructor(
     private _router: Router, 
     private _loginService: LoginService 
    ) { 
    } 

    isLoggedIn() { 
      let token = localStorage.getItem('token'); 
      if (token) { 
       this._loginService.isLoggedIn(token) 
        .subscribe(v => { 
         return v.status == 'ok'; 
        }); 
      } else { 
       return false; 
      } 
     }; 

    canActivate() { 
     console.log(this.isLoggedIn()); 

     if (this.isLoggedIn()) { 
      return true; 
     } else { 
      this._router.navigate(['/login']); 
      return false; 
     }; 
    } 

} 

aber mein Problem ist: Noch von AngularJS zu Angular :)

meinen Code Dies ist zu lernen und zu bewegen versucht

  1. Wenn ich this. halten auf dem console.log(this.isLoggedIn()); dann "undefined" wird ausgedruckt.
  2. Wenn ich es entfernen, dann habe ich die folgende Meldung auf VS-Code [ts] Cannot find name 'isLoggedIn'. Did you mean the instance member 'this.isLoggedIn'? und das gleiche auf der Konsole Uncaught (in promise): ReferenceError: isLoggedIn is not defined
  3. Das Verfahren isLoggedIn() ohne Probleme aus anderen Dateien verwendet wird, wo ich es nennen.
+0

Sind Sie eingeloggt, wenn undefined gedruckt wird? Können Sie versuchen, den Code auszuführen, wenn Sie ausgeloggt sind? Ich denke, Sie rufen alles korrekt auf, aber die 'isLoggedIn' Methode gibt keinen Wert in allen Fällen zurück. –

Antwort

2

Der Grund, warum Sie auf die Methode nicht definiert werden immer:

isLoggedIn() { 
    let token = localStorage.getItem('token'); 
    if (token) { 
     this._loginService.isLoggedIn(token) 
       .subscribe(v => { 
        return v.status == 'ok'; 
     }); 
    } else { 
      return false; 
     } 
}; 

ist, weil das Abonnement this._loginService.isLoggedIn(token) asynchron ist und kehrt nicht sofort. Die Methode isLoggedIn() beendet die Ausführung und kehrt zurück, bevor eine Antwort erfolgt.

Was Sie stattdessen tun könnten und was ich tue, ist Ihre _loginService pflegen eine lokale Variable, die andere Komponenten lesen und konsumieren können oder eine Funktion, die das Token synchron überprüfen kann, um sicherzustellen, dass es gültig ist. Wenn ein Token vorhanden ist, hat sich ein Benutzer angemeldet, und was Sie von dort aus tun können, ist das Token zu überprüfen, um sicherzustellen, dass es nicht abgelaufen ist. Das könnte auf verschiedene Arten geschehen. Wenn Ihr die angular2-jwt Bibliothek mit Token zu helfen, behandeln Ihre JWT könnten Sie eine Methode in Ihrer _loginService haben, die etwa wie folgt aussieht:

authenticated() { 
    // Check if there's an unexpired JWT 
    return tokenNotExpired(); 
} 

Wenn Sie nicht die angular-jwt-Bibliothek verwenden, um die JWT Token zu verwalten, Sie könnte so etwas tun:

isTokenValid(){ 
    let token = localStorage.getItem('token'); 
    let decodedToken = window.atob(token.split('.')[1]); 

    if((decodedToken.exp * 1000) < Date.now()){ 
     return false; 
    } 
    return true; 
} 

Hoffe, dass hilft. Dies kann nicht als Antwort

+0

Danke für die Antwort. Da ich 'angular2-jwt' nicht benutze, möchte ich die 'isTokenValid()' Methode testen. Ich bin mir jedoch nicht sicher, was zwischen den "decoded" und den "decodedToken" Zeilen liegt. Sind das die selben und nur ein Tippfehler oder irgendwie bekommt man den decodiertToken von der ersten? – Tasos

+0

Sorry, das war ein Tippfehler. –

+0

Ich habe festgestellt, dass ich das Token auf "." und nimm die zweite Instanz. Aber danach war alles in Ordnung. Markiere deine Antwort am besten, aber bearbeite sie bitte mit dem letzten Update. Vielen Dank – Tasos

1

qualifizieren, aber ich habe nicht genug Rufpunkte einen Kommentar zu hinterlassen - so dass jeder, verzeihen Sie mir :)

Ich glaube, Sie nicht einen Wert von subscribe wie das zurückgeben kann, wie es ein ist Asynchron-Anruf ..

Stattdessen Ihre isLoggedIn() -Methode zurückgegeben werden soll, wie unten dargestellt:

isLoggedIn() { 
      let token = localStorage.getItem('token'); 
      if (token) { 
       return this._loginService.isLoggedIn(token) 
        .subscribe(v => { 
         return v.status == 'ok'; 
        }); 
      } else { 
       return false; 
      } 
     }; 

Beachten Sie die Änderung ist hier: return this._loginService.isLoggedIn(token)... Hoffnung, das hilft.

EDIT: Ignorieren meine Antwort oben ... Das wäre immer noch nicht :(sorry ... Was passiert ist, die Sie anrufen isLoggedIn(), die einen asynchronen Aufruf ausführt (dh ein Anruf, der die Ausführung in weiter der Hintergrund und Rückkehr später.) Deshalb erhalten Sie ein "undefined." Was ich tun würde, ist Tylers Ratschlag oben zu folgen und eine lokale Variable zu haben, in der Sie den zurückgeführten Wert speichern und später ODER verwenden, konnten Sie einen Rückruf weitergeben zur isLoggedIn() -Methode - dieser Callback wird aufgerufen, sobald der Async-Aufruf abgeschlossen ist.Siehe unten:

import { Injectable } from '@angular/core'; 
import { CanActivate, Router } from '@angular/router'; 

import { LoginService } from './login.service'; 

@Injectable() 
export class LoggedInGuard implements CanActivate { 

    constructor(
     private _router: Router, 
     private _loginService: LoginService 
    ) { 
    } 

    isLoggedIn(callback: (v) => void) { 
      let token = localStorage.getItem('token'); 
      if (token) { 
       this._loginService.isLoggedIn(token) 
        .subscribe(v => { 
         callback(v) 
        }); 
      } 
     }; 

    canActivate() { 
     this.isLoggedIn((v) => { // this here is your callback function which will get invoked once async call is done 
      if(v.status == 'ok' { 
       // do something... 
       return true; 
      } else { 
       // do something 
       this._router.navigate(['/login']); 
      } 
     }); 
    } 

} 
Verwandte Themen