Storing my game score in local storage - javascript

I'm pretty new to JS so I'm struggling here. Basically I have a score function in place in my JavaScript and I want to store this locally so it can be retrieved by another page at a later time. I used local storage for my login and register page, but I'm not sure how I can do the same for score.
add_row_of_pipes: function() {
var hole = Math.floor(Math.random()*5)+1;
for (var i = 0; i < 8; i++)
if (i != hole && i != hole +1)
this.add_one_pipe(400, i*60+10);
this.score += 1;
this.label_score.content = this.score;
};
All feedback will be highly appreciated:)

This is how you can store and retrieve values from localStorage:
// Store
localStorage.setItem("score", "100");
// Retrieve
var score = localStorage.getItem("score");

This is a small LocalStorage framework that i've put together.
It covers all of the obvious functionality you would want from localstorage.
function set_LocalStorage(key,value)
{
//localStorage.setItem("name of variable", "value to store");
localStorage.setItem(key, value);
console.log('LocalStorage: ' + key + ' has been set to: ' + value);
}//End set_LocalStorage
function get_LocalStorage(key)
{
return localStorage.getItem(key);
console.log('LocalStorage: ' + key + ' has a value of: ' + value);
}//End get_LocalStorage
function remove_LocalStorage(key)
{
localStorage.removeItem(key);
console.log('LocalStorage: ' + key + ' has been removed');
}//End remove_LocalStorage
function check_LocalStorage_exist(key)
{
var v = get_LocalStorage(key);
var v2 = toInteger(v);
var FeedBack;
if(v2 == 'null' || v2 === 'NaN' || v2 == 'undefined' || v2 == ''){ /*console.log('key '+key+' does NOT exist');*/ FeedBack='NO';}
if(v2!=0){
console.log('key '+key+' exist');
FeedBack='YES';
}
return FeedBack;
}//End check_LocalStorage
function list_All_LocalStorage()
{
for (var i = 0; i < localStorage.length; i++)
{
let item = localStorage.getItem(localStorage.key(i)); //--Will only need to have this on when collecting APP_DATA
console.log('------ LocalStorage: '+localStorage.key(i)+' = '+item);
}
}//End list_All_LocalStorage
function remove_All_LocalStorage()
{
for (var i = 0; i < localStorage.length; i++)
{
let s_key = localStorage.key(i);
remove_LocalStorage(s_key);
}
}//End remove_All_LocalStorage
You're welcome! :)

Related

Integer not being updated properly

