Angularjs array changes reference after splice - arrays

I am using angularjs for my project and its working fine. Today I am facing little but different problem
so just need some kind of suggestion.
Consider code :
$scope.deleteEmpty = function(){
for(var sp=0;sp < $scope.column.length;sp++){
var offerings = $scope.column[sp];
if(offerings.spName == -1){
$scope.removeanswer(sp);
}
}
},
$scope.removeanswer = function(position){
for(var question=1;question<$scope.rows.length;question++){
$scope.rows[question].answerlst.splice(position, 1);
}
},
here i am deleting answerlst according to offerings position, it is getting deleted but the there is one problem. Consider one example:
$scope.column = [{'spName':'-1',spId:'1'},{'spName':'-1',spId:'2'},{'spName':'-1',spId:'3'},{'spName':'-1',spId:'4'}]
when first time call to $scope.removeanswer(sp); it delete answerlst for first column but after that the position of answerlst get changed. So it deletes for 1st and 3rd position and not for the whole.
Any suggestion please.
Thanks.

The following solution could be improved if there was more information.
The idea is to store the column indexes in a toRemove array and then remove them all at once from the answerlst of each question.
$scope.deleteEmpty = function(){
var toRemove = []; // column indexes to be removed
for(var sp=0;sp < $scope.column.length;sp++){
var offerings = $scope.column[sp];
if(offerings.spName == -1){
toRemove.push(sp);
}
}
$scope.removeanswer(toRemove);
},
$scope.removeanswer = function(positions){
for(var question=1;question<$scope.rows.length;question++){
$scope.rows[question].answerlst = $scope.rows[question].answerlst.filter(function(value, index) {
return positions.indexOf(index) < 0;
});
}
},

Related

How to stop original list from updating when cloned list is updated

I want to stop self.lineDetails from being updated when I update self.modifiedLineDetails.
self.modifiedLineDetails = [];
angular.forEach(self.lineDetails, function (value1, index1) {
var lineDetail = self.lineDetails[index1];
self.modifiedLineDetails.push(lineDetail)
});
console.log(self.lineDetails)
angular.forEach(self.modifiedLineDetails, function (value10, index10) {
var modifiedLineDetail = self.modifiedLineDetails[index10];
if (modifiedLineDetail.SelectedCustomers.length > 0) {
modifiedLineDetail.SelectedCustomers = 1;
} else {
modifiedLineDetail.SelectedCustomers = 0
}
});
console.log(self.modifiedLineDetails)
Previously I just assigned it like this self.modifiedLineDetails = self.lineDetails then I updated self.modifiedLineDetails but it wasn't working so I tried pushing it per line but self.lineDetails keeps updating.
You should clone an array and then modify your new array, one way to do this is using
spread operation ...
Here is the example of it:
var initialarray = [1,2,3,4];
var modification = [...initialarray];
modification.push(5);
console.log(initialarray);
console.log(modification);
Since the problem seems to be occurring because I was using angular. I researched and found angular.copy which creates a deep copy. The code below worked for me.
self.modifiedLineDetails = angular.copy(self.lineDetails);

AngularJS - Delete check box is not working correctly and only deleting one at a time

