JavaScript array.indexOf() not getting correct index - javascript

I have an array containing four element located in local storage.
function rm(t)
{
// var l = localStorage.getItem("subje");
// hide element from html page
document.getElementById(t).style.display = 'none';
var c = localStorage.getItem("class");
var item = c+""+t; // c is int and t is string
var subj = localStorage.getItem("std-sub");
var x = subj.indexOf(item);
/*
subj.splice(x,1);
localStorage.setItem("final", subj);
var k = localStorage.getItem("final");*/
document.getElementById('show').innerHTML = x;
}
when I executing function the value of x is showing
29,17,7,0. but my given array have only four element.
why?????

getItem always returns a string (or null). Therefore subj.indexOf(item); will get the position of the substring item in the string subj. You should encode and decode the array as JSON and store that in local storage instead.
See Storing Objects in HTML5 localStorage

Related

How to save and retrieve an array of floating point coordinates to localStorage in Javascript? [duplicate]

This question already has answers here:
How to store objects in HTML5 localStorage/sessionStorage
(24 answers)
Closed 2 years ago.
I want to save 5 button coordinates to localStorage then retrieve them for a click event to identify when a button is clicked. Centre coordinates for the buttons are saved to an array as they are rendered. When the object is retrieved I can only access them as a single character string rather than as an array.
How do I save them as an array ? and how do I retrieve them ?
I'm not sure if what I want to do is even possible as this is the first idea I have for using JSON. The idea came from looking at this answer which made me ask if this could be a way to store and receive a set of floating point numbers. So I'd be most grateful if anyone can point me in the right direction.
during render
var xButtonCoords = [];
var yButtonCoords = [];
xButtonCoords.push(button.x.toPrecision(6));
yButtonCoords.push(button.y.toPrecision(6));
Once rendering is done coordinates are saved to localStorage.
store(xButtonCoords, yButtonCoords);
The store function packs button coordinates as a string object before it is stored.
function store(xButtonCoords, yButtonCoords) {
var xCoords = packString(xButtonCoords, xButtonCoords.length); // show just x coordinate
localStorage.setItem('xCoords', JSON.stringify(xCoords)); // put into storage
The packString function represents button coordinates as a string before putting the object into storage. The string object uses a key value pair.
function packString(points, numberOf) {
var coords = [];
for (i = 0; i < numberOf; i++) { // do number of shifts
var key = i; // make a coordinate key
var val = points.shift(); // get coordinate value
var string = key+" : "+val; // create key value string
coords.push(string); // save string as coords
}
return coords;
}
during event
var X = localStorage.getItem('xCoords'); // retrieve from storage
var report = 'xDots: '+JSON.parse(X);
alert(report);
The retrieved object appears as a string of characters.
NB. The five string character integers in the key represent the order in which buttons are rendered. I am trying to create an array of 5 floating point numbers not a string of characters.
for (var [key, value] of Object.entries(report)) {
alert(`${key}: ${value}`); // characters not elements
}
}
Well you should use an array instead of an object because you need indexing, so you can use JSON.stringify to make a JSON string from your array then store it in localStorage, and when you want to retrieve it just do JSON.parse on it and you get the array back, here is a small example, note that stack snippets don't allow local storage usage so i used only an object, it's the same idea of course
// save the array as a string
var a = [0.1, 1.2, 2.3, 3.4, 4.5], myLocalStorage = {};
myLocalStorage.a = JSON.stringify(a);
// it's a string so you get the first char only
console.log(myLocalStorage.a[0]);
// get it back to an array so you get the first item
var b = JSON.parse(myLocalStorage.a);
console.log(b[0]);
I will try this with localStorage
You can do the same with local storage
// save the array as a string
var a = [0.1, 1.2, 2.3, 3.4, 4.5];
localStorage.a = JSON.stringify(a);
// it's a string so you get the first char only
console.log(localStorage.a[0]);
// get it back to an array so you get the first item
var b = JSON.parse(localStorage.a);
console.log(b[0]);
or using set and get
var a = [0.1, 1.2, 2.3, 3.4, 4.5];
localStorage.setItem("a", JSON.stringify(a));
// it's a string so you get the first char only
console.log(localStorage.getItem("a")[0]);
// get it back to an array so you get the first item
var b = JSON.parse(localStorage.getItem("a"));
console.log(b[0]);

My variables wont save in the array, they get replaced? help me

