Reputation: 1497
This function should push certain numbers to an array that I'm gonna display on view.
@Component({
selector: 'app-task2',
templateUrl: './task2.component.html',
styleUrls: ['./task2.component.css']
})
export class Task2Component implements OnInit {
array: [number];
input;
constructor() {}
ngOnInit() {}
}
Everything works just fine, but as soon as I include "this.array.push(i)" it keeps refreshing my page on submit (call of this function on submit). I delete it, everything works just fine, it iterates the right way, finds numbers and everything that it should do. Even if i make array inside of function and push to it, it works fine, but when i use it as an class "atribute" and use "this" as reference it doesnt work (starts refreshing).
onSubmit() {
for(var i=2; i<=this.input; i++) {
if(this.input % i == 0) {
this.input /= i;
this.array.push(i);
return this.onSubmit(); //does same even without this
}
}
this.input = "";
}
Upvotes: 1
Views: 2017
Reputation: 149
I know it looks weird, but the trick is very simple.
Just initialize the array and the reloading problem goes away.
array: number[] = [];
I just faced this problem with my code and this trick solved the issue.
Upvotes: 1
Reputation: 9421
Only the javascript is currently displayed in your question, so I am taking a guess at what the template contains. I am assuming your code is designed to factorise a number?
I suspect the cause for the multiple refreshes is that your template is programmed to display this.array
whenever it updates. If you are typing in a number with many factors, you will see many refreshes.
Am I right in saying that when you put in a prime number, you get just a single refresh, i.e. correct behaviour? If so then you could fix it by doing all the push
ing on a separate variable, and then copying that separate variable into this.array
. For example:
onSubmit() {
let nextArray = [];
for(var i=2; i<=this.input; i++) {
if(this.input % i == 0) {
this.input /= i;
nextArray.push(i);
// Remove this line: return this.onSubmit();
}
}
this.array = nextArray;
this.input = "";
}
When factorising N, once you have looked as far as (and including) sqrt(N), there is no need to look at the other numbers between sqrt(N) and N: they can't be factors. So you can modify the first line of your loop. Squaring is quicker than square-rooting, so you can test for i*i<=this.input
for speed instead of i<=Math.sqrt(this.input)
. You just have to remember to push
the final value of this.input if it is not 1, as this will be the largest factor.
onSubmit() {
let nextArray = [];
for(var i=2; i*i<=this.input; i++) {
if(this.input % i == 0) {
this.input /= i;
nextArray.push(i);
}
}
if (this.input !==1){
nextArray.push(this.input);
}
this.array = nextArray;
this.input = "";
}
I suspect your current code would not correctly factorise a number which had the same factor present multiple times. For example, it tests only once for whether a number is divisible by 5. So if this.input
was 250, which is 2*5*5*5, it would output 2, 5, 25.
To counteract this, you could do the incrementing of i
to happen only if you have not found a factor. So that when you find a factor, the next cycle of the for
will test the same factor, and subsequent cycles will keep testing the same factor, until it is no longer a factor.
onSubmit() {
let nextArray = [];
for(var i=2; i<=this.input;) {
if(this.input % i == 0) {
this.input /= i;
nextArray.push(i);
} else {
i++;
}
}
this.array = nextArray;
this.input = "";
}
Upvotes: 0