I've written out a block of code that allows the user to check or uncheck entities that will be added or removed via web services. My add function seems to be working correctly and provides the ability to add multiple entities. However, my delete function isn't working the same. It doesn't delete each time, and can only delete one at a time. I'm struggling since the code is effectively the same as the add, so I don't know if the issue is AngularJS related or perhaps my web service isn't working correctly.
Edit: I've actually noticed that the for loop goes through it all but doesn't select the correct id, it always starts from the first one.
var toDeleteService = [];
for (var i = 0; i < $scope.siteServices.length; i++) {
if ($scope.siteServices[i].chosen != $scope.siteServices[i].origChosen) {
if ($scope.siteServices[i].chosen == true) {
toAddService.push(i);
}
else {
toDeleteService.push(i);
}
}
}
if (toDeleteService.length > 0) {
var deleteRequest = {};
deleteRequest.services = [];
for (var i = 0; i < toDeleteService.length; i++) {
var parentServiceName = $scope.siteServices[i].parentServiceName;
var j = 0;
for (; j < deleteRequest.services.length; j++) {
if (deleteRequest.services[j].parentServiceName == parentServiceName) {
break;
}
}
if (j == deleteRequest.services.length) {
deleteRequest.services[j] = {};
deleteRequest.services[j].parentServiceName = parentServiceName;
deleteRequest.services[j].subservices = [];
}
var service = {};
service.serviceId = $scope.siteServices[i].serviceId;
deleteRequest.services[j].subservices.push(service);
}
var deleteUrl = "api/sites/" + $scope.targetEntity.siteId + "/services/" + service.serviceId;
$http.delete(deleteUrl)
.then(function (response) {
});
}
As I understood it you are trying to remove siteServices based by numbers stored in var toDeleteServices = [] so you need to access those numbers by its index. but in service.serviceId = $scope.siteServices[i].serviceId; you are using i instead.
service.serviceId = $scope.siteServices[toDeleteServices[i]].serviceId; as you need actual number of the service to delete.
If I understood your code correctly.

AngularJS mysql filter multiple element

Hi this is my hotel project. But I'm having a problem with a filter.
I want to filter the data in the amenities column.
This is: my fiddle
It works if you select a single checkbox but it does not work if you select multiple checkboxes.
I suspect the problem arises from indexof instead of what I can use. What method should I follow?
How to change this line: indexOf(x);
This is my bad code:
//PROBLEM FILTER HERE
$scope.am_en = function()
{
//get input value
x = $(".hosting_amenities input:checkbox:checked").map(function(){return $(this).val();}).get();
//filter
$scope.ot_Filter = function (location) {
return location.amenities.indexOf(x) !== -1;
};
}
The problem is indeed caused by the function $scope.am_en, in the declaration of the inner function $scope.ot_Filter
When you select multiple checkboxes, your x variable is an array of objects, so you should do a loop and can create a variable to check whether the element should be shown or not. You can do it as follows:
$scope.ot_Filter = function (location) {
var shouldBeShown = false;
for (var i = 0; i < x.length; i++) {
if (location.amenities.indexOf(x[i]) !== -1) {
shouldBeShown = true;
break;
}
}
return shouldBeShown;
};
I modified your jsfiddle, so that you can see this solution working properly.

Build a list if condition is met in one of several ranges on other tabs

I'm trying to write a script that builds a list for each subject in a row based on whether or not that subject appears within a specific year range within each tab.
Here is a sample version of my data for reference: https://docs.google.com/spreadsheets/d/1fRhsIAeQd2qDIWILhvhnoTr1Po009RljdjrL9TYwncI/edit#gid=0.
I manually filled in some of the rows column B on the "History" tab, but this is what I want the script to produce (the cells highlighted red).
My best idea so far is to create an object for all of the names and use a for loop to go through each name... then to create separate objects for each role and year, and loop through those with a conditional check to search for the name. If the name appears in that year range, perhaps I can push some text to a new object?
I started writing a script for this but quickly realized it's going to be really painful and inefficient. Any ideas for how I can do this more efficiently? My data goes back several years for hundreds of people so manual updating just isn't an option anymore!
Thanks!!
function buildHistory() {
var ss = SpreadsheetApp.getActive();
var historySheet = ss.getSheetByName("History");
var names = historySheet.getRange(2, 1, historySheet.getLastRow(), 1).getValues();
var pastMems = ss.getSheetByName("Past Members");
var mems2015 = pastMems.getRange(3, 2, pastMems.getLastRow(), 1).getValues();
var mems2014 = pastMems.getRange(3, 5, pastMems.getLastRow(), 1).getValues();
for (var i = 0; i < names.length; i++) {
var name = names[i];
Logger.log(name);
for (var j = 0; j < mems2015.length; j++) {
if (mems2015[j] == name) {
Logger.log("Mem in 2015");
} else if (mems2014[j] == name) {
Logger.log("Mem in 2014");
}
}
}
}
This is the way I would structure the code. This example is incomplete. I did not try to run it. It's meant to show a basic strategy of how the program would flow, and how the data would be processed. Again, the code is incomplete. The code does have a way to dynamically determine the start column for each year in a sheet. It shows how to associate a name, with that person's history.
var masterObject = {};
var ss = SpreadsheetApp.getActiveSpreadsheet();
function masterFunction() {
initialPopulationOfMasterObject();
processPastVolunteersSheet();
processPastSponsersSheet();
addDataToHistory();
};
function initialPopulationOfMasterObject() {
var historySheet = ss.getSheetByName("History");
var names = historySheet.getRange(2, 1, historySheet.getLastRow(), 1).getValues();
var i=0;
for (i=0;i<names.length;i+=1) {
masterObject.thisPerson = names[i];
masterObject.theirHistory = []; //array for list of this person's history
};
};
function processPastVolunteersSheet() {
var volunteersSheet = ss.getSheetByName("Past Volunteers");
var numberOfYears = 3;
var yrs = 0, thisYrsData=[], startColumn;
var j=0, thisName="", thisYr="";
for (yrs=0;yrs<numberOfYears;yrs+=1) {
if (yrs=0) {
startColumn = 1;
thisYr = volunteersSheet.getRange(1, startColumn, 1,1).getValue();
} else {
startColumn = yrs*3;
thisYr = volunteersSheet.getRange(1, startColumn, 1,1).getValue();
};
thisYrsData=volunteersSheet.getRange(2, startColumn, volunteersSheet.getLastRow(),2).getValues();
for (j=0;j<thisYrsData;j+=1) {
masterObject[thisName].push("Volunteer (" + thisYr);
};
};
};

