why does this infinite loop occures? - javascript

when trying to get items from local storage that are named
useJSON1, useJSON2 and so on.
i get an infinite loop.
var test = 0;
function loadTasks() {
let i = 1
let taskObject = JSON.parse(localStorage.getItem('useJSON' + i));
while (test < i)
if (taskObject) {
// do somthing;
i++;
} else {
test = i;
}
}

Have you checked your syntax, and brackets?
Should it look more like this?
var test = 0;
function loadTasks() {
var i = 1;
var taskObject = JSON.parse(localStorage.getItem('useJSON' + i));
while (test < i){
if (taskObject) {
`do somthing`;
i++;
} else {
test = i;
}
}
}

Related

How to repeat a function without effecting repeating the token

How do I modify the repeat loop function without it repeating the token variable in the function rowcount()?
function rowcount()
{
var token = getAccessToken();
var module = "sHistory";
var rows = 0;
var go = true;
var i = 1;
var data;
while (go) {
data = getRecordsByPage(i,200,token,module);
if (Number(data.info.count) < 200) {
go = false;
};
if ((i%10) == 0) {
go = false;
}
rows = Number(rows) + Number(data.info.count);
i++;
Logger.log(rows)
}
return rows
}
function repeatloop()
{
let counter = 0;
for(var i = 1; i <= 93; i++)
{
{
Utilities.sleep(10000);
Logger.log(i);
counter += rowcount();
Logger.log(counter);
}
}
return rowcount().rows;
}
What I am also trying to do is let the count continue because right now it goes in an increment of 2000, but I need it to continue like 200...400..600..800...1000...1200...1400...1600...1800...2000...2200. and it goes on until the loop stops.
You can make the token a global variable like this:
var token;
function rowcount()
{
var module = "sHistory";
var rows = 0;
var go = true;
var i = 1;
var data;
while (go) {
data = getRecordsByPage(i,200,token,module);
if (Number(data.info.count) < 200) {
go = false;
};
if ((i%10) == 0) {
go = false;
}
rows = Number(rows) + Number(data.info.count);
i++;
Logger.log(rows)
}
return rows
}
function repeatloop()
{
let counter = 0;
token = getAccessToken();
for(var i = 1; i <= 93; i++)
{
{
Utilities.sleep(10000);
Logger.log(i);
counter += rowcount();
Logger.log(counter);
}
}
return rowcount().rows;
}
Or did I understand you wrong?
I would pass the token as an optional parameter, insted to use GLOBAL variable:
function rowcount(_token = null)
{
let token;
if (_token) {token = _token;}
else {token = getAccessToken();}
var module = "sHistory";
var rows = 0;
var go = true;
var i = 1;
var data;
while (go) {
data = getRecordsByPage(i,200,token,module);
if (Number(data.info.count) < 200) {
go = false;
};
if ((i%10) == 0) {
go = false;
}
rows = Number(rows) + Number(data.info.count);
i++;
Logger.log(rows)
}
return rows
}
function repeatloop()
{
let token = getAccessToken();
let counter = 0;
for(var i = 1; i <= 93; i++)
{
{
Utilities.sleep(10000);
Logger.log(i);
counter += rowcount(token);
Logger.log(counter);
}
}
return rowcount(token).rows;
}

Map range to single value Javascript

I'm looking for any better way to implement the following in Javascript or in JSON format.
function getGroupId(val) {
let groupId = 0;
if (val < 5) {
groupId = 0;
} else if (val < 10) {
groupId = 1;
} else if (val < 25) {
groupId = 2;
} else if (val < 36) {
groupId = 3;
....
} else {
groupId = 8;
}
return groupId;
}
You mean something like this
const mapping = [5,10,25,36]
function getGroupId(val) {
let groupId = 8;
for (let i=0; i<mapping.length;i++) { // using simple for to be able to break
if (val<mapping[i]) { groupId = i; break }
}
return groupId;
}
console.log(getGroupId(1),getGroupId(11),getGroupId(50))

JavaScript Observable Property

In trying to learn more about JavaScript patterns I created the following 2 "Meters" based on an example I found. Is Meter1 better because it uses the Observable Property (or so I think) pattern? Would this pattern be used real-world or not really because of all the frameworks available?
//Meter1 - Observable Property Pattern
var Meter1 = function (count) {
var countChanging = [],
countChanged = [];
this.count = function (val) {
if (val !== undefined && val !== count) {
for (var i = 0; i < countChanging.length; i++) {
if (!countChanging[i](this, val)) {
return count;
}
}
count = val;
for (var i = 0; i < countChanged.length; i++) {
countChanged[i](this);
}
}
return count;
};
this.increment = function () {
return count = count + 1;
}
this.onCountChanging = function (callback) {
countChanging.push(callback);
};
this.onCountChanged = function (callback) {
countChanged.push(callback);
};
};
var meter = new Meter1(5);
var btnClick = document.getElementById('btnClick');
btnClick.addEventListener('click', function () {
meter.count(meter.count() + 1);
}, false);
meter.onCountChanging(function (b, count) {
if (count > 10) {
document.getElementById('numClicks').innerHTML = "Enough already!!!!!";
return false;
}
return true;
});
meter.onCountChanged(function () {
document.getElementById('numClicks').innerHTML = "Test " + meter.count();
});
//Meter2 - Does the same thing, is Observable Property pattern better?
var Meter2 = function (count) {
this.count = 0;
};
var meter2 = new Meter2(5);
var btnClick2 = document.getElementById('btnClick2');
btnClick2.addEventListener('click', function () {
meter2.count = meter2.count + 1;
if (meter2.count > 10) {
document.getElementById('numClicks2').innerHTML = "Enough already!!!!!";
} else {
document.getElementById('numClicks2').innerHTML = "Test " + meter2.count;
}
}, false);
<body>
<div id="numClicks">Test</div>
<div id="numClicks2">Test</div>
<button id="btnClick">Click - Meter</button>
<button id="btnClick2">Click - Meter 2</button>
</body>
</html>
<script src="../js/generalTesting.js"></script>

