0

I am porting some code from an AngularJS component into an Angular 5 component.

I have an array of objects loaded into a variable productlist.

In my old controller, I created a second variable as an empty array, showcaselist.

I run a forEach loop on the productlist to find all items that meet a condition (item.acf.product_slide.length > 0) and push them into the showcaselist. I then display these items in my template.

Logging to console shows the data is coming in, and the if statement works, but I keep getting a console error: TypeError: undefined is not an object (evaluating 'this.showcaselist')

Here is the whole component:

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';


@Component({
  selector: 'pb-ds-showcaseindex',
  templateUrl: './showcaseindex.component.html'
})
export class ShowcaseindexComponent implements OnInit {

  productlist;
  showcaselist = [];

  constructor(private _route: ActivatedRoute) { }


  ngOnInit() {
    this.productlist = this._route.snapshot.data.showcases;
    this.itemsWithSlides();

  }

  itemsWithSlides = function () {
    this.productlist.forEach(function (item) {
      if (item.acf.product_slide.length > 0) {
        this.showcaselist.push(item);
      }
    });
  };
}
3
  • 1
    itemsWithSlides = function.... is not correct syntax. Commented Jan 26, 2018 at 19:08
  • 3
    @Phax The syntax is correct, just unusual. Instead of declaring a method in the ES6 style it assigns a function to that property name. Commented Jan 26, 2018 at 19:12
  • Yes, we did it all the time in ES5. I'm still getting used to ES6/TS. Commented Jan 26, 2018 at 19:20

3 Answers 3

2

You could shorten the whole thing up using the filter() function

export class ShowcaseindexComponent implements OnInit {
  productlist;
  showcaselist = [];

  constructor(private _route: ActivatedRoute) { }


  ngOnInit() {
    this.productlist = this._route.snapshot.data.showcases;
    this.showcaseList = this.productList.filter(item => item.acf.product_slide.length > 0);
  }
}
Sign up to request clarification or add additional context in comments.

2 Comments

That's pretty awesome. I had no knowledge of the filter() function. Is that an ES6 thing?
Yep! With .map(), .reduce(), and .filter(), you can cut out most of your for loops. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
1

Try this:

ngOnInit() {
    this.productlist = this._route.snapshot.data.showcases;
    this.itemsWithSlides(this.productList);
  }

private itemsWithSlides(productList) {
  if (productList) {
    productList.forEach(item => {
      if (item && item.acf.product_slide.length > 0) {
        this.showcaseList.push(item);
      }
    });
  }
}

Comments

0

Try using an arrow function instead - the current function is creating a new this that refers to a different object.

  itemsWithSlides = () => {
    this.productlist.forEach((item) => {
      if (item.acf.product_slide.length > 0) {
        this.showcaselist.push(item);
      }
    });
  };

1 Comment

Thanks. Arrow functions are new to me. I figured it had something to do with the "this", though.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.