Unable to remove the elements still the array get cleared

I am fetching the data from the server each 10 sec, in this, i am getting 3 type of the data,
After the timeout call, i am removing the existing data, i can witness the console show that the array clears, but the elements still keep append upon.
how can i clear both elements in the DOM and unbind as well..
my close function is keep called, but the elements not remove from DOM.
my single view :
singleton.view = Backbone.View.extend({
tagName :'article',
template0 : function(value){
var label = value === 0 ? "projectName" : value === 1 ? "assignedTo" :"projectName";
return _.template("<a href='#'><%= "+label+" %></a>");
},
template1 : _.template($('#boardTemplate').html()),
initialize :function(prams){
this.template = this['template'+0](prams.subTempNo);
},
close:function(){
console.log('clean up') // i am getting consoled
this.unbind();// i am unbinding
this.remove();// i am removing
},
render:function(){
var temp = this.template;
this.$el.html(temp(this.model.toJSON()));
return this;
}
});
return singleton.view;
in the views :
listViewAppender:function(item,i){
var listElement = new singleton.view({model:item,tempNo:0,subTempNo:i,tagName:'li'});
listElement.close(); // whenever i call the new instance i am removing old stuff..
this.$el.find('.'+this.classItems[i]).append(listElement.render().el);
},
How can i fix this issue.. any correct approach pelase..
Ok just a quick rework.....you're going to have to test it out. Comment with what happens and I'll correct the code below.
Can you try
listViewSet:function(key,i){
var l = this.listCatch.length;
if(l > 0){
for (var i = 0; i < l; i++) {
console.log(this.listCatch[i]);
this.listCatch[i].remove();
}
}
this.listCatch = [];
_.each(this.listCollection.models, function(model){
that.listViewAppender(model,i); //setting agian.
});
},
listViewAppender:function(item,i){
var listElement = new singleton.view({model:item,tempNo:0,subTempNo:i,tagName:'li'});
console.log(listElement);
this.$el.find('.'+this.classItems[i]).append(listElement.render().el);
this.listCatch[i] = listElement;
},
I gone through across my functions, i find the issue in the line of this.listCatch[i] = listElement; wrongly declared.
Later i declared the array by manually, it's works fine. in my initialize i introduced 3 arrays, what i required now it works fine.
this.listCatch = [];
for(var i=0;i<this.listItems.length; i+=1){
this.listCatch[i] = [];
}
So before pushing the model to array, now the array introduced solved the issue.

Resources