Unstable work of splice in Angular JS - angularjs

I try to delete element from array of objects:
ng-click="deleteSpecialization(item)"
Where item is item from ng-repeat:
ng-repeat="item in data"
My function:
$scope.deleteSpecialization = function (item) {
var index = $scope.data.indexOf(item);
if (index != -1) {
$scope.data.splice(index, 1);
}
}
This code removes some items in template HTML after second click. I do one ng-clickbut template changes incorrect.
Format:
[{"name":"A","checked":false,"id":"6"},{"name":"B","checked":false,"id":"8"},{"name":"C","checked":false,"id":"10"},{"name":"D","checked":false,"id":"12"},

Here is the working demo of splice functionality, although you write the absolutely fine for splice.
https://codepen.io/kashifmustafa/pen/VvjqwE
$scope.deleteSpecialization = function (item) {
var index = $scope.data.indexOf(item);
if (index != -1) {
$scope.data.splice(index, 1);
}
}

Hello Demo is here http://jsfiddle.net/qjcqwhsw/2/
$scope.deleteItem = function(item){
var index = $scope.data.indexOf(item);
$scope.data.splice(index, 1);
};
hope this may help you

Related

ng-repeat is commened in the browser Element section in AngularJs?

I have to call the firebase function for get the sellerProducts but in my case function is called peoperly and array is display in the element console but ng-repeat data is commented what is the problem in my code?
//FUNCTION FOR GET THE LIST OF PRODUCT'S
$scope.productArray = [];
$scope.getProductData = function() {
firebase.database().ref("sellerProduct").once('value').
then(function(snapshot) {
var value = snapshot.val();
$scope.productArray = objToArray(value);
});
}
$scope.getProductData();
<div class="productInfo w3-col m3 w3-card-4 w3-margin-left"
ng-repeat="list in filtered = (productArray | filter: product) | filter:brandFilter">
</div>
As far as I could suggest it is much better to NOT use ng-filter at all inside a ng-repeat as it will cost you severe performance issue later on.
so instead of doing this:
ng-repeat="list in filtered = (productArray | filter: product) | filter:brandFilter"
just simply use:
ng-repeat="list in productArray"
then in your JS code format the array first the way you wanted it to be displayed, before assigning it to $scope.productArray
.then(function(snapshot)
{
var value = snapshot.val();
// save the original array
$scope.productArrayOrig = angular.copy(objToArray(value));
$scope.productArray = $scope.filterByBrand();
});
});
// then just create a function that filters your projectData by brandFilter
$scope.filterByBrand = function ()
{
var finalData = [];
if ($scope.productArrayOrig)
{
// then loop it
for (var i = 0; i < $scope.productArrayOrig.length; i++)
{
var item = $scope.productArrayOrig[i];
if ($scope.brandFilter == item["brand"])
{
finalData.push(item);
}
}
}
return finalData;
};
hope that helps

Jquery - Adding and removing items from array

