2016-12-21 9 views
2

私は自分のAuthServiceに以下の機能を持っている:私のangular2サービスの.subscribeからデータを渡す方法はありますか?

getToken() { 
    this.http.post('myAuthEndpoint', { credentials }) 
    .subscribe((res) => { 
    const token = res.headers.get('Authorization') 
    localStorage.setItem('id_token', token); 
    }); 
} 

私はgetToken()から、私は戻って.subscribeで取得実際のトークン値を返すようにしたいです。それを行う方法はありますか?

+1

いや、それは観測(およびそれらの前に約束)の全体のポイントです。コールが終了したときに返す値は必ずしも使用可能ではありません。 – jonrsharpe

+0

getToken()でトークンをリファクタリングして返す方法はありますか? – user1354934

+3

いいえ、ありません。トークンを取得するプロセスは非同期です。代わりに、観測可能なものを返すか(またはそれを約束に変換する)、それを返し、*呼び出し元にそれをサブスクライブさせるべきです。同様の問題を抱えた他の人に私のアドバイスを見てください:http://stackoverflow.com/questions/41271214/how-to-get-a-global-http-get-request-for-use-everywhere?noredirect=1#comment69743655_41271214 – jonrsharpe

答えて

2

あなたには、いくつかの他のアクションを実行する必要がある場合は、トークンが利用可能になったとき、あなたが次の操作を行うことができます。

getToken() { 
    return this.http.post('myAuthEndpoint', { credentials }) 
    .map((res) => { 
    const token = res.headers.get('Authorization') 
    return token; 
    }) 
    .do((token) => { 
    localStorage.setItem('id_token', token); 
    }); 
} 

// some other part of app 
authService.getToken() 
    .switchMap((token) => { 
    // perform any desired action 
    }) 
    .subscribe((result) => ...); 

をしかし、この場合には、その後のsubscribeなしgetToken()を呼び出すと、何もしないことを注意してください。あなたは2つのサービス1を持っているコメント

回答は、トークン、他方がそれを消費提供:

export class AuthService { 
    private tokenSource = new ReplaySubject(1); 
    private token$ = this.tokenSource.asObservable(); 

    constructor(private http: Http) { 
    return this.http.post('myAuthEndpoint', { credentials }) 
    .map((res) => { 
     let token = res.headers.get('Authorization') 
     return token; 
    }) 
    .do((token) => { 
     localStorage.setItem('id_token', token); 
    }) 
    .subscribe(this.tokenSource); 
    } 

    getToken() { 
    return this.token$; 
    } 
} 

export class RecentPhotosService { 
    constructor(private authService: AuthService) { 
    this.authService.getToken() 
     .switchMap(token => { 
     return this.getRecentPhotos(token); 
     }) 
     .subscribe(photos => {...}); 
    } 

    ... 
} 
+0

ありがとうSergey! app.componentでこれを行い、HTTP要求を行うために必要なコンポーネントにキーを伝播することをお勧めしますか? – user1354934

+0

@ user1354934、私はむしろ 'authService'でやったようにサービスに入れたいと思っています。しかし、それがそのまま使用され、 'getToken'を複数回購読すれば、すべてのサブスクリプションでhttpコールを行います。これを回避するには、結果をキャッシュする必要があります。 –

+0

これを行うにはどうすればよいでしょうか?また、私の推論が間違っているかどうか教えていただけますか?私はapp.componentにサブスクライブを行います。これは最初に読み込まれ、他のルータコンポーネントを読み込むコンポーネントだからです。ルータコンポーネント(親コンポーネント)のみがngOnInitで行うhttp呼び出しを持ち、それらが渡すデータを使用することができます。 – user1354934

関連する問題