Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ionic infiniteScroll: TypeError: Cannot read property '0' of undefined

I'm trying to display all items in a category. I have the slug or the keyword of a category, I can use that to identify the parent category, I get the parent category and use that to search for all categories having similar parent. I have two pagination related errors, the errors are related.

The url ads_url: https://jokerleb.com/wp-json/wp/v2/ads?per_page=100&&page=. For example page=1

service

  getAds(page): Observable<any[]> {
    return this.http.get(this.api_url + page)
      .flatMap((ads: any[]) => {
        if (ads.length > 0) {
          return Observable.forkJoin(
            ads.map((ad: any) => {
              return this.http.get(this.ads_thumb_url + ad.id)
                .map((res: any) => {
                  let media: any = res;
                  ad.media = media;
                  return ad;
                });
            })
          );
        }
        return Observable.of([]);
      });
  }

ts

  constructor(public navCtrl: NavController, public navParams: NavParams, public renderer: Renderer, public zone: NgZone, public adsProvider: AdsProvider) {

    this.category = this.navParams.get('category');

    this.loadAds();
  }
  loadAds(infiniteScroll?) {
    this.adsProvider.getAds(this.page).subscribe((data: any) => {
      if (!this.category.main) {
        if (this.category.slug) {
          for (let i = 0; i < data.length; i++) {
            if (data[i] !== undefined) {
              if (data[i].pure_taxonomies.ad_cat[0].slug.trim().toLowerCase() === this.category.slug.trim().toLowerCase()) {
                this.item_category = data[i].pure_taxonomies.ad_cat[0].term_id;
                break;
              }

            }
          }
          if (this.item_category !== undefined) {
            for (let i = 0; i < data.length; i++) {
              if (data[i].pure_taxonomies !== undefined) {
                if (data[i].pure_taxonomies.ad_cat[0].term_id === this.item_category ||
                  data[i].pure_taxonomies.ad_cat[0].slug.trim().toLowerCase() === this.category.slug.trim().toLowerCase()) {
                  this.items.push(data[i]);
                }
              }
            }
          }
        }
      } else {
        if (this.category.main === 2) {
          for (let i = 0; i < data.length; i++) {
            if (data[i] !== undefined) {
              if (data[i].pure_taxonomies.ad_cat[0].slug.trim().toLowerCase() === this.category.slug.trim().toLowerCase()) {
                this.item_category = data[i].pure_taxonomies.ad_cat[0].parent;
                break;
              }

            }
          }
          if (this.item_category !== undefined) {
            for (let i = 0; i < data.length; i++) {
              if (data[i].pure_taxonomies !== undefined) {
                if (data[i].pure_taxonomies.ad_cat[0].parent === this.item_category) {
                  this.items.push(data[i]);
                }
              }
            }
          }
        }
      }
      if (infiniteScroll) {
        infiniteScroll.complete();
      }
    });
  }
  loadMore(infiniteScroll) {
    this.page++;
    this.loadAds(infiniteScroll);
  }

html

<ion-content fullscreen class="home-content" [ngSwitch]="tab">
  <div *ngIf="items.length>0; then thenTemplateName else elseTemplateName">
  </div>
  <ng-template #thenTemplateName>
    <div class="all-lists">
      <div class="all-category" *ngSwitchCase="1">
        <ion-card class="category-card" *ngFor="let item of items" (click)="onShowItemDetail(item);">
          <span *ngIf="item.media.length">
            <img src="{{item.media[item.media.length-1].media_details.sizes.medium.source_url}}" />
          </span>
          <div class="card-title" text-uppercase>
            <h4 color="secondary">{{item?.title.rendered}}</h4>
          </div>
        </ion-card>
      </div>
    </div>
    <ion-infinite-scroll (ionInfinite)="loadMore($event)" loadingSpinner="bubbles">
      <ion-infinite-scroll-content></ion-infinite-scroll-content>
    </ion-infinite-scroll>
  </ng-template>
  <ng-template #elseTemplateName>
    <div class="all-lists">
      <div class="all-category" *ngSwitchCase="1">
        <ion-card text-center>
          <ion-card-header>
            This Category is empty
          </ion-card-header>
          <ion-card-content>
            This Category is empty
          </ion-card-content>
        </ion-card>
      </div>
    </div>
  </ng-template>
</ion-content>

Sometimes I get TypeError: Cannot read property '0' of undefined, if item not found, I don't get the error, the error happens if I scroll down too much, loadMore() function gets called, it finds nothing and I get the error.

I might have two problems in my code, due to loadMore and pagination, the first one being the error above and the second one is that sometimes the last 2 or 3 items don't show. Perhaps I'm increasing the page without checking if there are still items on to be displayed. I don't know how to fix that.

I think if there's a way to tell whether items exist before paginating, both errors will be fixed.

like image 448
Lynob Avatar asked Aug 30 '18 22:08

Lynob


People also ask

What does the TypeError cannot read properties of undefined (Reading 0) mean?

Uncaught TypeError: Cannot read properties of undefined (reading '0') This issue usually occurs when you are trying to access an element in the array and the array does not contain elements, instead has a value undefined. First, let's replicate the issue.

Why can’t I call a function on an undefined variable?

In JavaScript, properties and functions can only belong to objects. Since undefined is not an object type, calling a function or a property on such a variable causes the TypeError: Cannot read property of undefined.

What is the meaning of undefined in JavaScript?

Undefined means that a variable has been declared but has not been assigned a value. In JavaScript, properties and functions can only belong to objects. Since undefined is not an object type, calling a function or a property on such a variable causes the TypeError: Cannot read property of undefined.


1 Answers

As you already mentioned in the question, this happens when you try to access elements when they are empty. You can handle with a if check wherever you are trying to access items as follows,

if(data && data.length > 0){
  for (let i = 0; i < data.length; i++) {
}
like image 101
Sajeetharan Avatar answered Nov 13 '22 23:11

Sajeetharan