I want this click event to check to see if the item is in the array. If it is, remove it. If not, add it back in the same spot.
var myArray = ["apple","orange","pear","grape"];
$("button").click(function(){
if($.inArray(apple,myArray) != -1){
myArray.push(apple,1);
} else {
myArray.splice(apple,1);
}
alert(myArray);
});
Stores the last removed index in an external variable.
Changes myArray.push("apple"); for myArray.splice(lastRemovedIndex, 0, "apple");
Changes if($.inArray(apple,myArray) != -1) for $.inArray("apple", myArray) == -1.
Removes the element using the index myArray.splice(myArray.indexOf("apple"), 1);.
Don't forget the " around the element apple.
Updates the last remove index if the element is removed.
var myArray = ["apple", "orange", "pear", "grape"];
var lastRemovedIndex = -1;
$("#myBtn").click(function() {
if ($.inArray("apple", myArray) == -1) {
myArray.splice(lastRemovedIndex, 0, "apple");
} else {
var i = myArray.indexOf("apple");
myArray.splice(i, 1);
lastRemovedIndex = i;
}
alert(myArray);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="myBtn">Click me</button>

angularjs filter nested array-using-checkboxes-with-angularjs

I am following this approach to filter nested json response. I have a nested property like this:
instances:{
instance:[
{cname:'name1', location:'pa', price:40, model:'2014' },
{cname:'name1', location:'ga', price:30 , model:'2014'},
{cname:'name1', location:'ga', price:20, model:'2010' }
]}
I can filter by top level properties using the above mentioned example but not the child properties.
I have modified above example to show nested properties of my json here.http://jsfiddle.net/jackAndy/qygL2m01/4/. I am new to angularjs.
First of all - why You use instances.instance? It it not principally, use players.instances = [];
Use Group functions only 1 time after data loading; Watching filters - it's not necessary in this case;
Function for get filters values (I use underscore uniq function, You can use Your own algorithm for this):
$scope.getFieldsValues = function(field){
var result = [];
for(var i = 0; i < $scope.players.length; i++){
result.push($scope.players[i][field]);
}
return _.uniq(result);
};
Filter for players:
$scope.testFl = function(el){
for(var filter in $scope.filters){
var filterArray = [];
for(var i in $scope.filters[filter]){
if($scope.filters[filter][i]) filterArray.push(i);
}
//You can make array with instances properties & compare with it;
if(filter === 'location'){
if(el.instances && el.instances.length > 0){
var intersection = el.instances.filter(function(n) {
return filterArray.indexOf(n[filter]) != -1
});
} else if(filterArray.length > 0){return false;}
} else {
if(filterArray.length > 0 && filterArray.indexOf(el[filter]) === -1) return false;
}
}
return true;
};
Template:
<li ng-repeat="player in players | filter:testFl" >
Filter for instances:
$scope.testFl2 = function(el){
var filterArray = [];
for(var i in $scope.filters.location){
if($scope.filters.location[i]) filterArray.push(i);
}
return filterArray.length > 0 && filterArray.indexOf(el.location) === -1 ? false : true;
};
Template:
<span ng-repeat="loc in player.instances | filter:testFl2" >
Fiddle for this;
UPDATE:
Function for count:
$scope.getCount = function(field, value){
var obj = {};
obj[field] = value;
return _.where($scope.players, obj).length;
};
Update fiddle - update underscore, add count function;
I hope this will help you;
For answer were used:
Add underscore to jsfiddle;
variable property name in where underscore.js;

AngularJS, Add Rows

Morning,
We are trying to implement this add row Plunkr, it seems to work however our input data seems to repeat. Does anyone know of a solution to add a unique id to preview duplicated fields ?
Here is our current Plunkr and LIVE example.
$scope.addRow = function(){
var row = {};
$scope.productdata.push(row);
};
$scope.removeRow = function(index){
$scope.productdata.splice(index, 1);
};
$scope.formData you have is not an array, but just one object. All your rows are bound to that object and hence all of them reference the same data.
The reason you get a new row added is because your ng-repeat is bound to $scope.productData and you add extra record in it. You should bind your form elements to the properties in the row object that you create
a simple example is :
In your template
<div ng-repeat="product in products">
<input type="text" ng-model="product.title">
</div>
In your controller
$scope.addProduct = function(){
var product = {};
$scope.productData.add(product);
}
You'd then always only work with the productData array and bind your model to them.
Even in your backend calls, you'd use productData instead of your formData.
Hope this helps.
U can use a filter : This will return Unique rows only
app.filter('unique', function () {
return function (items, filterOn) {
if (filterOn === false) {
return items;
}
if ((filterOn || angular.isUndefined(filterOn)) && angular.isArray(items)) {
var hashCheck = {}, newItems = [];
var extractValueToCompare = function (item) {
if (angular.isObject(item) && angular.isString(filterOn)) {
return item[filterOn];
} else {
return item;
}
};
angular.forEach(items, function (item) {
var valueToCheck, isDuplicate = false;
for (var i = 0; i < newItems.length; i++) {
if (angular.equals(extractValueToCompare(newItems[i]), extractValueToCompare(item))) {
isDuplicate = true;
break;
}
}
if (!isDuplicate) {
newItems.push(item);
}
});
items = newItems;
}
return items;
};
});
I think the reason why this is happening is that the addRow() function is just pushing an empty son object into the $scope.productdata array, whereas all input fields are bound to $scope.formData[product.WarrantyTestDescription]. I think you mean to bind the input fields to the properties of the product object.

Angular filter returning an array of objects causing infinite $digest loop

I have a custom filter which returns an array of matches to search field input and it works, but only after causing an infinite $digest loop. This also apparently only began happening after upgrading from Angular 1.0.6. This is the filter code:
angular.module("Directory.searches.filters", [])
.filter('highlightMatches', function() {
var ary = [];
return function (obj, matcher) {
if (matcher && matcher.length) {
var regex = new RegExp("(\\w*" + matcher + "\\w*)", 'ig');
ary.length = 0;
angular.forEach(obj, function (object) {
if (object.text.match(regex)) {
ary.push(angular.copy(object));
ary[ary.length-1].text = object.text.replace(regex, "<em>$1</em>");
}
});
return ary;
} else {
return obj;
}
}
});
I've seen elsewhere that this could be caused by having the filter inside of an ng-show, or that it's because the array being returned is interpreted as a new array every time it's checked, but I'm not sure how I could fix either problem. You can see a production example of this issue at https://www.popuparchive.com/collections/514/items/4859 and the open source project is available at https://github.com/PRX/pop-up-archive. Thank you!
This is happening because of angular.copy(object). Each time the digest cycle runs, the filter returns an array of new objects that angular has never seen before, so the the digest loop goes on forever.
One solution is return an array containing the original items that match the filter, with a highlightedText property added to each item...
angular.module("Directory.searches.filters", [])
.filter('highlightMatches', function() {
return function (items, matcher) {
if (matcher && matcher.length) {
var filteredItems = [];
var regex = new RegExp("(\\w*" + matcher + "\\w*)", 'ig');
angular.forEach(items, function (item) {
if (item.text.match(regex)) {
item.highlightedText = item.text.replace(regex, "<em>$1</em>");
filteredItems.push(item);
}
});
return filteredItems;
} else {
angular.forEach(items, function (item) {
item.highlightedText = item.text;
});
return items;
}
}
});
You can bind to the highlightedText property, something like...
<div>
Results
<ul>
<li ng-repeat="item in items | highlightMatches : matcher" ng-bind-html="item.highlightedText"></li>
</ul>
</div>

Resources