Angular JS Empty Object Path to Array

I am working on a project that allows the user to control options and options. Basically the user can add a new type of parameter, let him name it “Color” and then add options “Black”, “Red”, “Purple”, etc. When the collection first loads existing entries, add an empty option at the end

When the user starts typing a text box, I want to add a new blank option, thus always presenting the user with a new field to work with.

It almost works for me, but I can't figure out how to properly add a new empty option to a new Option type or existing option types. The push method keeps crashing Plunkr. Any input is appreciated, an overview of the sample plunkr is below

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope) {

$scope.optionTypeId = 0;
$scope.productOptionId = 0;

$scope.productEditorModel = {
  "ProductOptions": [0],
  "OptionTypes": [0]
};

$scope.productEditorModel.optionTypeName = '';

$scope.addEmptyOption = function (optionTypeId) {

var emptyOption = { ProductOptionId: 3, ProductId: '1066', OptionTypeId: 1, OptionValue: '', Price: '', IsStocked: true };
console.log(emptyOption);
//$scope.productEditorModel.ProductOptions.push(emptyOption);
};

$scope.loadData = function () {

$scope.productEditorModel.OptionTypes = [{ OptionTypeId: 1, OptionName: 'Color' },{ OptionTypeId: 2, OptionName: 'Size' },];
  $scope.productEditorModel.ProductOptions = [{ ProductOptionId: 1, ProductId: '1066', OptionTypeId: 2, OptionValue: 'Medium', Price: '', IsStocked: true, },{ ProductOptionId: 2, ProductId: '1066', OptionTypeId: 1, OptionValue: 'Black', Price: '', IsStocked: true }];

angular.forEach($scope.productEditorModel.ProductOptions, function (item) {
      //console.log(item.OptionTypeId);
      $scope.addEmptyOption(item.OptionTypeId);
});
};

$scope.loadData();

$scope.removeOption = function (option) {
        var index =   $scope.productEditorModel.ProductOptions.indexOf(option);
        $scope.productEditorModel.ProductOptions.splice(index, 1);
};

$scope.filterEmptyElements = function (optionTypeId) {
$scope.emptyElements = $.grep($scope.productEditorModel.ProductOptions, function (k) { return k.OptionValue === "" || angular.isUndefined(k.OptionValue) && k.OptionTypeId == optionTypeId });
};

$scope.update = function (option, index) {
  var optionTypeId = option.OptionTypeId;
  $scope.filterEmptyElements(optionTypeId);

  if (!angular.isUndefined(option.OptionValue) && $scope.emptyElements.length == 1 && option.OptionValue.length > 0) {
      $scope.addOption(optionTypeId);
  } else if (angular.isUndefined(option.OptionValue)) {
      $scope.removeOption(option);
  }
}; 

$scope.addOptionType = function () {
  var optionTypeId = --$scope.optionTypeId;
  var optionName = $scope.productEditorModel.optionTypeName;
  var newOptionType = { OptionTypeId: optionTypeId, OptionName: optionName    };

  $scope.productEditorModel.OptionTypes.push(newOptionType);
  $scope.addEmptyOption(optionTypeId);
};

$scope.editOptionType = function (optionType) {
  $scope.editing = true;
};

$scope.saveOptionType = function (optionType) {
  $scope.editing = false;
};

$scope.trackOptionTypesCount = function () {
if ($scope.productEditorModel.OptionTypes.length == 3) {
    $scope.isMaxOptionTypes = true;
} else {
    $scope.isMaxOptionTypes = false;
}
};

$scope.removeOptionType = function (optionType) {
  var index = $scope.productEditorModel.OptionTypes.indexOf(optionType);
  $scope.productEditorModel.OptionTypes.splice(index, 1);
  $scope.trackOptionTypesCount();
};
});

      

See the plunker below: http://plnkr.co/edit/YHLtSwQWVb2swhNVTQzU?p=info

+3


source to share


1 answer


The error you are getting $ is not defined

is that you have not included jQuery. You don't need jQuery to do this, but array.map

should be able to do the same functionality.

$scope.emptyElements = $scope.productEditorModel.ProductOptions.map(function (k) { 
   return k.OptionValue === "" || angular.isUndefined(k.OptionValue) && k.OptionTypeId == optionTypeId 
});

      

And it will work because inside $scope.loadData

you have

angular.forEach($scope.productEditorModel.ProductOptions, function (item) {
    $scope.addEmptyOption(item.OptionTypeId);
});

      

and then inside $scope.addEmptyOption

you try

$scope.productEditorModel.ProductOptions.push(emptyOption);

      



So, foreach

will loop over each item in $scope.productEditorModel.ProductOptions

which you keep adding parameters like this ....? Infinite loop.

No crashing version: http://plnkr.co/edit/5Sc2sWfhKBs9kLCk83f1?p=preview

What you really should be doing is looking at the data structure. Make ProductOptions a sub-object of OptionTypes and simply rename it Options. Remove ALL the code about creating an id here in your GUI that the backend should handle. Instead, the GUI should have a Sortorder property in the settings (which is of course also stored in the backend). Then, when you store, the ones that don't have an ID get up, the ones that have an ID are updated. It's much easier to deal with this.

I would also rip out optionsTypes and options for my own services / providers. It's much easier to keep track of what needs to be done. And each just basically contains add, remove and maybe find / getJSON or something.

Here's a restructured version. It's much easier to keep track of what belongs. And it has more features than the original with less code. http://plnkr.co/edit/BHcu6vAfcpEYQpZKHc5G?p=preview

0


source







All Articles