I am trying to save my variables in an array. Theses variables are written in by the user and saved to localStorage when a button is pressed. On my other html page i reach these variables and put them in 3 different arrays(the variables, that go in three arrays). Then the user writes in new text and save to the variables. Now to the problem. The newly created variables don't add to the array, they replace. I'm thinking this is due to to the same variable name however I can't find an solution.
I have tried to change variable names etc for saving the new variable but cant find solution.
//This is html page 2 (gets the items from localhost)
var TankaKostnadVar = localStorage.getItem("StorageKostnadVar");
var TankaLiterVar= localStorage.getItem("StorageLiterVar");
var TankaDatumVar = localStorage.getItem("StorageDatumVar");
var arrayKostnad = [];
var arrayLiter = [];
var arrayDatum = [];
arrayKostnad.push(TankaKostnadVar,);
arrayLiter.push(TankaLiterVar,);
arrayDatum.push(TankaDatumVar,);
document.write(arrayLiter,arrayKostnad,arrayDatum); //Ignore this, just test
//This is the code where the user is writing and it saves to localStorage.
//Html page 1 that saves the variables
var TankaKostnadVar = document.getElementById("tankaKostnad").value;
var TankaLiterVar = document.getElementById("tankaLiter").value;
var TankaDatumVar = document.getElementById("tankaDatum").value;
localStorage.setItem("StorageKostnadVar", TankaKostnadVar);
localStorage.setItem("StorageLiterVar", TankaLiterVar);
localStorage.setItem("StorageDatumVar", TankaDatumVar);
I expect the array to add the variable. So if the user writes an 5 the array should first be [5] then when the user writes an 8 the array should be [5,8]
If you don't want use JSON, you can save string comma separated and, when necessary, transform the items to numbers. To transform in numbers you can use map function or a for. Localstorage only save strings, so if you need to be back to numbers you need to use JSON.parse or use function parseInt, that is global.
//Retrieve saved items from localstorage
var TankaKostnadVar = localStorage.getItem("StorageKostnadVar"); // "1,2"
var TankaLiterVar = localStorage.getItem("StorageLiterVar");
var TankaDatumVar = localStorage.getItem("StorageDatumVar");
TankaKostnadVar += "," + document.getElementById("tankaKostnad").value;
TankaLiterVar += "," + document.getElementById("tankaLiter").value;
TankaDatumVar += "," + document.getElementById("tankaDatum").value;
localStorage.setItem("StorageKostnadVar", TankaKostnadVar);
localStorage.setItem("StorageLiterVar", TankaLiterVar);
localStorage.setItem("StorageDatumVar", TankaDatumVar);
// if you want to transform TankaKostnadVar and others two, just do like this
TankaKostnadVar.split(','); // result: ['1', '2']
// if you want to transform to number
TankaKostnadVar = TankaKostnadVar.split(',').map( function(number) {
return parseInt(number)
} );
The split function of string, breaks a strings in parts separated by one string. In this case, breaks a string separated with comma. So "1,2" turns into ['1', '2'].
If you want to keep adding to the array you'll need to push the entire array you're holding in memory up to localStorage after appending a new element. Alos, localStorage only stores string values so if you want to maintain the Array structure you'll have to use JSON.stringify() before running setItem() and then JSON.parse() next time you access those values with getItem().
//This is the code where the user is writing and it saves to localStorage.
//Html page 1 that saves the variables
var TankaKostnadVar = document.getElementById("tankaKostnad").value;
var TankaLiterVar = document.getElementById("tankaLiter").value;
var TankaDatumVar = document.getElementById("tankaDatum").value;
localStorage.setItem("StorageKostnadVar", JSON.stringify( [TankaKostnadVar] ));
localStorage.setItem("StorageLiterVar", JSON.stringify( [TankaLiterVar] ));
localStorage.setItem("StorageDatumVar", JSON.stringify( [TankaDatumVar] ));
//This is html page 2 (gets the items from localhost)
var TankaKostnadVar = localStorage.getItem("StorageKostnadVar");
var TankaLiterVar = localStorage.getItem("StorageLiterVar");
var TankaDatumVar = localStorage.getItem("StorageDatumVar");
var arrayKostnad = JSON.parse(TankaKostnadVar);
var arrayLiter = JSON.parse(TankaLiterVar);
var arrayDatum = JSON.parse(TankaDatumVar);
// Now you have arrays with data, but I don't know what you want to do with them...
// you could add more values like this (still page 2)...
arrayKostnad.push('new value 1')
arrayLiter.push('new value 2')
arrayDatum.push('new value 3')
localStorage.setItem("StorageKostnadVar", JSON.stringify( arrayKostnad ));
localStorage.setItem("StorageLiterVar", JSON.stringify( arrayLiter ));
localStorage.setItem("StorageDatumVar", JSON.stringify( arrayDatum ));
// now check the values again
var TankaKostnadArr = JSON.parse(localStorage.getItem("StorageKostnadVar"));
var TankaLiterArr = JSON.parse(localStorage.getItem("StorageLiterVar"));
var TankaDatumArr = JSON.parse(localStorage.getItem("StorageDatumVar"));
document.write(TankaKostnadArr, TankaLiterArr, TankaDatumArr)
And this is what I would do to clean things up a little...
// Import these functions and variables to any file that needs to interact with LocalStorage
var storageKeys = ["StorageKostnadVar","StorageLiterVar","StorageDatumVar"];
function addToArray(key, val, arrObj) {
arrObj[key].push(val)
}
function storeAllLocalStorage(arrayObject) {
Object.keys(arrayObject).forEach(key=>{
localStorage.setItem(key, JSON.stringify(arrayObject[key]));
})
}
// Use above functions when needed
var storedArrays = storageKeys.reduce((acc,key)=> {
var val = JSON.parse(localStorage.getItem(key));
if (typeof val === 'array') return {...acc, [key]:val};
return {...acc, [key]:[val]};
},{})
addToArray("StorageKostnadVar", document.getElementById("tankaKostnad").value, storedArrays);
addToArray("StorageLiterVar", document.getElementById("tankaLiter").value, storedArrays);
addToArray("StorageDatumVar", document.getElementById("tankaDatum").value, storedArrays);
storeAllLocalStorage(storedArrays)
You are simply using localStorage.setItem which saves your values with the given key. If the key exists, it will replace the value. Before you do a .setItem, get the value from the local storage first, then parse it to array so that you can finally push the new user inputs to that parsed array. Then you can .setItem to replace the "outdated" value from the localStorage.
UPDATE Example:
Sorry for leaving this hangin without an example. Here it is:
// Get array from local storage
const stringifiedArray = localStorage.getItem('myCollection');
// If there is no 'myCollection' from localStorage, make an empty array
const myCollection = stringifiedArray ? JSON.Parse(stringifiedArray) : [];
myCollection.push('My new item added'); // update array
localStorage.setItem('myCollection', JSON.stringify(myCollection)); // save

