我在我的客户端应用程序中使用Angular 4。
customer.service中的getCustomer()函数调用API来获取数据。这个功能是Observable。
此功能需要访问令牌才能调用API。访问令牌可以从auth.service中的getAccessToken()函数获得。
但是getAccessToen()是异步的。我们如何从异步函数中获取价值?
请注意,getCustomer()必须是Observable,以便我可以映射响应中的数据并绑定到customer.component的成员。
auth.service.ts
import { Injectable } from '@angular/core';
import { Http, Headers } from '@angular/http';
import { Observable } from 'rxjs/Observable';
@Injectable()
export class AuthService {
private tokenEndpoint = "http://localhost:9000/connect/token";
private clientId = "testclientid";
private clientSecret = "testsecret";
constructor(private http: Http) { }
getAccessToken() : Observable<any> {
let credential = "Basic " + btoa(`${this.clientId}:${this.clientSecret}`);
let body = "grant_type=client_credentials&scope=testscope";
let headers = new Headers();
headers.set("Content-Type", "application/x-www-form-urlencoded");
headers.set("Authorization", credential);
return this.http.post(this.tokenEndpoint, body, { headers: headers })
.map(result => {
let data = result.json();
return data.access_token || "";
});
}
}
&#13;
customer.service.ts
import { Injectable } from '@angular/core';
import { Http, Headers } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
import { Customer } from './customer';
import { Address } from './customer';
import { ResourceData } from './customer';
import { ResourceAttributes } from './customer';
import { CustomerResource } from './customer';
import { ResourceCollection } from './customer';
import { AuthService } from '../auth/auth.service';
@Injectable()
export class CustomerService {
private customersUrl = "http://localhost:60001/api/v1/customers";
constructor(private http: Http, private authService: AuthService) { }
getCustomer(id: string): Observable<CustomerResource> {
let accessToken = this.authService.getAccessToken().subcribe(
// how to get accessToken from authService because subcribe is async?
);
let headers = addAccessTokenToHeader(accessToken);
let url = `${this.customersUrl}/${id}`;
return this.http.get(url, { headers: headers })
.map(result => {
return result.json() as CustomerResource;
})
.catch((error) => {
console.log(error);
return Observable.throw(error);
});
}
private addAccessTokenToHeader(accessToken: string): Headers {
let headers = new Headers();
headers.set("Authorization", `Bearer ${accessToken}`);
return headers;
}
}
&#13;
客户detail.component.ts
showCustomer(id: string) {
this.modalTitle = "Update PL customer";
this.buttonSaveTitle = "Update";
this.customerService.getCustomer(id)
.subscribe(customer => {
this.mapFromResource(customer.data);
this.customerModal.show();
});
}
private mapFromResource(data: ResourceData) {
this.customerId = data.id;
this.reference = data.attributes.reference;
this.lastName = data.attributes.lastName;
this.middleName = data.attributes.middleName;
this.firstName = data.attributes.firstName;
}
// this.customerId, this.reference are the members of customer.component. They are binding on UI.
&#13;
答案 0 :(得分:0)
在我的customer.service.ts
中,您可以使用以下内容链接方法调用:
getCustomer(id: string): Observable<CustomerResource> {
this.authService.getAccessToken()
.map((accessToken) => {
let headers = addAccessTokenToHeader(accessToken);
let url = `${this.customersUrl}/${id}`;
return this.http.get(url, { headers: headers })
// rest of the code
});
如果它不起作用,请尝试将.map
替换为.switchMap
。
答案 1 :(得分:0)
我正在使用flatMap,现在可以使用了。非常感谢您的建议@ AJT_82