Angular Typescript service file get all product names from data file

Hi, in my service file, I would like to get all productnames from the productlist array

here is my data:

export const PACKAGEPRODUCTS: any = [ { packagename: 'Package 1' }, { productlist: [ { productname: 'product1' }, { productname: 'product2' }, { productname: 'product3' }, ] }, { packagename: 'Package 2' }, { productlist: [ { productname: 'product3' }, { productname: 'product6' }, ] }, { packagename: 'Package 3' }, { productlist: [ { productname: 'product6' }, { productname: 'product9' } ] }, { packagename: 'Package 4' }, { productlist: [ { productname: 'product2' }, { productname: 'product3' }, { productname: 'product5' } ] } ];

I have written something like what I require in PHP but need this in TypeScript

 foreach (packages as package){
      foreach ($package['products'] as $product) {
        if($fullProductList.indexOf($product) == -1) {
          $fullProductList.push($product);
        }
      }
    }

So, I have made a start by writing the following:

getFullProductList() {
    
    this.packageproducts.forEach(
      //if condition here 
    );
      return this.packageproducts.slice();
    }

hmm maybe I should be coding this in my component typescript file not my service typescript file

(this is an old post, but is a “new” post in the new Web Development category, so I’ll reply with an answer since it pertains to Angular :wink: )

First off, be sure to format your data properly so we can read it hehe (you formatted the code correctly, but not that products array):

export const PACKAGEPRODUCTS: any = [
  { packagename: "Package 1" },
  {
    productlist: [
      { productname: "product1" },
      { productname: "product2" },
      { productname: "product3" }
    ]
  },
  { packagename: "Package 2" },
  { productlist: [{ productname: "product3" }, { productname: "product6" }] },
  { packagename: "Package 3" },
  { productlist: [{ productname: "product6" }, { productname: "product9" }] },
  { packagename: "Package 4" },
  {
    productlist: [
      { productname: "product2" },
      { productname: "product3" },
      { productname: "product5" }
    ]
  }
];

I would keep this logic in the service file, as it should handle the “dirty” buisness logic instead of your component. The idea behind this is mainly so you abstract away some complexity with a service (or multiple) so the component has to care about less and less.

Also, I’d personally recommend not mixing the packageNames and the product lists. Put them inside of each other, or use nested arrays, or take a totally different approach. Right now mixing and matching data is asking for trouble. I’m not sure where this data is coming from, but I’d consider refactoring it (thus making this logic unnecessary but I digress)


solution

getFullProductList() {
  return PACKAGEPRODUCTS.reduce((productNames, productObj) => {
    if (productObj.productlist) {
      // if the item in the array has the productlist attribute, we
      // add it to the array
      productNames.push(...productObj.productlist);
    }
    return productNames;
  }, []);
}

example gist to run locally