JavaScript continue label scope

Map.prototype.updateMap = function (vehicles) {
nextVehicle:
for (var i = 0; i < vehicles.length; i++) {
for (var j = 0; j < this.oldVehicles.length; j++) {
var vehicle = vehicles[i];
var oldVehicle = this.oldVehicles[j];
if (vehicle.registration == oldVehicle.registration) {
oldVehicle.getPosition(function(latLng) {
if (vehicle.latitude != oldVehicle.lat) {
var newPos = new plugin.google.maps.LatLng(vehicle.latitude, vehicle.longitude);
oldVehicle.setPosition(newPos);
}
continue nextVehicle;
});
}
}
}
};
The code above does not work. I have a feeling this is to do with scope, I can't reach the nextVehicle label from inside the oldVehicle.getPosition method. How can I get around this?
Separate the matching logic from the update logic.
Map.prototype.updateMap = function (vehicles) {
// Only need to look up array lengths once
var vehiclesLength = vehicles.length,
oldVehiclesLength = this.oldVehicles.length;
for (var i = 0; i < vehiclesLength; i++) {
var vehicle = vehicles[i];
var oldVehicle = null;
// Find oldVehicle
for (var j = 0; j < oldVehiclesLength; j++) {
if (vehicle.registration == oldVehicle[j].registration) {
oldVehicle = oldVehicles[j];
break;
}
}
// Check for update if found
if (oldVehicle){
// Create closure for async callbacks
(function(oldV, lat,lng){
oldV.getPosition(function(latLng) {
if (lat != oldV.lat) {
var newPos = new plugin.google.maps.LatLng(lat,lng);
oldV.setPosition(newPos);
}
});
})(oldVehicle, vehicle.latitude, vehicle.longitude);
}
}
};
Just move the continue nextVehicle; line from inside the callback to immediately following the call to oldVehicle.getPosition(...):
Map.prototype.updateMap = function (vehicles) {
nextVehicle:
for (var i = 0; i < vehicles.length; i++) {
for (var j = 0; j < this.oldVehicles.length; j++) {
var vehicle = vehicles[i];
var oldVehicle = this.oldVehicles[j];
if (vehicle.registration == oldVehicle.registration) {
oldVehicle.getPosition(function(latLng) {
if (vehicle.latitude != oldVehicle.lat) {
var newPos = new plugin.google.maps.LatLng(vehicle.latitude, vehicle.longitude);
oldVehicle.setPosition(newPos);
}
});
continue nextVehicle;
}
}
}
};
This assumes the call to getPosition is a synchronous operation.
Edit:
Now if getPosition is asynchronous, you will need to use an asynchronous loop:
Something along this line might do the trick:
Map.prototype.updateMap = function (vehicles) {
var i = 0, j = -1, self = this;
var updatePosition = function() {
j++;
if (j == self.oldVehicles.length) {
j = 0;
i++;
}
if (i === vehicles.length) {
return; // We're done
}
var vehicle = vehicles[i];
var oldVehicle = self.oldVehicles[j];
if (vehicle.registration !== oldVehicle.registration) {
updatePosition();
}
else {
oldVehicle.getPosition(function(latLng) {
if (vehicle.latitude != oldVehicle.lat) {
var newPos = new plugin.google.maps.LatLng(vehicle.latitude, vehicle.longitude);
oldVehicle.setPosition(newPos);
updatePosition();
}
});
}
};
updatePosition();
};

Change one letter of innerHTML

I have a for loop like this:
for(var i = 0; i < woord.length; i++) {
if(woord[i] === letter) {
goed = true;
woordContainer.innerHTML[i] = woord[i];
}
}
But the text in the woordContainer doesn't change on the page. I tried logging woord[i] to the console and it show the correct letter.
EDIT:
Let me share the complete code, so you can understand it better:
(it is a hangman game)
var store,
woord,
wrapper,
woordContainer,
letterInput,
gokButton,
pogingen,
pogingenText;
window.onload = function() {
store = new Persist.Store("galgje");
woord = store.get("woord");
pogingen = 10;
wrapper = document.getElementById("wrapper");
woordContainer = document.getElementById("woordContainer");
letterInput = document.getElementById("letterInput");
gokButton = document.getElementById("gokButton");
pogingenText = document.getElementById("pogingenText");
if (!woord) {
document.location.href = "./index.html";
}
for (var i = 0; i < woord.length; i++) {
woordContainer.innerHTML += ".";
}
wrapper.appendChild(woordContainer);
gokButton.onclick = function() {
var letter = letterInput.value.toLowerCase();
var goed = false;
if(letter) {
for(var i = 0; i < woord.length; i++) {
if(woord[i] === letter) {
goed = true;
woordContainer.innerHTML = woord[i];
}
}
if(!goed) {
pogingen--;
if(pogingen === 0) {
document.location.href = "./af.html";
}
pogingenText.innerHTML = "Pogingen: " + pogingen;
}
letterInput.value = "";
}
return false;
}
}
If you want to replace the character int woordContainer.innerHTML at index i, with the one in woord[i], you can do it like this:
if(woord[i] === letter) {
goed = true;
var temp = woordContainer.innerHTML
woordContainer.innerHTML = temp.substr(0, i) + woord[i] + temp.substr(i + woord[i].length);
}

Categories