Decrypt each element of an Array

I've got an array of n string elements encrypted with CryptoJS : [krypt1, krypt2, krypt3, ...]
The keydecrypt is the same for each element.
I try to decrypt each element of the array and return an array of string decrypted elements like this [dekrypt1, dekrypt2, dekrypt3, ...]
My code is:
var urltodecrypt = this.url.chunk;
function decrypteach(x) {
return CryptoJS.AES.decrypt(x.toString(), keydecrypt).toString(CryptoJS.enc.Utf8);
}
var clearfileurl = urltodecrypt.map(decrypteach);
When there is 1 element in the array, everything's fine: it return an array of rightly decrypted string element.
When there is >1 elements, var urltodecrypt give still the right array (verified), but var clearfileurl return an error: Error: Malformed UTF-8 data
What am I missing?
EDIT
Tried on #vector advices a loop over each element function on this model :
var urltodecrypt = this.url.chunk;
var arrayLength = urltodecrypt.length;
for (var i = 0; i < arrayLength; i++) {
var clearfileurl = CryptoJS.AES.decrypt(urltodecrypt.toString(), keydecrypt).toString(CryptoJS.enc.Utf8);
}
console.log (clearfileurl);
Exact same result = 1 element array :ok / >1 elements array: Error: Malformed UTF-8 data
EDIT #2: question close
I just broke my first code (map) into different vars :
x.toString()
CryptoJS.AES.decrypt()
toString(CryptoJS.enc.Utf8)
I relaunched my server : everything's fine now, from 1 element array to +10 elements array.
Just in case, below my (heavy & superstitious...) tested working code:
var urltodecrypt = this.url.chunk;
console.log (urltodecrypt);
function decrypteach(x) {
var stringurl = x.toString();
var bytesfileurl = CryptoJS.AES.decrypt(stringurl, keydecrypt);
var finaldecrypturl = bytesfileurl.toString(CryptoJS.enc.Utf8);
return finaldecrypturl;
}
var clearfileurl = urltodecrypt.map(decrypteach);
console.log (clearfileurl);

Update JSON.parsed object in javascript

