admin管理员组文章数量:1357312
I have the following code:
// in a service
downloadCSV(): Observable<Blob> {
return this.httpClient.get(`${apiUrl}/a.csv`, {responseType: 'blob'});
}
// in ponent
onDownloadClicked(event: MouseEvent) {
this.downloading = true;
this.service.downloadCSV()
.pipe(finalize(() => this.downloading = false))
.subscribe(
(data: Blob) => {
console.log(data);
},
(error) => {
console.error(error);
alert('Sorry, something wet wrong. Try again.');
},
() => {
console.log('pleted!');
}
);
}
The data is logged correctly but 'pleted!' is not logged and finalize is never called.
Edit:
So on further investigation, it seems the issue is related to an interceptor which adds an auth header.
If the interceptor is bypassed (and auth disabled on the server) the observable pletes without error.
I don't understand why this is happening though. Possibly something related to the fact the request is cloned?
//interceptor code
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
let scope: string;
// only inject tokens for the following scopes
if (req.url.indexOf('') === 0) {
scope = '';
}
else if (req.url.indexOf('') === 0) {
scope = '';
}
else if (req.url.indexOf(environment.apiUrl) === 0) {
scope = environment.appId;
}
if (scope) {
return this.authService.getToken(scope).pipe(
switchMap((token) => {
let newReq;
if (token) {
const JWT = `Bearer ${token}`;
newReq = req.clone({
setHeaders: {
Authorization: JWT,
}
});
}
return next.handle(newReq || req);
})
);
}
else {
return next.handle(req);
}
}
I have the following code:
// in a service
downloadCSV(): Observable<Blob> {
return this.httpClient.get(`${apiUrl}/a.csv`, {responseType: 'blob'});
}
// in ponent
onDownloadClicked(event: MouseEvent) {
this.downloading = true;
this.service.downloadCSV()
.pipe(finalize(() => this.downloading = false))
.subscribe(
(data: Blob) => {
console.log(data);
},
(error) => {
console.error(error);
alert('Sorry, something wet wrong. Try again.');
},
() => {
console.log('pleted!');
}
);
}
The data is logged correctly but 'pleted!' is not logged and finalize is never called.
Edit:
So on further investigation, it seems the issue is related to an interceptor which adds an auth header.
If the interceptor is bypassed (and auth disabled on the server) the observable pletes without error.
I don't understand why this is happening though. Possibly something related to the fact the request is cloned?
//interceptor code
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
let scope: string;
// only inject tokens for the following scopes
if (req.url.indexOf('https://graph.microsoft.') === 0) {
scope = 'https://graph.microsoft.';
}
else if (req.url.indexOf('https://management.azure.') === 0) {
scope = 'https://management.azure.';
}
else if (req.url.indexOf(environment.apiUrl) === 0) {
scope = environment.appId;
}
if (scope) {
return this.authService.getToken(scope).pipe(
switchMap((token) => {
let newReq;
if (token) {
const JWT = `Bearer ${token}`;
newReq = req.clone({
setHeaders: {
Authorization: JWT,
}
});
}
return next.handle(newReq || req);
})
);
}
else {
return next.handle(req);
}
}
Share
Improve this question
edited Jun 5, 2019 at 14:05
mfa
asked Jun 5, 2019 at 10:30
mfamfa
7097 silver badges20 bronze badges
4
-
2
Could not replicate locally - I see the pleted callback get invoked when making an
HttpClient#get
with{ responseType: 'blob' }
and afinalize
in thepipe
. – jonrsharpe Commented Jun 5, 2019 at 10:38 - Press F12 and tell us what's on network. What do you see in response? – JWP Commented Jun 5, 2019 at 11:02
- 1 I tried to create a stackblitz. Used the same versions of all the libraries but I can't replicate it either. It just works in the sb: stackblitz./edit/… – mfa Commented Jun 5, 2019 at 11:42
- @JohnPeters network tab looks normal, the request is in there with a code of 200 and the content looks fine. – mfa Commented Jun 5, 2019 at 11:45
1 Answer
Reset to default 10So it turns out the problem was in the getToken function of my auth service. I had forgotten to plete the observable after returning the token! Since the httpClient.get observable is switch mapped through my getToken observable it was causing my subscription in onDownloadClicked to never plete.
// from my auth service
getToken(resource: string): Observable<string> {
return Observable.create((observer: Observer<string>) => {
this.context.acquireToken(resource, (error, token) => {
if (token) {
observer.next(token);
observer.plete(); // this was missing
}
else {
this.login();
}
});
});
}
本文标签: javascriptAngular HttpClient observable not completingStack Overflow
版权声明:本文标题:javascript - Angular HttpClient observable not completing - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1743971587a2570710.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论