Angular 2 loop through a list with some delay - arrays

How do I loop through an array with some delay with Angular 2 and TypeScript?
I have an array,
students: Array<any> = [
{
name: "Alan"
},
{
name: "Jake"
},
{
name: "Harry"
},
{
name: "Susan"
},
{
name: "Sarah"
},
{
name: "Esther"
}
];
I want to loop through the list and display the names with a 2000ms delay.
<div *ngFor="let student of students">
{{student.name}}
</div>
doesn't work with a delay but is looping all at once.

Just use setTimeout. For example (* not tested):
students: Array<any> = [ ];
populateArrayWithDelay():void{
let people = [
{
name: "Alan"
},
{
name: "Jake"
},
{
name: "Harry"
},
{
name: "Susan"
},
{
name: "Sarah"
},
{
name: "Esther"
}
];
for(let i = 0; i < people.length; i++){
let student = people[i];
setTimeout(() => {
this.students.push(student);
}, 2000*(i+1));
}
}

Plunker example
export class App {
name:string;
students: Array<any> = [
{
name: "Alan"
},
{
name: "Jake"
},
{
name: "Harry"
},
{
name: "Susan"
},
{
name: "Sarah"
},
{
name: "Esther"
}
];
constructor() {
var timer = 0;
this.$students = Observable.from([[], ...this.students])
.mergeMap(x => Observable.timer(timer++ * 1000).map(y => x))
.scan((acc, curr) => {acc.push(curr); return acc;});
}
}

Related

Remove object in array

I have a array object and a array.
const arr1=[
{ name: "viet" },
{ name: "hai" },
{ name: "han" }
]
const arr2= ["viet", "hai"];
How can i compare and set arr like:
arr = [{name: "han"}]
Try this code :D
const arr1=[
{ name: "viet" },
{ name: "hai" },
{ name: "han" }
]
const arr2= ["viet", "hai"];
const result = arr1.filter(item => !arr2.includes(item.name))
console.log(result) // [{name: "han"}]
const arr1=[
{ name: "viet" },
{ name: "hai" },
{ name: "han" }
]
const arr2= ["viet", "hai"];
let res = arr1.filter(function (n) {
return !this.has(n.name);
}, new Set(arr2));
console.log(res);

unable to update setState

Tried to update a state. Somehow the setState isn't working..
this is the function and state:
state = {
security: {
0: { id: "54321", name: "test1"}
1: { id: "98765", name: "test2"}
}
}
removeSecInState = (security) => () => {
var temp = Object.assign({}, this.state.security)
var temp1 = Object.values(temp)
var index = temp1.findIndex(id => id.id === security.id) //getIndex
delete temp[0]
this.setState({security: temp},() => {
console.log(temp, "inside");
console.log(this.state.security, "inside1")
})
}
console.log(temp, "inside") =
security: {
1: { id: "98765", name: "test2"}
}
console.log(this.state.security, "inside1") =
security: {
0: { id: "54321", name: "test1"}
1: { id: "98765", name: "test2"}
}
somehow, state is not updated to be the same with temp, always goes back to the previous state
It seems that you have not included the this keyword before state, also you should
Try this
this.state = {
security: {
0: { id: "54321", name: "test1"}
1: { id: "98765", name: "test2"}
}
}
Also you should try to refactor the code a little bit
Maybe like this
this.state = {
security: [
{ id: "54321", name: "test1"},
{ id: "98765", name: "test2"}
]
}
removeSecInState(sec) {
this.setState({
security: this.state.security.filter(item => item.id !== sec.id)
})
}

At the same time, two identical elements can not be selected in dropDownList

Hello i am have two kendo ui drodDownList:
kendo-drop-down-list(
ng-model = 'vm.firstList'
k-data-source='vm.filterData'
k-data-text-field='"title"'
k-data-value-field='"name"'
k-value-primitive='true'
k-filter='"contains"'
k-on-change='vm.onChange($event)'
)
and
kendo-drop-down-list(
ng-model = 'vm.secondList'
k-data-source='vm.filterData'
k-data-text-field='"title"'
k-data-value-field='"name"'
k-value-primitive='true'
k-filter='"contains"'
k-on-change='vm.onChange($event)'
)
it is data source:
this.filterData = [
{ name: 'Brown', title: 'Soier' },
{ name: 'Maks', title: 'Inkl' },
{ name: 'Lint', title: 'Baks' },
{ name: 'Hover', title: 'Niyou' }
]
they have same data source, and i am want when choosing item in first dd then remove this item from other dd (and likewise for the second). At the same time, two identical elements can not be selected.
my solution:
in first dd add:
k-on-change='vm.onFirstSelect(kendoEvent)'
k-data-source='vm.firstFilterElements'
for second dd:
k-on-change='vm.onSecondSelect(kendoEvent)'
k-data-source='vm.secondFilterElements'
in controller add:
this.filterElements = [
{ name: 'Brown', title: 'Soier' },
{ name: 'Maks', title: 'Inkl' },
{ name: 'Lint', title: 'Baks' },
{ name: 'Hover', title: 'Niyou' }
]
this.firstFilterElements = this.filterElements;
this.secondFilterElements = this.filterElements;
onFirstSelect(e) {
this.secondFilterElements = this.filterByItem(e);
}
onSecondSelect(e) {
this.firstFilterElements = this.filterByItem(e);
}
filterByItem (e) {
return this.filterElements.filter(function (el) {
return el.name !== e.sender.dataItem(e.item)
[e.sender.options.dataValueField];
});
}
if someone can optimize it i will be glad)