I have a fairly long javascript file below, but it's not important to understand the entire file, only the 'totalItemCount' variable and how it is updated. This code uses the Igloo API to recursively count the number of files within a directory (and that count is stored in the totalItemCount var). I have never used recursion with Javascript before, so I may have made a mistake there. For some reason the count increases and then goes down later on in the javascript console, which makes me think I have made a mistake updating that variable somewhere (and it's only updated in a few places but I can't find it)
EDIT: I now have it updating more accurately, but items are over-counted or under-counted by about 10%. I think the last few updates might be where the problem is but i'm not sure. The code below is updated:
new ApiClient({
apimethod: 'objects/7f6d706e-6754-e411-b5b8-d4ae5294c399/children/view',
method: 'get',
queryparams: {
maxcount: 8000,
startindex: 0,
includefuturepublished: true
},
onSuccess: function (responseText)
{
var result = JSON.parse(responseText);
var originalObject = result; //first, top-level object
var totalItemCount = 0; //UPDATED HERE
console.log(result.response);
console.log(result.response.items);
console.log('RESPONSE TITLE: ' + result.response.items[0].title);
console.log("\n\n\n");
totalItemCount += parseInt(result.response.totalCount); //UPDATED HERE
console.log("totalItemCount: " + totalItemCount);
//Check if object has children and add to totalItemCount accordingly FOR EACH object:
function getItemsRecursively(totalItemCount1)
{
for(var i = 0; i < parseInt(totalItemCount); i++) //at this point, totalCount == #objects at this lvl
{
console.log("FOR LOOP TEST: " + i);
var currentObject = result.response.items[i];
console.log("href/dir: " + currentObject.href);
console.log("title: " + currentObject.title);
console.log("numchildren: " + currentObject.numchildren);
if(currentObject.numchildren > 0 && currentObject.numchildren != undefined)
{
console.log("it has children...");
getChildrenItemCount(totalItemCount1, currentObject);
}
console.log("New totalItemCount: " + totalItemCount);
console.log("\n~~~~~ NEXT OBJECT ~~~~~\n");
}
}
function getChildrenItemCount(totalItemCount2, previousObject)
{
//totalItemCount2 = totalItemCount;
var childID = previousObject.id;
console.log("childID: " + childID);
new ApiClient
({
apimethod: 'objects/' + childID + '/children/view',
method: 'get',
queryparams: {
maxcount: 8000,
startindex: 0,
includefuturepublished: true
},
onSuccess: function (responseText)
{
console.log("getChildrenItemCount successful...");
var result = JSON.parse(responseText);
console.log(result);
var currentObject = result.response;
var currentFolderItemCount = currentObject.totalCount;
console.log("currentFolderItemCount: " + currentFolderItemCount);
for(var i = 0; i < parseInt(currentFolderItemCount); i++) //at this point, totalCount == #objects at this lvl
{
console.log("CHILDREN FOR LOOP TEST: " + i);
var currentObject = result.response.items[i];
console.log("href/dir: " + currentObject.href);
console.log("title: " + currentObject.title);
console.log("numchildren: " + currentObject.numchildren);
if(currentObject.numchildren > 0 && currentObject.numchildren != undefined)
{
console.log("it's children has children...");
totalItemCount += parseInt(currentObject.numchildren); //UPDATED HERE
totalItemCount2 = totalItemCount; //UPDATED HERE
console.log("totalItemCount after one sub-child total: " + totalItemCount);
getChildrenItemCount(totalItemCount2, currentObject);
}
console.log("New totalItemCount after ENTIRE getChildrenItemCount: " + totalItemCount);
console.log("\n~~~~~ NEXT OBJECT WITHIN CHILDREN ~~~~~\n");
console.log("\n\n\n\nFINAL ITEM COUNT: " + totalItemCount);
}
}
})
//return totalItemCount;
}
getItemsRecursively(totalItemCount);
console.log("\n\n\n\nFINAL ITEM COUNT: " + totalItemCount);
}
});
It's a "scope" problem, you're using the same variable name as parameter of function and out the function, so the parameter overwrite the global variable.
See following please:
var global = 10;
function test(global){
global += 100;
console.log(global);
}
console.log(global);
test(global);
console.log(global);
You simply have to remove the var function's parameters.
var global = 10;
function test(){
global += 100;
console.log(global);
}
console.log(global);
test(global);
console.log(global);
I hope it was clear, bye.

onlogerror event in testcomplete

I have a function which compares 2 array values. As soon as a mismatch value is found the execution stops , but
i want to only when all comparison have been done and if error has been found. There is OnLogError in testcomplete but
do not know how to use it
function compare() {
for (var i = 0; i < arrActualIntendedVal.length; i++) {
if (val1[i] != val2[i]) {
Log.Error("Value " + val1[intArrIndex] + " do not match to Actual Value " +
val2[intArrIndex]);
Runner.Stop(0);
}
}
return true;
}
You just need to "remember" that there was an error and post the corresponding info after your loop is finished.
function compare() {
var errors = new Array();
for (var i = 0; i < arrActualIntendedVal.length; i++) {
if (val1[i] != val2[i]) {
errors.push("Value " + val1[intArrIndex] + " do not match to Actual Value " + val2[intArrIndex]);
}
}
if (errors.length > 0) {
Log.Error("Error when comparing arrays", errors.join("\r\n"));
Runner.Stop();
}
return true;
}

Object doesn't support this property or method in IE8 javascript