I am trying to update the parsed object.data is the JSON object received from the server.
var document_text = JSON.parse(data.projectData[0]['document_text']);
for(var j = 0; j < document_text.length;j++)
{
var k = JSON.parse(document_text[j]);
var document_data = JSON.parse(k).text;
var page_number = JSON.parse(k).page_number;
}
Now i want to update the document_text object which contains the text and the page_number field.Note that i have to parse the object two times.First to parse the outer value then to get the inner value.How can i update the the fields of document_text(i.e text,page_number).
This is the original data
["\"{\\\"text\\\":\\\"Osddsdsdsdsds \\\\n\\\\n to as \\\\\\\"sdfdsdsfsdfsdfsdf\\\\\\\") and CPGsddsdsdsdssdROsdsdsdsdP sdsdds, a \\\\sd sdds\\\\n\\\\n\\\\f\\\",\\\"page_number\\\":44}\"","\"{\\\"text\\\":\\\"Page 14 \\\\n\\\\nsdfsdfsdfdscopysdsdds\\\n\\\\n\\\\f\\\",\\\"page_number\\\":45}]
var document_text = JSON.parse(data.projectData[0]['document_text']);
/* At this point, document_text is already a JSON object. Iterating over it with
a for loop doesn't make much sense. You can now just access its properties directly. */
document_text.text = "Some other text";
document_text.page_numer = 1;
/* Now we can return it to where it came from by stringify'ing it */
data.projectData[0]['document_text'] = JSON.stringify(document_text);

JavaScript empty array

https://stackoverflow.com/a/1234337/1690081
shows that array.length = 0;will empty array but in my code it doesn't
here's an sample:
window.onload = draw;
window.onload = getFiles;
var namelist = [];
function draw(){
// assing our canvas to element to a variable
var canvas = document.getElementById("canvas1");
// create html5 context object to enable draw methods
var ctx = canvas.getContext('2d');
var x = 10; // picture start cordinate
var y = 10; // -------||---------
var buffer = 10; // space between pictures
for (i=0; i<namelist.length; i++){
console.log(namelist[i])
var image = document.createElement('img');
image.src = namelist[i];
canvas.appendChild(image);
ctx.drawImage(image,x,y,50,50);
x+=50+buffer;
}
}
function getFiles(){
namelist.length = 0;// empty name list
var picturesFiles = document.getElementById('pictures')
picturesFiles.addEventListener('change', function(event){
var files = picturesFiles.files;
for (i=0; i< files.length; i++){
namelist.push(files[i].name);
console.log(namelist)
}
draw();
}, false);
}
after i call getFiles() second time. It doesn't remove the previous list, just appends to it. any idea why?
You should empty the array in the event handler, not getFiles which is only called once per pageload. It is actually doing nothing because the array is already empty when the page loads.
picturesFiles.addEventListener('change', function(event){
namelist.length = 0; //empty it here
var files = picturesFiles.files;
for (i=0; i< files.length; i++){
namelist.push(files[i].name);
console.log(namelist)
}
draw();
}, false);
Another problem is that you cannot just set .src to the name of a file. That would make the request to your server for the file.
To really fix this, just push the file objects to the namelist:
namelist.push(files[i]);
Then as you process them in draw, create localized BLOB urls to show them:
var file = namelist[i];
var url = (window.URL || window.webkitURL).createObjectURL( file );
image.src = url;
It looks like you're using namelist as a global variable. This would be easier (and would avoid needing to empty it at all) if you passed the new array out of the function as a return value.
ie:
function getFiles() {
var newNameList = [];
..... //push entries here.
return newNameList;
}
... and then populate namelist from the return value where you call it:
namelist = getFiles();
However, to answer the question that was actually asked:
Instead of setting the length to zero, you can also reset an array simply by setting it to a new array:
namelist = [];
You haven't shown us how you're 'pushing' entries to the list, but I suspect that the end result is that namelist is being generated as a generic object rather than an array object. If this is the case, then setting .length=0 will simply add a property to the object named length with a value of 0. The length property in the way you're using it only applies to Array objects.
Hope that helps.
If you are using non-numeric indexes then the array will not clear.
"...whenever the length property is changed, every property whose name is an array index whose value is not smaller than the new length is automatically deleted"
Test:
var arr = [];
arr['this'] = 'that';
arr.length = 0;
console.log(arr);
//output ['this':'that']
var arr = [];
arr[0] = 'that';
arr.length = 0;
console.log(arr);
//output []
There is nothing wrong with how you empty the array, so there has to be something else that is wrong with your code.
This works fine, the array doesn't contain the previous items the second time:
var namelist = [];
function draw() {
alert(namelist.join(', '));
}
function getFiles() {
namelist.length = 0; // empty name list
namelist.push('asdf');
namelist.push('qwerty');
namelist.push('123');
draw();
}
getFiles();
getFiles();
Demo: http://jsfiddle.net/Guffa/76RuX/
Edit:
Seeing your actual code, the problem comes from the use of a callback method to populate the array. Every time that you call the function, you will add another event handler, so after you have called the function the seccond time, it will call two event handlers that will each add all the items to the array.
Only add the event handler once.

Categories