2016-07-25 12 views
0

サービスHTTPメソッドを呼び出して、最終的にエラーメッセージを返そうとしていますが、多くのことを試して1週間後に(約束、Observables、...)それを働かせてください。誰かが私を助けてくれることを願っていますか?Angular2コンポーネントのサービスからのログイン関数の呼び出しと返信エラー

私はAngular2の新機能を持ち、このプロジェクトでは単独で作業しています。私の周りの誰もAngularの専門知識を持っていません。私は3日間のトレーニングコースを受けました。

コンポーネント

@Component({ 
    templateUrl: 'build/pages/login/login.html' 
}) 
export class LoginPage { 
    error: string; 

    constructor(private navController: NavController, private auth: AuthService) { 
    } 

    private login(credentials) { 
    // Method calling the login service 
    // Could return an error, or nothing 
    this.error = this.auth.login(credentials); 

    // If there is no error and the user is set, go to other page 
    // This check is executed before previous login methode is finished... 
    if (!this.error && this.auth.user) { 
     this.navController.setRoot(OverviewPage); 
    } 
    } 
} 

のAuthService

@Injectable() 
export class AuthService { 
    private LOGIN_URL: string = "http://localhost:8080/rest/auth"; 
    private USER_URL: string = "http://localhost:8080/rest/user"; 

    private contentHeader: Headers = new Headers({ 
    "Content-Type": "application/json" 
    }); 

    errorMessage: string; 
    user: User; 

    constructor(private http: Http) { 
    } 

    login(credentials) { 
     let contentHeader = new Headers({ 
     "Content-Type": "application/json" 
     }); 

    this.http.post(this.LOGIN_URL, JSON.stringify(credentials), { headers: contentHeader }) 
     .map(res => res.json()) 
     .catch(this.handleError) 
     .subscribe(
     data => this.handleLogin(data), 
     err => this.handleError 
    ); 

    // could return an errorMessage or nothing/null 
    return this.errorMessage; 
    } 

    private handleLogin(data) { 
    let token = data.token; 
    this.getAccount(token); 
    } 

    private getAccount(token) { 
    let authHeader = new Headers({ 
     "Content-Type": "application/json", 
     "X-Auth-Token": token 
    }); 

    this.http.get(this.USER_URL, { headers: authHeader }) 
     .map(res => res.json()) 
     .catch(this.handleError) 
     .subscribe(
     data => this.setUser(data), 
     err => this.errorMessage = err 
    ); 
    } 

    private setUser(data) { 
    this.user = new User(data.naam, data.voornaam); 
    } 

    private handleError(error) { 
    // this.errorMessage is not saved? 

    if (error.status === 401) { 
     this.errorMessage = '401'; 
    } else if (error.status === 404) { 
     this.errorMessage = '404'; 
    } else { 
     this.errorMessage = 'Server error'; 
    } 

    return Observable.throw(error.json() || 'Server error'); 
    } 
} 

答えて

1

私はあなたの問題はあなたのログイン方法は、フラット値(errorMessageを)返しているということだと思います。ログインメソッドは、値が初期化されない非同期要求を作成するため、常にnullを返します。これを設定すると、ログインメソッドはObservableになります。

さらに複雑なことをするには、ログインしたユーザーを取得するためにログイン後に連続して呼び出したいと思われます。両方の通話を完了するまで、ログイン方法を放棄したい場合は、何らかの方法で組み合わせる必要があります。私はswitchがこれを行うことができると思います。

@Injectable() 
export class AuthService { 
    private LOGIN_URL: string = "http://localhost:8080/rest/auth"; 
    private USER_URL: string = "http://localhost:8080/rest/user"; 

    private contentHeader: Headers = new Headers({ 
    "Content-Type": "application/json" 
    }); 

    user: User; 

    constructor(private http: Http) { 
    } 

    login(credentials) { 
     let contentHeader = new Headers({ 
     "Content-Type": "application/json" 
     }); 

     let response:Observable<Response> = this.http.post(this.LOGIN_URL, JSON.stringify(credentials), { headers: contentHeader }); 

     //Take response and turn it into either a JSON object or 
     //a string error. 
     //This is an Observable<any> (any is returned by json()) 
     let jsonResponse = response.map(res => res.json()) 
           .catch(err => this.handleError(err)); 
     //Take JSON object and turn it into an Observable of whatever the 
     //login request returns 
     //This is an Observable<Observable<any>> (Observable<any> is returned 
     //by handleLogin 
     let userResponse = jsonResponse.map(
     data => this.handleLogin(data) 
    ); 

     //Switch to the observable of the login request 
     //This is an Observable<any>, we will switch to the Observable<any> 
     //returned by handleLogin 
     let finalResponse = userResponse.switch(); 

     //Hide actual response value from user. This will return an 
     //observable that will emit null on success and an error message 
     //on error 
     //Again, an Observable<any> since we're mapping to null 
     return finalResponse.map(res => null); 
    } 

    //We need to return this call as an observable so we can wire it into 
    //our chain 
    private handleLogin(data) { 
    let token = data.token; 
    return this.getAccount(token); 
    } 

    private getAccount(token) { 
    let authHeader = new Headers({ 
     "Content-Type": "application/json", 
     "X-Auth-Token": token 
    }); 

    let loginResponse = this.http.get(this.USER_URL, { headers: authHeader }) 
           .map(res => res.json()) 
           .catch((err) => this.handleError(err)); 

     loginResponse.subscribe(
     data => this.setUser(data) 
    ); 

     return loginResponse; 
    } 

    private setUser(data) { 
    this.user = new User(data.naam, data.voornaam); 
    } 

    private handleError(error) { 
    let errorMessage = "Uninitialized"; 
    if (error.status === 401) { 
     errorMessage = '401'; 
    } else if (error.status === 404) { 
     errorMessage = '404'; 
    } else { 
     errorMessage = error.json() || 'Server error'; 
    } 
    return Observable.throw(errorMessage); 
    } 
} 

ここで、ログインコンポーネントでは、応答に非同期でリスンする必要があります。これはすぐには起こりませんが(ローカルホストではかなり速いかもしれませんが、現実には時間がかかるかもしれません)、loginDisabledを追加して、ログイン要求を待っている間にユーザーがログインボタンを2回押すのを防ぐことができます実現する。

@Component({ 
    templateUrl: 'build/pages/login/login.html' 
}) 
export class LoginPage { 
    error: string; 
    loginDisabled:boolean = false; 

    constructor(private navController: NavController, private auth: AuthService) { 
    } 

    private login(credentials) { 
    // Method calling the login service 
    // Could return an error, or nothing 
    this.loginDisabled = true; 
    this.auth.login(credentials).subscribe(
     rsp => { 
     //On success, navigate to overview page 
     this.navController.setRoot(OverviewPage); 
     }, err => { 
     //On failure, display error message 
     this.error = err; 
     this.loginDisabled = false; 
    }); 

    } 
} 

これはまったく正しいとは言えませんが(私はそれに対してテストすることはありません)、正しい方向性でなければなりません。

+0

本当にありがとうございます。まさに私が探していたもので、魅力のように働いています! Observablesとコメントを作成してくれてありがとう、それは私にははっきりとはっきりしていることがはっきりしています。 'なしでなければなりません「;;」 '観察可能 ''観察可能でなければならない ' と 'データ=> this.handleLogin(データ):同じコードを使用したい人のため 小修正'data => this.handleLogin(data)' – Stijn

関連する問題