Сообщение HttpClient не завершается внутри гвардии разрешения, если оно не передано через `take (1)` - PullRequest
0 голосов
/ 21 мая 2018

У меня есть приложение Angular с маршрутизацией и решателем охраны.Защита разрешения является асинхронной и возвращает наблюдаемую информацию, возвращаемую из HttpClient.post - проблема в том, что запрос AJAX завершается, а наблюдаемая - нет, и поэтому распознаватель никогда не завершает свою работу, и страница никогда не отображается.Однако, когда я передаю результат через take(1), он завершается и работает нормально.Мой вопрос почему?Разве HttpClient.post не должен завершиться после того, как AJAX-запрос вернется нормально (200 OK)?

Вот код моего распознавателя:

@Injectable()
export class MyDataResolver implements Resolve<MyData> {
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot)
    : MyData | Observable<MyData> | Promise<MyData> {
    return this.svc.getData().pipe(take(1)); // <-- Why is take(1) necessary here??
}

constructor(private svc: MyService) { }

}

Вот метод обслуживания, который вызывает post:

import { HttpClient } from '@angular/common/http';

export class MyService {
  constructor(private http: HttpClient) {}

  getData(): Observable<MyData> {
    return this.http.post('/api/data'), {}).pipe(
      map((resp: { data: SomeData }) => resp.data),
      map(r => convertSomeDataToMyData(r)));
  }
}

Спасибо

1 Ответ

0 голосов
/ 21 мая 2018

Я вынужден ответить на свой вопрос, так как я нашел ответ.Проблема связана с используемым мной перехватчиком, который является скрытой переменной на этом рисунке.

Мое приложение использует ngrx для управления избыточным магазином.И мой перехватчик касается магазина, чтобы получить токен авторизации.

Вот мой код перехватчика:

@Injectable()
export class TokenInterceptor implements HttpInterceptor {
  constructor(private store: Store<fromStore.State>,
    private route: Router) { }

  intercept(request: HttpRequest<any>, next: HttpHandler):
    Observable<HttpSentEvent
    | HttpHeaderResponse
    | HttpProgressEvent
    | HttpResponse<any>
    | HttpUserEvent<any>> {
    const rc = this.store.select(x => x.main.token).pipe(
      take(1), // <--- This is where the take(1) was needed
      switchMap(r => {
        const req2 = request.clone({
          setHeaders: {
            Authorization: `Bearer ${r}`
          }
        });
        return next.handle(req2);
      }));
      return rc;
  }
}

Как видите, без этого take(1) запрос измененперехватчиком фактически никогда не завершается, потому что подписка магазина никогда не завершается.

Надеюсь, этот неясный случай кому-нибудь поможет:)

...