I made a loop in angularjs and i want to get a distinct values from this loop then push it to an array.
What I got instead, are repetitive values.
The $scope.Empassignedvacations returns multiple data from datatable from db. one column from it is vac which displays multiple vacations keys in the db.
What i want to do is to take these keys and distinct them and push them to another $scope array. its name is $scope.checkedvacs. but i got 2,2,2,2,20,20,20,20
Assignments.getvacations().then(function (response) {
$scope.vacations = (response.data);
Assignments.GetEmpassignedvacations($scope.SelectedEmp1.staffkey)
.then(function (response) {
$scope.Empassignedvacations = (response.data)
$scope.checkedvacs.push( $scope.Empassignedvacations.vac );
angular.forEach($scope.Empassignedvacations, function (e) {
angular.forEach($scope.AlternateDirector, function (a) {
if (e.Staff_Key == a.Staff_Key) {
$scope.AlternateD = e.AlternateD;
}
})
angular.forEach($scope.status, function (s) {
if (e.status == s.stsid) {
$scope.sts = s.stsid;
}
})
})
Thanks in advance
It happens because you play with the same value $scope.Empassignedvacations.
You push it to the array and after - change it. This is a reason why you get 2,2,2,2,20,20,20,20
So you can fix it by pushing the copy of the value, like:
$scope.checkedvacs.push( angular.copy($scope.Empassignedvacations.vac));
First declare $scope.checkedvacs=[] & $scope.keys=[] in globally for standard code practice then try bellow code
angular.forEach($scope.Empassignedvacations.vac, function(item) {
// we check to see whether our object exists
$scope.keys = item[keyname];
// if it's not already part of our keys array
if ($scope.keys.indexOf(key) === -1) {
// push this item to our final output array
$scope.checkedvacs.push(item);
}
});
remove bellow code and replace your code with first code sample..
$scope.checkedvacs.push( $scope.Empassignedvacations.vac );
angular.forEach($scope.Empassignedvacations, function (e) {
angular.forEach($scope.AlternateDirector, function (a) {
if (e.Staff_Key == a.Staff_Key) {
$scope.AlternateD = e.AlternateD;
}
})
angular.forEach($scope.status, function (s) {
if (e.status == s.stsid) {
$scope.sts = s.stsid;
}
})
You can also follow bellow link that may be helpful for you
https://tutorialedge.net/javascript/angularjs/removing-duplicates-from-ng-repeat/
Related
I'm working on a simple to-do list with vanilla js. I've managed to add the input to local storage, but have not been able to add the style changes(check strike through) to local storage, nor can I figure out how to remove one item at a time from storage. I have been able to clear all, just unable to remove each item separately. Below is my code, any advice is greatly appreciated.
//local storage setup
let saved = window.localStorage.getItem(input.value);
if (saved) {
list.innerHTML = saved;
}
//handle input submit
function handleSubmitForm(e) {
e.preventDefault();
let input = document.querySelector('input');
if (input.value != '') {
addTodo(input.value);
}
input.value = '';
window.localStorage.setItem(input.value, list.innerHTML);
}
//check off todo
function checkTodo(e) {
let item = e.target.parentNode;
if (item.style.textDecoration == 'line-through') {
item.style.textDecoration = 'none';
} else {
item.style.textDecoration = 'line-through';
}
window.localStorage.setItem(item);
}
//delete todo
function deleteTodo(e) {
let item = e.target.parentNode;
item.addEventListener('transitionend', function () {
item.remove();
});
item.classList.add('todo-list-item-fall');
window.localStorage.removeItem(item);
}
JavaScript Storage is a key-value pair. Just use a string-based key so you can remove, edit or read it easily.
// Set todo item
localStorage.setItem("todo1", "Stand-up meeting 9.15am");
// Read todo item
localStorage.getItem("todo1");
// Delete todo item
localStorage.removeItem("todo1");
It's better if you can save it as a JSON string because you can mark it as completed without delete, so you can find completed tasks too.
// Saving todo item as a JSON string
localStorage.setItem("todo1", JSON.stringify({ text: "Stand-up meeting 9.15am", completed: false }));
// Read it
const todo = JSON.parse(localStorage.getItem("todo1"));
// You can read the text
console.log(todo.text);
// Also you can mark it as completed and save it back
todo.completed = true;
localStorage.setItem("todo1", JSON.stringify(todo));
Storing object in localStorage is a tricky job.
Everything you store in the local or session storage is of type string
you can create an object like
item = {
value : ANY_VALUE
}
and save it in your localStorage using JSON.stringify
localStorage.setItem(`item`,JSON.stringify(item))
now when you want to update the item just update the object and again set using the ablove syntax
To access the saved item from the local storage use JSON.parse
yourItemObject = JSON.parse(localStorage.getItem())```
You can access values now using yourItemObject .value
It appears you're passing the whole HTML element (it passed as an object) inside the removeItem function. you need to pass the key instead.
try localStorage.removeItem(item.innerText);
If you are working with lists in localStorage. I would use something like this basic example:
function addTodo(key, item){
var list = getTodo(key);
list.push(item);
localStorage.setItem(key, JSON.stringify(list) );
}
function getTodo(key){
try{
var rawList = localStorage.getItem(key);
return JSON.parse(rawList) || [];
}
catch(e){
return [];
}
}
function removeTodo(key, id){
var list = getTodo(key);
var newlist = list.filter( function(item){
return item.id != id;
});
localStorage.setItem(key, JSON.stringify(newlist) )
}
function emptyTodo(key){
localStorage.removeItem(key);
}
addTodo('list', {
id: 1,
text: 'do shopping'
});
addTodo('list', {
id: 2,
text: 'study'
});
console.log( getTodo('list') );
removeTodo('list', 1);
console.log( getTodo('list') )
emptyTodo('list');
I've got two pages I'm working on, and both return an array of objects. When I use the following code, the new results work:
this.adminService.waiversGetAll()
.subscribe((data: Waiver[]) => {
this.waivers = data;
this.waivers.forEach((e) => {
if(e.has_signed === true) {
e.url = `View`
} else {
e.url = `${e.message}`;
}
return e;
});
console.log(this.waivers);
})
}
But when I try to do the same thing with a different array (where I need to update the values of an array nested inside) I don't get updated values:
this.adminService.GetUnsignedWaivers()
.subscribe((data: Player[]) => {
console.log("data",data);
data.forEach(e => {
let record: Object = {};
for(let i = 0; i < e.waivers.length; i++) {
console.log(e.waivers[i].has_signed);
if (e.waivers[i].has_signed === true) {
e.waivers[i].url = e.waivers[i].signatureUrl;
console.log(e.waivers[i].url);
e.waivers[i].message = "View Waiver";
} else {
e.waivers[i].url = e.waivers[i].url;
e.waivers[i].message = e.waivers[i].message;
}
console.log(e.waivers[i].message);
return;
};
return e;
});
this.size = this.players.length;
console.log(this.players);
})
}
When I look at the console.log of e.waivers[i].has_signed, the data is correct, but after that it's not right.
What do I have to do to make this work? I've tried using a for loop inside the foreach, and a bunch of other stuff.
The data supplied to the loop provides info like:
{
buyer: "email#someaddress.edu"
event: "COED A"
field: "Main"
net: null
player: {shirtSize: null, avp_id: 12345678, adult: true, …}
team: null
waivers: [{
email: "someemail#gmail.com",
has_signed: true,
message: "Liability Waiver",
signatureUrl: "https://somelink.pdf",
url: "https://somelink.com/somekeyidentifier"
}
IF the player has signed the waiver, there will be a signatureUrl field and the message should say "View Waiver" instead of the message telling me what type of waiver they will sign. I want the url to be set to signatureUrl if they signed, so I can use it in a table that doesn't like manipulation of data.
A visual of what is returned in my table:
All I get is 1600 records showing the url as though everyone hasn't signed, but when I console.log has_signed in the inner loop, it's showing TRUE for the ones that should show a signatureUrl instead.
Quickly looking at it, you have a return statement within your for loop, which would stop it from running after the first iteration.
First of all drop all the return statements in your code. Next, use map instead of forEach as the former returns you the new manipulated array and the latter is used just for iteration purpose.
Your code within subscribe then becomes:
data.waivers = data.waivers.map((waiver) => {
if (waiver.has_signed) {
// your logic goes here...
waiver.url = waiver.signatureUrl;
waivers.message = "View Waiver";
}
// No else is required as you are just reassigning with same values
});
this.playerDetails = data;
At last bind this modified data in your template.
i have an array in my component and based on the searchString i am filtering the array of items. and it is working fine.
if user removes the characters from the search field i want to show all the records again. but i am unable to show all records again when clearing the items from the search field.
please see below code.
this.filterServ.filterData.subscribe(searchData => {
if (Object.keys(searchData).length != 0) {
console.log('component', searchData);
this.cardData = this.cardData.filter((project) => {
let name = project.Name.toLowerCase();
if (name.includes(searchData.searchString.toLowerCase())) {
return true;
}
});
console.log('filterd data', this.cardData);
}
});
You already mutated the cardData. Therefore, you can't revert it back.
The solution is to create another property, for example you can name it displayData.
Then you can do like:
this.displayData = this.cardData.filter((project) => {
and instead of using cardData on the template, use displayData instead
Declare field filterData and bind this field in the template.
this.filterServ.filterData.subscribe(searchData => {
if (Object.keys(searchData).length != 0) {
console.log('component', searchData);
this.filterData= this.cardData.filter((project) => {
let name = project.Name.toLowerCase();
if (name.includes(searchData.searchString.toLowerCase())) {
return true;
}
});
console.log('filterd data', this.cardData);
}
});
Hope this help!
You should take copy of array data before filtering, and return the original array if input text is empty.
private originalData;
this.originalData = this.cardData.slice();
this.filterServ.filterData.subscribe(searchData => {
if (Object.keys(searchData).length != 0) {
console.log('component', searchData);
this.cardData = this.originalData.filter((project) => {
let name = project.Name.toLowerCase();
if (name.includes(searchData.searchString.toLowerCase()))
{
return true;
}
});
console.log('filterd data', this.cardData);
}
});
So basically, I have a web application that retrieves data from Firebase using rxjs observables.
here's my code,
initializeItems(){
this.travelList$ = this.plsdala.getTravelList()
.snapshotChanges()
.map(
changes => {
return changes.map(c=>({
key: c.payload.key, ...c.payload.val()
})).slice().reverse();//to reverse order
})
this.travelList$.subscribe(res => {
for(let i=0;i<res.length;i++){
this.ListOfitems.push (res[i].toAddress);
}
})
}
this is called from the constructor. problem here is that i cannot check if it is push successfully and if try to print in console , it wont print. why?
the element pushed is needed for filtering. heres is the code for filtter. but when i print the this.ListOfitems in console it is undefined and im wondering unto why? when the elements are initialized first
getItems(ev: any) {
console.log("awdaw");
console.log(this.ListOfitems);
if (this.ListOfitems.length>1){
console.log("otin");
let val = ev.target.value;
if (val && val.trim() != '') {
this.ListOfitems = this.ListOfitems.filter((ListOfitems) => {
return (ListOfitems.toLowerCase().indexOf(val.toLowerCase()) > -1);
})
}
}
}
when you are declaring list of items if you want to push into the array you need to declare it empty first like this:
ListOfitems: string[] = [];
I have a problem with the validation about existing values. I don't know how to compare two values and add the new value only, when it isn't exist in the Database. I've tried with angular.forEach() but it adds the new object always when the compare (what I'm doing with angular.equals()) isn't false and thats wrong. The object have to be only one time in the database.
Here is my create function:
$scope.createItem = function (createItem) {
//here I have to define a query to compare createItem.lname with the table list (array items from the db) in the view.
//That was the code:
angular.forEach(nameslist, function (value) {
if (angular.equals(createItem.lname, value.lname)) {
CrudService.create(createItem).then(
function () {
//success code
$scope.createItem = null;
},
function (err) {
//error code
});
}
}
});
}
Can anyone give me some help.. I don't know how to solve it.
var itemAbsent = namelist.map(function(value){
return value.name;
}).indexOf(createItem.name) < 0;
if (nameAbsent){
CrudService.create(createItem).then(
function () {
//success code
$scope.createItem = null;
},
function (err) {
//error code
});
}
}