Everything works perfectly with modern browsers but for ie8 I get this error for this line:
tabValues.push(tabParams[i].split(attribute_anchor_separator));
Here the whole function:
function checkUrl()
{
if (original_url != window.location || first_url_check)
{
first_url_check = false;
url = window.location + '';
// if we need to load a specific combination
if (url.indexOf('#/') != -1)
{
// get the params to fill from a "normal" url
params = url.substring(url.indexOf('#') + 1, url.length);
tabParams = params.split('/');
tabValues = [];
if (tabParams[0] == '')
tabParams.shift();
for (var i in tabParams)
tabValues.push(tabParams[i].split(attribute_anchor_separator));
product_id = $('#product_page_product_id').val();
// fill html with values
$('.color_pick').removeClass('selected');
$('.color_pick').parent().parent().children().removeClass('selected');
count = 0;
for (var z in tabValues)
for (var a in attributesCombinations)
if (attributesCombinations[a]['group'] === decodeURIComponent(tabValues[z][0])
&& attributesCombinations[a]['attribute'] === tabValues[z][1])
{
count++;
// add class 'selected' to the selected color
$('#color_' + attributesCombinations[a]['id_attribute']).addClass('selected');
$('#color_' + attributesCombinations[a]['id_attribute']).parent().addClass('selected');
$('input:radio[value=' + attributesCombinations[a]['id_attribute'] + ']').attr('checked', true);
$('input[type=hidden][name=group_' + attributesCombinations[a]['id_attribute_group'] + ']').val(attributesCombinations[a]['id_attribute']);
$('select[name=group_' + attributesCombinations[a]['id_attribute_group'] + ']').val(attributesCombinations[a]['id_attribute']);
}
// find combination
if (count >= 0)
{
findCombination(false);
original_url = url;
return true;
}
// no combination found = removing attributes from url
else
window.location = url.substring(0, url.indexOf('#'));
}
}
return false;
}
Any ideas?? Thx!
I noticed you are using a for..in over an Array however using for..in was meant to be used for iteration over objects (not arrays):
for ( var prop in obj1 ) {
if ( obj1.hasOwnProperty(prop) ) {
// loop body goes here
}
}

Image fires onload event, but image is still undefined

I have a fiddle located here illustrating my problem, namely that when I load images using the Image object, onload gets called but the returned object is still undefined.
Here's the code in case the fiddle were to disappear into the void:
var ImageManager = function() {
var _images = [],
_loaded = 0;
var precache = function(imageArray) {
if (!(imageArray instanceof Array)) {
return;
}
for (var i = 0; i < imageArray.length; i++) {
if (typeof imageArray[i] !== 'string') {
continue;
}
_images[i] = new Image();
_images[i].onload = function() {
_loaded++;
document.write('<p>Successfully loaded: ' + imageArray[i] + ' [' + _loaded + '/' + imageArray.length + ']</p>');
}
_images[i].onerror = function() {
document.write('<p>Unable to load: ' + imageArray[i] + '</p>');
}
_images[i].src = imageArray[i];
}
};
var get = function(imagePath) {
if (!_images.hasOwnProperty(imagePath)) {
document.writeln('<p>' + imagePath + ' isn\'t precached!</p>');
return null;
}
return _images[imagePath];
};
return { get: get, precache: precache }
};
// Test case starts here:
var testImages = [
'http://jsfiddle.net/img/logo.png',
'http://jsfiddle.net/img/logo.png',
'http://jsfiddle.net/img/logo.png'
];
var imageManager = new ImageManager();
imageManager.precache(testImages);
Sample output:
Successfully loaded: undefined [1/3]
Successfully loaded: undefined [2/3]
Successfully loaded: undefined [3/3]
As per usual, it's likely something obvious I'm overlooking. Aid me, ye all-knowing oracles.
i inside the event handlers are always equal to imageArray.length - 1, because i increases during the loop. Wrap the loop's body in a closure:
Also, don't use document.write, even for debugging purposes. Use console.log(..), alert(..) or at least document.body.innerHTML += ...
Demo: http://jsfiddle.net/dpDXp/7/
for (var i = 0; i < imageArray.length; i++) {
if (typeof imageArray[i] !== 'string') {
continue;
}
(function(i){ //<-- This
_images[i] = new Image();
_images[i].onload = function() {
_loaded++;
console.log('Successfully loaded: ' + imageArray[i] + ' [' + _loaded + '/' + imageArray.length + ']');
}
_images[i].onerror = function() {
console.log('Unable to load: ' + imageArray[i]);
}
_images[i].src = imageArray[i];
})(i); //<-- This
}

Extract IPTC information from JPEG using Javascript