Angular 2 pipe to filter grouped arrays

I have a group of arrays on my Angular2 app that I use to build a grouped list with *ngFor in my view:
[
{
category: 1,
items: [{ id: 1, name: "helloworld1" }, { id: 2, name: "helloworld2" }]
},
{
category: 2,
items: [{ id: 3, name: "helloworld3" }, { id: 4 }]
},
{
category: 3,
items:[{ id: 5 }, { id: 6 }]
}
]
I also have a boolean that when it's true should filter only the items that have the name property. If a group does not have any item that matches this condition it should not pass. So the result would be the following if the boolean is true:
[
{
category: 1,
items: [{ id: 1, name: "helloworld1" }, { id: 2, name: "helloworld2" }]
},
{
category: 2,
items: [{ id: 3, name: "helloworld3" }]
}
]
How can I implement a pipe to achieve this kind of result?
http://plnkr.co/edit/je2RioK9pfKxiZg7ljVg?p=preview
#Pipe({name: 'filterName'})
export class FilterNamePipe implements PipeTransform {
transform(items: any[], checkName: boolean): number {
if(items === null) return [];
let ret = [];
items.forEach(function (item) {
let ret1 = item.items.filter(function (e) {
return !checkName || (checkName && (e.name !== undefined));
});
if(ret1.length > 0) {
item.items = ret1;
ret.push(item);
}
});
return ret;
}
}

How to remove items in one array if other has it?

How to remove item from array B if array A has it. I want to iterate through by ID.
array A: it has all the items
[{
"Name":"John",
"Id":1
},
{
"Name":"Peter",
"Id":2
},
{
"Name":"Phillip",
"Id":3
},
{
"Name":"Abby",
"Id":4
},
{
"Name":"Don",
"Id":5
}]
array B: has just the selected items
[{
"Name":"John",
"Id":1
},
{
"Name":"Abby",
"Id":4
}]
I want to remove from array A John and Abby by Id, because they are in array b.
for (var i = 0; i < a.length; i++) {
if (b[i].Id == ta[i].Id) {
for (var j = 0; j < b[j]; j++) {
a.splice(i, 1);
}
}
}
this is not working as I thought
You could first get all id's of person objects in b:
let idsInB: number[] = b.map(person => person.Id); // > [1, 4]
This array of id's can be used to filter a, and then assign the result back to a. Let's contain that in a function cleanA:
function cleanA(): void {
let idsInB: number[] = b.map(person => person.Id);
a = a.filter((person) => -1 === idsInB.indexOf(person.Id));
}
All you need to do now is call cleanA whenever the contents of b changes.
Full working example:
interface Person {
Id: number;
Name: string;
}
let a: Person[] = [
{ Id: 1, Name: "John" },
{ Id: 2, Name: "Peter" },
{ Id: 3, Name: "Phillip" },
{ Id: 4, Name: "Abby" },
{ Id: 5, Name: "Don" },
];
let b: Person[] = [
{ Id: 1, Name: "John" },
{ Id: 4, Name: "Abby" },
];
function cleanA(): void {
let idsInB: number[] = b.map(person => person.Id);
a = a.filter((person) => -1 === idsInB.indexOf(person.Id));
}
presentArray(a, 'A before clean');
cleanA();
presentArray(a, 'A after clean');
// -------------------------------------------------------
// Displaying purposes only:
// -------------------------------------------------------
function presentArray(arr, msg) {
document.body.innerHTML += `<br><b>${msg}:</b><br>[<br>`
+ arr.map(person => ` { Id: ${person.Id}, Name: ${person.Name} },<br>`)
.join('')
+ ' ]<br><br>';
}

Resources