我正在尝试在地图内部调用API方法,但从未进行第二次API调用。没有控制台错误。
//This method is not being called - Not hitting the API method
this.getUserPermissions(localStorage.getItem('user_ref'));
只是想知道我是否不能在地图内调用地图?
下面是我的代码。
public isAuthenticated() {
if (!this.loggedIn)
this.redirectToLogin();
return this.httpClient.get<boolean>(`${this.settings.getApiSettings('uri')}/api/auth/IsTokenValid`, {
params: { token: this.getToken }
}).map( /// <<<=== use `map` here
(response) => {
if (response !== null) {
var receivedToken = response["securityStamp"];
var availableToken = localStorage.getItem('access_token');
//Check if received a refreshed token. (tokens are refreshed every 15 minutes)
if (receivedToken && receivedToken !== availableToken) {
localStorage.removeItem('access_token');
localStorage.setItem('access_token', response["securityStamp"]);
}
this.user_permissions = this.getUserPermissions(localStorage.getItem('user_ref'));
}
let data = response;
if (data == null)
return false;
else
return true;
}
);
}
getUserPermissions(user_ref) {
if (!this.loggedIn)
this.redirectToLogin();
const httpParams: HttpParamsOptions = { userRef: "44C4D2F7-76A0-4714-B8CA-3123F607AC5A" } as HttpParamsOptions;
const httpOptions = {
params: new HttpParams(httpParams),
headers: new HttpHeaders({
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + this.getToken
})
};
return this.httpClient.get<Array<any>>(`${this.settings.getApiSettings('uri')}/api/auth/GetUserPermissions`, httpOptions).map( /// <<<=== use `map` here
(response) => {
if (response["status"] == 401) {
this.redirectToLogin();
}
else if (response["status"] < 200 || response["status"] >= 300) {
throw new Error('This request has failed ' + response["status"]);
}
this.user_permissions = response;
return response;
}
);
}
答案 0 :(得分:2)
这是因为.map()
函数不会返回预订,而是可以观察到的。
如果您需要与HttpClient的api调用的响应进行交互,则需要订阅您正在调用的.get()
或.post()
方法。
这可以满足您的需求,或者至少在请求失败的情况下将其记录在控制台中。
firstUrl = `${this.settings.getApiSettings('uri')}/api/auth/IsTokenValid`;
secondUrl = `${this.settings.getApiSettings('uri')}/api/auth/GetUserPermissions`;
public isAuthenticated() {
if (!this.loggedIn) this.redirectToLogin();
return this.httpClient.get<boolean>(this.firstUrl, {params: {token: this.getToken}}).subscribe(
(response) => {
if (response !== null) {
let receivedToken = response["securityStamp"];
let availableToken = localStorage.getItem('access_token');
if (receivedToken && receivedToken !== availableToken) {
localStorage.removeItem('access_token');
localStorage.setItem('access_token', response["securityStamp"]);
}
this.user_permissions = this.getUserPermissions(localStorage.getItem('user_ref'));
}
return response != null;
},
(error) => console.log(error)
);
}
getUserPermissions(user_ref) {
if (!this.loggedIn) this.redirectToLogin();
const httpParams: HttpParamsOptions = {userRef: "44C4D2F7-76A0-4714-B8CA-3123F607AC5A"} as HttpParamsOptions;
const httpOptions = {
params: new HttpParams(httpParams),
headers: new HttpHeaders({
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + this.getToken
})
};
return this.httpClient.get<Array<any>>(this.secondUrl, httpOptions).subscribe(
(response) => {
if (response["status"] == 401) {
this.redirectToLogin();
} else if (response["status"] < 200 || response["status"] >= 300) {
throw new Error('This request has failed ' + response["status"]);
}
this.user_permissions = response;
return response;
},
(error) => console.log(error)
);
}
答案 1 :(得分:2)
您使用的是哪个版本的Angular(更重要的是rxjs)?
请记住HttpClient返回且具有Observable(一个懒惰的observable,在您订阅它之前不会做任何事情)。
当您的isAuthenticated
方法返回HttpClient Get方法时,您的isAuthenticated
返回一个可观察的等待订阅状态。
可观察到的HttpClient订阅将使http调用,在收到响应时调用观察者的下一个处理程序,并在提供时调用on complete处理程序。我建议在这里阅读Observables。 https://www.learnrxjs.io/
// Doing this will not do anything as the observable has not been subscribed to.
this.httpClient.get<boolean>(`...`);
// Subscribing to the HttpClient will make the request
this.httpClient.get<boolean>(`...`)
.subscribe((response) => {
// do something with the response
});
正如您所说的,第一个HttpCall已完成,我假设您在调用isAuthenticated
方法时正在订阅它?即
isAuthenticated().subscribe( (response) => {
//
})
请注意,您的getUserPermissions
还返回HttpClient方法(一个可观察的方法),但是当您调用它this.getUserPermissions(localStorage.getItem('user_ref'));
时,它从未被预订,因此也从未被调用。
要发起第二个请求,您必须订阅getUserPermissions
调用,如下所示。
public isAuthenticated() {
// ...
return this.httpClient.get<boolean>('...').map(
(response) => {
// Subscribe to the second Http call
this.getUserPermissions(localStorage.getItem('user_ref'))
.subscribe( (response) => {
// do something with the second
})
})
}
一些注意事项;
自rxjs v6起,您不赞成使用链接到map
方法的httpClient.get
运算符,而推荐使用管道运算符。
请参阅:https://github.com/ReactiveX/rxjs/blob/master/docs_app/content/guide/v6/migration.md
所以这个
this.httpClient.get<boolean>('...')
.map( ... )
.subscribe(...)
现在应该这样写:
this.httpClient.get<boolean>('...')
.pipe( // <- Pipe the operators
map( ... ),
map( ... )
)
.subscribe( ...)
尽管不在最初的问题之外,我还是会考虑重构您的代码,并使用可用的rxjs / operator进行更好的流控制。
this.httpClient.get<boolean>('...')
.pipe(
map(( response ) => {
// some logic
return something;
}),
map( (something) => localStorage.getItem('user_ref')),
switchMap( (userRef) => this.getUserPermissions(userRef)), // <- switchMap to a new observable
)
.subscribe( (responseFromGetUserPermissions) => {
// This value is now the return of getUserPermissions because of switchMap
})
rxjs / observable是一个非常强大的模式,我强烈建议您花大量时间学习如何充分利用它们。
问候 乔诺
答案 2 :(得分:0)
您当然可以在地图中调用地图,但是您此处未调用API的问题是因为您的方法“ getUserPermissions”返回的是Observable而不是用户的数据。
我建议您按照反应性方法来更改此部分的设计。
您可以阅读此link。
希望对您有帮助