I'm trying to extract IPTC photo caption information from a JPEG file using Javascript. (I know I can do this server-side, but I'm looking specifically for a Javascript solution.)
I found this script, which extracts EXIF information ... but I'm not sure how to adapt it to grab IPTC data.
Are there any existing scripts that offer such functionality? If not, how would you modify the EXIF script to also parse IPTC data?
UPDATE
I've modified the EXIF script I linked above. It sorta does what I want, but it's not grabbing the right data 100 percent of the time.
After line 401, I added:
else if (iMarker == 237) {
// 0xED = Application-specific 13 (Photoshop IPTC)
if (bDebug) log("Found 0xFFED marker");
return readIPTCData(oFile, iOffset + 4, getShortAt(oFile, iOffset+2, true)-2);
}
And then elsewhere in the script, I added this function:
function readIPTCData(oFile, iStart, iLength) {
exif = new Array();
if (getStringAt(oFile, iStart, 9) != "Photoshop") {
if (bDebug) log("Not valid Photoshop data! " + getStringAt(oFile, iStart, 9));
return false;
}
var output = '';
var count = 0;
two = new Array();
for (i=0; i<iLength; i++) {
if (getByteAt(oFile, iStart + i) == 2 && getByteAt(oFile, iStart + i + 1) == 120) {
var caption = getString2At(oFile, iStart + i + 2, 800);
}
if (getByteAt(oFile, iStart + i) == 2 && getByteAt(oFile, iStart + i + 1) == 80) {
var credit = getString2At(oFile, iStart + i + 2, 300);
}
}
exif['ImageDescription'] = caption;
exif['Artist'] = credit;
return exif;
}
So let me now modify my question slightly. How can the function above be improved?
For what it's worth, I extrapolated on this a bit... I haven't done a whole lot of testing, but the few test images I have seem to work.
var bDebug = false;
var fieldMap = {
120 : 'caption',
110 : 'credit',
25 : 'keywords',
85 : 'byline',
122 : 'captionWriter',
105 : 'headline',
116 : 'copyright',
15 : 'category'
};
function readIPTCData(oFile, iStart, iLength) {
var data = {};
if (oFile.getStringAt(iStart, 9) != "Photoshop") {
if (bDebug) log("Not valid Photoshop data! " + oFile.getStringAt(iStart, 9));
return false;
}
var fileLength = oFile.getLength();
var length, offset, fieldStart, title, value;
var FILE_SEPARATOR_CHAR = 28,
START_OF_TEXT_CHAR = 2;
for (var i = 0; i < iLength; i++) {
fieldStart = iStart + i;
if(oFile.getByteAt(fieldStart) == START_OF_TEXT_CHAR && oFile.getByteAt(fieldStart + 1) in fieldMap) {
length = 0;
offset = 2;
while(
fieldStart + offset < fileLength &&
oFile.getByteAt(fieldStart + offset) != FILE_SEPARATOR_CHAR &&
oFile.getByteAt(fieldStart + offset + 1) != START_OF_TEXT_CHAR) { offset++; length++; }
if(!length) { continue; }
title = fieldMap[oFile.getByteAt(fieldStart + 1)];
value = oFile.getStringAt(iStart + i + 2, length) || '';
value = value.replace('\000','').trim();
data[title] = value;
i+=length-1;
}
}
return data;
}
function findIPTCinJPEG(oFile) {
var aMarkers = [];
if (oFile.getByteAt(0) != 0xFF || oFile.getByteAt(1) != 0xD8) {
return false; // not a valid jpeg
}
var iOffset = 2;
var iLength = oFile.getLength();
while (iOffset < iLength) {
if (oFile.getByteAt(iOffset) != 0xFF) {
if (bDebug) console.log("Not a valid marker at offset " + iOffset + ", found: " + oFile.getByteAt(iOffset));
return false; // not a valid marker, something is wrong
}
var iMarker = oFile.getByteAt(iOffset+1);
if (iMarker == 237) {
if (bDebug) console.log("Found 0xFFED marker");
return readIPTCData(oFile, iOffset + 4, oFile.getShortAt(iOffset+2, true)-2);
} else {
iOffset += 2 + oFile.getShortAt(iOffset+2, true);
}
}
}
IPTC.readFromBinaryFile = function(oFile) {
return findIPTCinJPEG(oFile);
}
I'd like to suggest library exifr that works in both Node.js and browser. And it also supports the new HEIC image format.
exifr.parse(input, {iptc: true}).then(output => {
console.log('IPTC', output)
})
It parses multiple data formats (TIFF/EXIF, ICC, IPTC, XMP, JFIF) but IPTC isn't enabled by default so you need to enabled it in options as seen in the example.
Well, this should get you going on creating your own javascript parser if you can't find a library that already does this.
http://www.iptc.org/std/photometadata/specification/IPTC-PhotoMetadata%28200907%29_1.pdf

Categories