在使用 apollo 时,Angular 18 错误未在 30 秒内渲染

问题描述 投票:0回答:1

我发现使用 Angular 18 SSR 尝试控制来自 grapqhl-apollo 的错误响应时出现错误,服务器方法在 30 秒后返回错误,并且从带有可观察的 Angular 客户端返回错误,当我收到错误响应时,我必须仅显示加载或错误警报,但组件未渲染,30 秒后显示错误“页面/未在 30 秒内渲染”。

成分:

@Component({
selector: 'app-shop',
standalone: true,
imports: [SidebarMenuComponent, ProductCardComponent, ProductCardSkeletonComponent],
templateUrl: './shop.component.html',
styleUrl: './shop.component.css'
})
export default class ShopComponent implements OnInit{
//...

public productsPaginatedResp = signal<ProductPaginatedResponse>({
  loading: true,
  products: [],
  error: false,
  hasNextPage: false,
  hasPreviousPage: false,
  totalCount: 0
});


ngOnInit(): void {
 //se suscribe a los cambios en la url
 this.route.queryParams.subscribe(params => {
  if (!this.isNavigating) {
    const after = params['after'] ? atob(params['after']) : null;
    const before = params['before'] ? atob(params['before']) : null;
    this.updateProductsPaginated(after, before, false);
  } else {
    this.isNavigating = false;
  }
 });
}

updateProductsPaginated(after: string | null = null, before: string | null = null, 
updateUrl: boolean = true) {

this.productsPaginatedResp.update(prev => ({
  ...prev,
  loading: true,
  error: false
}));

let observable$;

if (after) {
  observable$ = this.productsService.getProductsPaginatedAfter(this.defaultItemsShow, after);
} else if (before) {
  observable$ = this.productsService.getProductsPaginatedBefore(this.defaultItemsShow, before);
} else {
  observable$ = this.productsService.getProductsPaginatedAfter(this.defaultItemsShow, null);
}

observable$.subscribe(
  (response: ProductPaginatedResponse) => {
    console.log(response, "resp");

    if (response.error) {
      this.showErrorMessage('An error occurred while fetching products');
      this.productsPaginatedResp.update(prev => ({
        ...prev,
        loading: false,
        error: true,
        products: []
      }));
    } else {

      this.productsPaginatedResp.set(response);

      // Evitar recarga infinita
      if (updateUrl) {
        this.updateUrlParams(before, after);
      }
    }
  },
  (error: any) => {
    console.error('Subscription error:', error);
    // Manejar cualquier error inesperado en la suscripción
    this.showErrorMessage('An unexpected error occurred');
    this.productsPaginatedResp.update(prev => ({
      ...prev,
      loading: false,
      error: true,
      products: []
    }));
  }
);
}
//...

服务:

export class ProductsService {
 private apollo = inject(Apollo);

 getProductsPaginatedAfter(quantity: number, after: string | null): Observable<ProductPaginatedResponse> {
 return this.apollo.watchQuery({
  query: GET_AFTER_PRODUCTS,
  variables: { first: quantity, after: after }
 }).valueChanges.pipe(
  map(({ data, errors }: any) => {
    if (errors && errors.length) {
      throw new Error(errors.map((err: any) => err.message).join(', '));
    }
    return {
      loading: false,
      products: data.productsPaginated?.nodes || [],
      hasNextPage: data.productsPaginated?.pageInfo.hasNextPage || false,
      hasPreviousPage: data.productsPaginated?.pageInfo.hasPreviousPage || false,
      startCursor: data.productsPaginated?.pageInfo.startCursor,
      endCursor: data.productsPaginated?.pageInfo.endCursor,
      totalCount: data.productsPaginated?.totalCount || 0,
      error: false
    } as ProductPaginatedResponse;
  }),
  catchError(error => {
    console.error('Holi GraphQL error:', error.message);
    return of({
      loading: false,
      products: [],
      hasNextPage: false,
      hasPreviousPage: false,
      startCursor: undefined,
      endCursor: undefined,
      totalCount: 0,
      error: true
    } as ProductPaginatedResponse);
  })
 );
}
}

enter image description here

angular rxjs server-side-rendering apollo-client ngoninit
1个回答
0
投票

Apollo 可能会因为开放的 websocket(或持久的 setTimeout/setInterval)而导致应用程序不稳定。

要解决此问题,您必须在角度区域之外运行函数

ngZone.runOutsideAngular() => { ... }
© www.soinside.com 2019 - 2024. All rights reserved.