【问题标题】:ERROR TypeError: Cannot read property 'concat' of undefined错误类型错误:无法读取未定义的属性“concat”
【发布时间】:2019-05-09 18:29:50
【问题描述】:

在我的组件中,如果我向下滚动列表,我会调用这个函数来获取更多数据:

  onScroll(event) {
    if (this.shouldGetData(event.srcElement)) {
      this.store.dispatch(new StartAppendRoutesList());
    }
  }
  /* support methods */

  shouldGetData(targetEventElement) {
    return this.scrollAskForData(targetEventElement) && !this.alllistAlreadyFetched;
  }

  scrollAskForData(targetEventElement): boolean {
    const scrollPercentage = ((targetEventElement.clientHeight + targetEventElement.scrollTop) / targetEventElement.scrollHeight) * 100;
    return scrollPercentage > constants.SCROLL_PERCENTAGE_THRESOLD_TO_GET_DATA;
  }

在我的副作用中,我有以下几点:

  @Effect()
  appendRoutes = this.actions$.pipe(
    ofType(RoutesListActionTypes.StartAppendRoutesList),
    switchMap((action: StartAppendRoutesList) => this.service.getRoutes(fromRoot.initialStateRouteList.currentOffset)
      .pipe(
        switchMap(result => of(new EndAppendRoutesList(result))),
        catchError(err => of(new OnError(err.message)))
      ))
  );

我的行为如下:

  StartAppendRoutesList = '[routes] Starting Adding More items to route list',
  EndAppendRoutesList = '[routes] Ending Adding More items to route list',

并具有以下代码:

export class EndAppendRoutesList implements Action {
  readonly type = RoutesListActionTypes.EndAppendRoutesList;
  payLoad: RouteList;

  constructor(payLoad: RouteList) {
    this.payLoad = payLoad;
  }
}

export class StartAppendRoutesList implements Action {
  readonly type = RoutesListActionTypes.StartAppendRoutesList;
}

我的减速器是这样的:

case RoutesListActionTypes.StartAppendRoutesList:
  return {
    ...state,
    processingRoute: true,
  };
case RoutesListActionTypes.EndAppendRoutesList:
  const queryResult = action;
  return {
    ...state,
    processingRoute: false,
    currentOffset: state.currentOffset + 5,
    routesList: {
      results: state.routesList.results.concat(queryResult.payLoad.results)
    }
  };

现在乍一看,当我应用偏移量以检索一定数量的数据,或者如果我选择检索服务中的整个列表时,一切正常:

  getRoutes(offset: number): Observable<any> {
    const numberToRetrieve = 5;
    const routes = configUrl.routeBaseUrl["routes"]["results"];
    return of(routes.slice(offset, numberToRetrieve));
  }

但是一旦它到达列表的末尾,它就会开始给我这个错误:

显示的错误出现在我的 reducer 中的 concat 方法中:

routesList: {
  results: state.routesList.results.concat(queryResult.payLoad.results)
}

我尝试通过创建一个方法来寻找解决方案,该方法将在我的 createStateSubscriptions 方法中返回一个 fetched indicator,该方法在 ngOnInit 中被调用,如下所示:

  alllistAlreadyFetched = false;
  ngOnInit() {
    // state subscriptions
    this.createStateSubscriptions();
    // attaching listeners
    this.createEventScrollSubscription();
    // getting initial data
    this.store.dispatch(new StartLoadRoutesList());
  }

  /* subscriptions and observables creation methods*/
  createStateSubscriptions() {
    // state observable use directly in view through async pipe
    this.listObservable$ = this.store
      .select((state: RoutesListState) => state);

    // all routes fetched indicator
    this.listStateSubscription$ = this.store
      .select(allListItemsAlreadyFetchedValidators)
      .subscribe((allRoutesFetched: boolean) => {
          this.alllistAlreadyFetched = allRoutesFetched;
      });
  }

而我的allListItemsAlreadyFetchedValidators selector 是这样的:

export const allListItemsAlreadyFetchedValidators = createSelector(
  selectRoutesList,
  state => state.routes.currentOffset,
  (currentOffset, TotalRoutes) => currentOffset.currentOffset >= TotalRoutes
);

然后我在.select(allListItemsAlreadyFetchedValidators) 的组件中遇到另一个错误,如下所示:

ERROR in side-list/side-list.component.ts(43,15): error TS2345: Argument of type 'MemoizedSelector<State, boolean>' is not assignable to parameter of type '"routesList" | "processingRoute" | "processingDetail" | "currentOffset" | "selectedRouteItemId" | "selectedRouteItemData" | "errorMessage"'.
  Type 'MemoizedSelector<State, boolean>' is not assignable to type '"errorMessage"'.

这是我的 HTML:

<div class="routes-container">
  <div class="wrapper-scroll-y grid-scrollbar">
    <header class="header" role="banner">
      <h1 class="logo">
        <a><span>Routes :</span></a>
        <mat-icon class="icon">add</mat-icon>
      </h1>
      <div class="nav-wrap">
        <nav class="main-nav" role="navigation">
          <ul class="unstyled list-hover-slide" *ngFor="let route of (listObservable$|async).routes.routesList">
            <li (click)= "onListItemSelected($event, route.id)"><a>{{route.name}}</a></li>
          </ul>
        </nav>
      </div>
    </header>
  </div>
  <app-loader-indicator [show]="(listObservable$|async).processingRoute"></app-loader-indicator>
</div>

【问题讨论】:

    标签: angular ngrx


    【解决方案1】:

    如果您的 state.routesList.results 未定义或不是数组,您将面临该错误。要解决它,您必须在 concat 方法之前检查它。如果它不是数组或未定义,您可以直接将结果设置为 queryResult.payLoad.results

    routesList: {
      results: (state.routesList.results && state.routesList.results instanceOf Array)? state.routesList.results.concat(queryResult.payLoad.results) : queryResult.payLoad.results
    }
    

    【讨论】:

    • 然后我得到错误错误:尝试比较 [object Object] 时出错。 DefaultIterableDiffer.push 只允许使用数组和可迭代对象,它们在我的组件的 html 中位于
      • 它在第一次检索前 5 个数据时工作,但是一旦我向下滚动我得到那个错误,它与提取结束有关
      猜你喜欢
      • 1970-01-01
      • 2019-05-30
      • 2018-04-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-03
      • 2021-11-22
      • 2018-07-12
      相关资源
      最近更新 更多