1

I have been playing around with the Angular UI Tree drag and drop and have come by an issue that has stumped me. The json is being received from my services. When it is received by my controller, I must format it properly with an empty array so it will be able to hold childen:

Formatting:

function categorySuccessPost(data) {
    var emptyCategoryArray = {
        Categories: []
    }
    for (var i = 0; i < data.length; i++) {
        $.extend(data[i], emptyCategoryArray);
    }
     $scope.categoryData = data;
}

It is now formatted and looks like:

[ { "CategoryId": 27054, "MerchantId": 5594, "ProductCategoryId": 1310,
"Name": "BulkUpload", "Description": "BulkUpload", "DateCreated": 
"/Date(1446793200000-0000)/", "IsActive": true, "IsDefault": false, "ItemCount":
 5, "ResponseStatus": { "ErrorCode": "SUCCESS" }, "TotalRecordCount": 15, 
"Categories": [] }, { "CategoryId": 23267, "MerchantId": 5594, 
"ProductCategoryId": 818, "Name": "Coupon", "Description": "Coupon", 
"DateCreated": "/Date(-62135596800000-0000)/", "IsActive": true, "IsDefault":
 true, "ItemCount": 1, "ResponseStatus": { "ErrorCode": "SUCCESS" }, 
"TotalRecordCount": 15, "Categories": [] } }

I have tried two different functions when attempting to add a child:

Function 1 (Uses model value):

$scope.newSubItem = function (scope) {
        var currentCategoryData = scope.$modelValue;
        currentCategoryData.Categories.push({
            CategoryId: currentCategoryData.CategoryId * 10 + currentCategoryData.Categories.length,
            Name: currentCategoryData.Name + '.' + (currentCategoryData.Categories.length + 1),
            Categories: []
        });
    };

Function 2 (Uses index of object in the array, and yes, I have made sure the correct index is being passed):

$scope.newSubItem = function (index) {
        var array = $scope.categoryData;
        array[index].Categories.push({
            CategoryId: 12312,
            Name: 'test',
            Categories: []
        });
    };

The issue is that instead of pushing the new data to the selected index, it adds the json to every Categories :

[ { "CategoryId": 27054, "MerchantId": 5594, "ProductCategoryId": 1310, 
"Name": "BulkUpload", "Description": "BulkUpload", "DateCreated": 
"/Date(1446793200000-0000)/", "IsActive": true, "IsDefault": false, "ItemCount":
 5, "ResponseStatus": { "ErrorCode": "SUCCESS" }, "TotalRecordCount": 15, 
"Categories": [ { "CategoryId": 12312, "Name": "test", "Categories": [] } ] }, {
 "CategoryId": 23267, "MerchantId": 5594, "ProductCategoryId": 818, "Name": "Coupon", "Description": "Coupon", "DateCreated": "/Date(-62135596800000-
0000)/", "IsActive": true, "IsDefault": true, "ItemCount": 1, "ResponseStatus":
 { "ErrorCode": "SUCCESS" }, "TotalRecordCount": 15, "Categories": [ { 
"CategoryId": 12312, "Name": "test", "Categories": [] } ] }

enter image description here

I am not showing the HTML because it does not appear to be an issue. Here's where I have narrowed it down to, but still have no explanation:

If I use the data that goes through the $.extend method then it adds a child to every parent. But if I copy the json that is generated after the formatting, put it into and object and then read from that, then it only adds a child to the selected parent like I want. But it is necessary to add the empty array. Any idea why this is happening and any solution?

EDIT

One more piece of information that may be important: When I add a full Category (different function), rather than adding a subcategory and then try to add a child to the newly generated category then it works correctly (adding only a child to that category):

$scope.addCategory = function () {
            var name = $scope.categoryName;
            // Temporary
            var categoryId = Math.floor((Math.random() * 50000) + 1)
            console.log(name, categoryId)
            $scope.categoryData.unshift({ CategoryId: categoryId, Name: name, Categories: [] })
            $scope.categoryName = "";
            $("#addCategoryModal").modal('hide');
            Notification.success({ message: 'Category Added Successfully!', delay: 3000 });
        }
cfly24
  • 1,882
  • 3
  • 22
  • 56

1 Answers1

0

I'm still not sure exactly why this is happening, but this was my solution to fixing the issue:

Remove the $.extend for loop and $.extend function:

function categorySuccessPost(data) {
     $scope.categoryData = data;
}

When adding an item, check if the array has been initialized, if not, create it in the current scope:

$scope.newSubItem = function (scope) {
    var currentCategoryData = scope.$modelValue;
    if(currentCategoryData.Categories === 'undefined'){
        currentCategoryData.Categories = [];
    }
    currentCategoryData.Categories.push({
        CategoryId: currentCategoryData.CategoryId * 10 + currentCategoryData.Categories.length,
        Name: currentCategoryData.Name + '.' + (currentCategoryData.Categories.length + 1),
        Categories: []
    });
};

The issue with this method is that you can no longer drag a node into an empty parent.

cfly24
  • 1,882
  • 3
  • 22
  • 56