Populate array with foreach in foreach javascript (angular)

I have categories. and each category has elements. now i am returning category list and item list from api.

now in angular i want to do this into 1 object. I did the following:

        if ($scope.categories_norm) {
            $scope.delivery_items = [];

            //get categories
            angular.forEach(data.item_categories.normal_categories, function (v, k) {
                //push categories
                $scope.delivery_items.push(v);

                //push items for categories
                var i = 0;
                if ($scope.items) {
                    angular.forEach($scope.items, function (val, key) {
                        i++;
                        if (val.item_category_id == v.item_category_id) {
                        //console.log();
                            $scope.delivery_items[k][i].push(val);
                        }
                    });
                }
            });
        }

      

for some reason i can't fill it. it returns errors: TypeError: Cannot read property "push" of undefined

how should i do this properly? I want an object inside each category object with all elements

+3


source to share


2 answers


I think the problem is k

to $scope.delivery_items[k][i].push(val);

change it on v

and see what happens.

EDIT:



Ok, after looking at your question again, I thought this might work better:

if ($scope.categories_norm) {
        $scope.delivery_items = {}; // create empty object
        //get categories
        angular.forEach(data.item_categories.normal_categories, function (v, k) {
            var catagery = v.category_name; // create cataogry variable scoped to this block
            $scope.delivery_items[category] = {}; //create empty category object using category name as the key
            if ($scope.items) {
                angular.forEach($scope.items.filter(check_item_category(v.item_category_id)), function (val, key) {
                    $scope.delivery_items[category][category_info] = v; // comment out or omit this line if you don't want category information included within the category
                    $scope.delivery_items[category][val.item_name] = val; // set item object to it corosponding name
            });
        };
    });
}

function check_item_category (category_id) {
    return function(item) {
        return item.item_category_id == category_id
    }
}

      

You still have to fill in a bit (namely how to get the category and item names), but that should be what you want.

EDIT: I switched to using a filter, I just didn't like seeing the ID check for each item, I think using a filter would just be cleaner.

EDIT:



As a result, it should have an object like this:

{
    "category_1" : {
        "category_info" : category_object,
        "item_1" : item_1_object,
        "item_2" : item_2_object
    }
    "category_2" : {
        "category_info" : category_object,
        "item_1" : item_1_object,
        "item_2" : item_2_object,
        "item_3" : item_3_object,
    }
    "category_3" : {
        "category_info" : category_object,
        "item_1" : item_1_object,
        "item_2" : item_2_object,
        "item_3" : item_3_object,
    }
}

      

EDIT: Ok, the last time I looked at this again and realized that it could be done faster (reduction in time $scope.items

is done by iteration) and at the same time remove duplicate data (item name is in both key and object object).

Please note that you will not be storing the category object along with the category if you use this solution

if ($scope.categories_norm) {
        $scope.delivery_items = get_items_sorted_by_category(data.item_categories.normal_categories,$scope.items) // create empty object
    });
}

function get_items_sorted_by_category(categories,items) {
    var filled_object = {}
    for(var category in categories){
        //will need to change how you set the catagory name as I don't know how this object looks
        filled_object[category.name] = items.filter(check_item_category(category.item_category_id)) // will filter out any objects that don't have the correct caragory ID
    };
    return filled_object;
}

function check_item_category (category_id) {
    return function(item) {
        return item.item_category_id == category_id
    }
}

      

you should get an object that looks like this:

{
    "category_1" : [
        "item_1", 
        "item_2", 
        "item_3"
    ]
    "category_2" : [
        "item_1",
        "item_2",
        "item_3"
    ]
    "category_3" : [        
        "item_1",
        "item_2",
        "item_3"
    ]
}

      

0


source


Remove '[i]'

    if ($scope.categories_norm) {
        $scope.delivery_items = [];

        //get categories
        angular.forEach(data.item_categories.normal_categories, function (v, k) {
            //push categories
            $scope.delivery_items.push(v);

            //push items for categories
            var i = 0;
            if ($scope.items) {
                angular.forEach($scope.items, function (val, key) {
                    i++;
                    if (val.item_category_id == v.item_category_id) {
                    //console.log();
                        $scope.delivery_items[k].push(val);
                    }
                });
            }
        });
    }

      



Or remove 'push':

    if ($scope.categories_norm) {
        $scope.delivery_items = [];

        //get categories
        angular.forEach(data.item_categories.normal_categories, function (v, k) {
            //push categories
            $scope.delivery_items.push(v);

            //push items for categories
            var i = 0;
            if ($scope.items) {
                angular.forEach($scope.items, function (val, key) {
                    i++;
                    if (val.item_category_id == v.item_category_id) {
                    //console.log();
                        $scope.delivery_items[k][i] = val;
                    }
                });
            }
        });
    }

      

0


source







All Articles