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

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++) {
}

Try this (I added more checks)

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 && (data[i].pure_taxonomies.ad_cat || []).length ) {
              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 && (data[i].pure_taxonomies.ad_cat || []).length) {
                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 && data[i].pure_taxonomies && (data[i].pure_taxonomies.ad_cat || []).length) {
              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 && (data[i].pure_taxonomies.ad_cat || []).length) {
                if (data[i].pure_taxonomies.ad_cat[0].parent === this.item_category) {

                  this.items.push(data[i]);
                }
              }
            }
          }
        }
      }
      if (infiniteScroll) {
        infiniteScroll.complete();
      }
    });
  }

(I'm changing my answer to letting you know the problem with the "missing items".)

From your comment:

please clone social-login-untested branch, deploy it, go to ford, for example you'll see that only 1 car shows

And your question:

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.

So I cloned the social-login-untested branch of your GitHub repo, and tested the app locally.

I went to Vehicles → Cars → Ford, and noticed that there's only one item showing, which is actually as expected since on the first page (items 1st to 100th), there's only one "Ford" item, and the rest are on pages #2, etc.

Which means, the rest of the "Ford" items are only visible when you scroll down on the page — and only if you can scroll down the page.. i.e. the document's height is greater than the window's height.

Otherwise, you're stuck on page #1's results, and pages #2 and other pages would never be loaded. On Chrome, toggle the device toolbar → choose "Responsive" and try 400 x 320 px, like below:

At 400 x 320 px, you can scroll down, so all the "Ford" items would be loaded.

One way I could think of how you could fix the issue, is with a logic that looks something like this (see the CategoryDetailsPage.loadAds() in src/pages/category-details/category-details.ts):

if ( {DOCUMENT'S HEIGHT} <= {WINDOW'S HEIGHT} ) {
  // Loads next page without waiting for the scrolling to occur; but stops
  // loading when scrolling starts - for that, the logic is not included.
  this.loadMore( infiniteScroll );
} else if ( infiniteScroll ) {
  infiniteScroll.complete();
}

.. but (since I'm actually less experienced in AngularJS and Ionic) you would need to create that on your own.. You may also want to add a listener to the window/document onscroll event and stop the loadMore() on page scroll. And make sure there are no (or just remove/hide) duplicate items.

Nonetheless, I hope this "new" answer will help you. =)

Additional Note

As I pointed in my comment to your question, if necessary, you can retrieve the total available number of pages via the header X-WP-TotalPages. See https://developer.wordpress.org/rest-api/using-the-rest-api/pagination/