Concatenate json arrays from localStorage and send to PHP - javascript

I am using localStorage to store some json arrays (no more than 25), and when the user logs out, I need to save the information stored in a MySQL database. Therefore, I am sending the data to a PHP script that is in charge of communicating and dealing with all the database stuff.
Anyway, I have been searching on the web, and I found here - Merge two json/javascript arrays in to one array - that I could just use concat.
I basically use this function:
function saveEverything() {
var localStorageData = "";
for (var i=0; i < localStorage.length; i++) {
localStorageData = localStorageData.concat(localStorage.getItem(localStorage.key(i)));
}
...
}
The ... represents the ajax bit that sends the localStorageData to a PHP script.
As you should know, localStorage doesn't store anything but strings, so I have to do JSON.stringify when I am setting the items. You might have noticed that I didn't do JSON.parse when concatenating the localStorage items into the localStorageData variable. I tried that before, and when I did alert(localStorageData) I only got [Object][object] ... (or something like that).
Anyway, with this kind of approach I am sending strings to php, and each json array is separated by line break. Is this the best/correct thing to do or should I have sticked to the JSON.parse way?

What does your JSON look like? concat is a method of Array instances, so you can only do this when you're working with an Array. Furthermore, JSON is a notation, to use it like this you would have to parse it back into JavaScript and then out again.
For example,
var json1 = '[{"foo":"bar"}]',
json2 = '[{"fizz":"buzz"}]';
var mergedJS = JSON.parse(json1).concat(JSON.parse(json2)),
mergedJSON = JSON.stringify(merged);
mergedJSON; // '[{"foo":"bar"},{"fizz":"buzz"}]'
If they're not Arrays, you might be able to get away with just wrapping them (depending on how you want the result), i.e.
var json1 = '{"foo":"bar"}',
json2 = '{"fizz":"buzz"}';
var mergedJSON = '[' + json1 + ',' + json2 + ']';
mergedJSON; // '[{"foo":"bar"},{"fizz":"buzz"}]'
Finally,
You might have noticed that I didn't do JSON.parse when concatenating the localStorage items into the localStorageData variable. I tried that before, and when I did alert(localStorageData) I only got [object Object]
[object Object] is the result of calling toString on almost any Object.
({}).toString(); // "[object Object]"
If you want to see something useful, use console.log and view the Console, or convert back to String with JSON.stringify.

alert(localStorageData) I only got [Object][object]
That's normal, you should stick with this previous version, build an object of objects and in the end use
JSON.stringify(localStorageData)
to send it as string.
function saveEverything(){
var localStorageData = {},
l = localStorage.length,
k;
for (var i=0; i < l; i++) {
k = localStorage.key(i);
localStorageData[k] = JSON.parse(localStorage.getItem(k));
}
return localStorageData;
}
Using object also makes it easier to distinguish these arrays, since you can also save keys under which they were saved.

Related

String to JSON Array

I have the below JSON object array which I get back from the server. However while the server sends back the response the data is enclosed in "" and that then makes the javascript function thing this is a String and not an Array.
"[
[32.361346650846805,50.90932315437885],
[32.36743646734031,50.95189517586323],
[32.35467638118774,50.95876163094135],
[32.342494619322636,50.904516635824166],
[32.36279664436138,50.90039676277729],
[32.380194752587755,50.899023471761666],
[32.3648265962154,50.91481631844135],
[32.361346650846805,50.90932315437885]
]"
I just need to get the String into an array and use a for loop to iterate in the set of elements in the array. However since it is being treated a string it is not possible to iterate using a for loop.
any help?
You just need to run this through JSON.parse(), which is supported by almost all the JavaScript parsers:
console.log(JSON.parse(`[
[32.361346650846805,50.90932315437885],
[32.36743646734031,50.95189517586323],
[32.35467638118774,50.95876163094135],
[32.342494619322636,50.904516635824166],
[32.36279664436138,50.90039676277729],
[32.380194752587755,50.899023471761666],
[32.3648265962154,50.91481631844135],
[32.361346650846805,50.90932315437885]
]`));
Just beware that the JavaScript might not like having line-breaks in strings if you give them in source code. If the original string does have line-breaks, that's totally fine. That's why I have used a template literal here.
// Say you have your string here.
var str = `[
[32.361346650846805,50.90932315437885],
[32.36743646734031,50.95189517586323],
[32.35467638118774,50.95876163094135],
[32.342494619322636,50.904516635824166],
[32.36279664436138,50.90039676277729],
[32.380194752587755,50.899023471761666],
[32.3648265962154,50.91481631844135],
[32.361346650846805,50.90932315437885]
]`;
// Convert to array.
var arr = JSON.parse(str);
// Loop throught the array.
for (var i = 0; i < arr.length; i++)
console.log(arr[i]);

Every character in an array being recognized with ".hasOwnProperty(i)" in javascript as true with Google Apps Script

This is the array:
{"C8_235550":
{"listing":"aut,C8_235550_220144650654"},
"C8_231252":
{"listing":"aut,C8_231252_220144650654"}}
It was fetched with a GET request from a Firebase database using Google Apps Script.
var optList = {"method" : "get"};
var rsltList = UrlFetchApp.fetch("https://dbName.firebaseio.com/KeyName/.json", optList );
var varUrList = rsltList.getContentText();
Notice the .getContentText() method.
I'm assuming that the array is now just a string of characters? I don't know.
When I loop over the returned data, every single character is getting pushed, and the JavaScript code will not find key/value pairs.
This is the FOR LOOP:
dataObj = The Array Shown At Top of Post;
var val = dataObj;
var out = [];
var someObject = val[0];
for (var i in someObject) {
if (someObject.hasOwnProperty(i)) {
out.push(someObject[i]);
};
};
The output from the for loop looks like this:
{,",C,8,_,2,3,5,5,5,0,",:,{,",l,i,s,t,i,n,g,",:,",a,u,t,,,C,8,_,2,3,5,5,5,0,_,2,2,0,1,4,4,6,5,0,6,5,4,",},,,",C,8,_,2,3,1,2,5,2,",:,{,",l,i,s,t,i,n,g,",:,",a,u,t,,,C,8,_,2,3,1,2,5,2,_,2,2,0,1,4,4,6,5,0,6,5,4,",},}
I'm wondering if the array got converted to a string, and is no longer recognized as an array, but just a string of characters. But I don't know enough about this to know what is going on. How do I get the value out for the key named listing?
Is this now just a string rather than an array? Do I need to convert it back to something else? JSON? I've tried using different JavaScript array methods on the array, and nothing seems to return what it should if the data was an array.
here is a way to get the elements out of your json string
as stated in the other answers, you should make it an obect again and get its keys and values.
function demo(){
var string='{"C8_235550":{"listing":"aut,C8_235550_220144650654"},"C8_231252":{"listing":"aut,C8_231252_220144650654"}}';
var ob = JSON.parse(string);
for(var propertyName in ob) {
Logger.log('first level key = '+propertyName);
Logger.log('fisrt level values = '+JSON.stringify(ob[propertyName]));
for(var subPropertyName in ob[propertyName]){
Logger.log('second level values = '+ob[propertyName][subPropertyName]);
}
}
}
What you have is an object, not an array. What you need to do is, use the
Object.keys()
method and obtain a list of keys which is the field names in that object. Then you could use a simple for loop to iterate over the keys and do whatever you need to do.

Can't get JSON to output

First try at using JSON. I have an ajax/php function that returns a JSON object. Back on the js side, I can see the object and output it to a div. It looks fine. I can print it to the console, still looks good. But when I try to iterate over it and expose the individual values, I just get 'undefined' in my console. I can't figure out what I am missing. Sorry it if's something obvious, but I don't see it. Thanks!
var jsonObj = JSON.parse(xmlhttp.responseText);
console.log(jsonObj); //<--looks perfect
console.log(jsonObj.length);
document.getElementById("rightsidebox").innerHTML=response; //<--looks good
for (var group in jsonObj) {
//each of these generates 'undefined' WHY???
//I get 4 'undefined' outputs for each group, so I know that my loop is iterating correctly
console.log(group.id);
console.log(group.day);
console.log(group.time);
console.log(group.name);
}
EDIT: Here is an example of one of the JSON objects being returned by my ajax call. In this example, I only have a single object inside of the array. Of course, there will typically be multiple objects:
[{"id":"7","day":"Thursday","time":"7:00 a.m.","name":"Sub 10:00"}]
EDIT 2: Given this array, I have to ask what the point of JSON is. I can return this array without having PHP encode it in JSON format. So, if all that comes back is just a javascript array, then what have I accomplished? Why not skip the JSON encoding in PHP and then iterate over the array? Clearly there is a reason for this, so I'm obviously missing something. Is there a better way to do what I am trying to accomplish? Thanks!
Consider the following:
var myJson = '{"groupA": {"id": 123, "name": "foo"}}';
var myObj = JSON.parse(myJson);
for (var i in myObj) {
console.log(i);
console.log(i.id);
console.log(myObj[i].id);
}
The expected output here is:
myGroup
undefined
123
This is because you loop is just assigning the 'key' of your object to the value i. If you were to iterate an array, instead of an object, you'd get indices instead of strings.
In the example JSON you've given, you have an array with one object in it. If you intend to have multiple objects in your array, something like this would be better:
for (var group in jsonObj) {
var thisGroup = jsonObj[group];
thisGroup.id; // Etc etc..
}
If you have the correct jsonObj, and you say that you do, you can use formatting to output the object in an easy to read form. You don't have to loop through it.
console.log(JSON.stringify(jsonObj, null, 1));
Not sure why this works, when my original for (var group in jsonObj) loop doesn't, but whatever...
for (var i=0; i < jsonObj.length; i++) {
console.log(jsonObj[i].id);
console.log(jsonObj[i].day);
console.log(jsonObj[i].time);
console.log(jsonObj[i].name);
}

Javascript: How to convert JSON dot string into object reference

I have a string: items[0].name that I want to apply to a JSON object: {"items":[{"name":"test"}]} which is contained in the variable test. I want to apply that string to the object in order to search it (test.items[0].name). I can only think of one way to do this: parse the square brackets and dots using my own function. Is there another way I can do this? Perhaps using eval? (Even though I'd LOVE to avoid that...)
For clarity:
I have a JSON object, what is inside of it is really irrelevant. I need to be able to query the object like so: theobject.items[0], this is normal behaviour of a JSON object obviously. The issue is, that query string (ie. items[0]) is unknown - call it user input if you like - it is literally a string (var thisIsAString = "items[0]"). So, I need a way to append that query string to theobject in order for it to return the value at theobject.items[0]
function locate(obj, path) {
path = path.split('.');
var arrayPattern = /(.+)\[(\d+)\]/;
for (var i = 0; i < path.length; i++) {
var match = arrayPattern.exec(path[i]);
if (match) {
obj = obj[match[1]][parseInt(match[2])];
} else {
obj = obj[path[i]];
}
}
return obj;
}
var name = locate(test, 'items[0].name');
...JSON doesn't have objects, it's just a string.
If you're dealing with an object (ie: you can reference it using dot/bracket notation) then it's just a JavaScript object/array...
So depending on what the deal is, if you're dealing with a 100% string:
'{"name":"string","array":[0,1,2]}'
Then you need to send it through JSON.parse;
var json_string = '{"name":"string","array":[0,1,2]}',
js_obj = JSON.parse(json_string);
js_obj.name; // "string"
js_obj.array; // [0,1,2]
js_obj.array[1]; // 1
If it's not a string, and is indeed an object/array, with other objects/arrays inside, then you just need to go:
myObj.items[0].name = items[0].name;
If it IS a string, then .parse it, and use the parsed object to do exactly what I just did.
If it needs to be a string again, to send to the server, then use JSON.stringify like:
var json_string = JSON.stringify(js_obj);
Now you've got your modified JSON string back.
If you need to support GhettoIE (IE < 8), then download json2.js from Douglas Crockford, and add that script on the page conditionally, if you can't find window.JSON.

Best way to convert string to array of object in javascript?

I want to convert below string to an array in javascript.
{a:12, b:c, foo:bar}
How do I convert this string into array of objects? Any cool idea?
I think that the best way of doing this, as Douglas Crockford (one of the biggests gurus of JavaScript) suggests in here is using the JSON native parser, as it is not only faster than the eval(), it's also more secure.
Native JSON parser is already available in:
Firefox 3.5+
IE 8+
Opera 10.5+
Safari Safari 4.0.3+
Chrome (don't know which version)
And Crockford has made a safe fallback in javascript, called json2.js, which is an adaption of the eval() approach, with some security bits added and with the native JSON parsers API. You just need to include that file, remove its first line, and use the native JSON parser, and if it's not present json2 would do the work.
Here is an example:
var myJSONString = '{ "a": 1, "b": 2 }',
myObject = JSON.parse(myJSONString);
Once parsed you'll get an object with attributes a and b, and as you may know, you can treat an object as a hash table or associative array in JavaScript, so you would be able to access the values like this:
myObject['a'];
If you just want a simple array and not an associative one you could do something like:
var myArray = [];
for(var i in myObject) {
myArray.push(myObject[i]);
}
Lastly, although not necessary in plain JavaScript, the JSON spec requires double quoting the key of the members. So the navite parser won't work without it. If I were you I would add it, but if it is not possible use the var myObject = eval( "(" + myString + ")" ); approach.
Since your string is malformed JSON, a JSON parser can't parse it properly and even eval() will throw an error. It's also not an Array but a HashMap or simply an Object literal (malformed). If the Object literal will only contain number and string values (and no child objects/arrays) you can use the following code.
function malformedJSON2Array (tar) {
var arr = [];
tar = tar.replace(/^\{|\}$/g,'').split(',');
for(var i=0,cur,pair;cur=tar[i];i++){
arr[i] = {};
pair = cur.split(':');
arr[i][pair[0]] = /^\d*$/.test(pair[1]) ? +pair[1] : pair[1];
}
return arr;
}
malformedJSON2Array("{a:12, b:c, foo:bar}");
// result -> [{a:12},{b:'c'},{foo:'bar'}]
That code will turn your string into an Array of Objects (plural).
If however you actually wanted a HashMap (Associative Array) and NOT an array, use the following code:
function malformedJSON2Object(tar) {
var obj = {};
tar = tar.replace(/^\{|\}$/g,'').split(',');
for(var i=0,cur,pair;cur=tar[i];i++){
pair = cur.split(':');
obj[pair[0]] = /^\d*$/.test(pair[1]) ? +pair[1] : pair[1];
}
return obj;
}
malformedJSON2Object("{a:12, b:c, foo:bar}");
// result -> {a:12,b:'c',foo:'bar'}
The above code will become a lot more complex when you start nesting objects and arrays. Basically you'd have to rewrite JSON.js and JSON2.js to support malformed JSON.
Also consider the following option, which is still bad I admit, but marginally better then sticking JSON inside an HTML tag's attribute.
<div id="DATA001">bla</div>
<!-- namespacing your data is even better! -->
<script>var DATA001 = {a:12,b:"c",foo:"bar"};</script>
I am assuming you omit quote marks in the string because you had put it inside an HTML tag's attribute and didn't want to escape quotes.
The simplest, but unsafe way to do it is:
eval('(' + myJSONtext + ')')
But since this will interpret any javascript code, it has security holes. To protect against this use a json parser. If you're using a framework (jquery, mootools, etc.) there's a framework-specific call. Most of them are based on Douglas Crawford's parser available at http://www.json.org/js.html.
You can use "for in"
var myObject = {a:'12', b:'c', foo:'bar'};
var myArray = [];
for(key in myObject) {
var value = myObject[key];
myArray[key] = value;
}
myArray['a']; // returns 12
Notes: considering that myObject only have one level of key-value pairs.
JSON.parse will do the trick. Once parsed, you can push them into the array.
var object = JSON.parse(param);
var array = [];
for(var i in object) {
array.push(object[i]);
}
If you're using jQuery, there's the $.parseJSON() function. It throws an exception if the string is malformed, and "Additionally if you pass in nothing, an empty string, null, or undefined, 'null' will be returned from parseJSON. Where the browser provides a native implementation of JSON.parse, jQuery uses it to parse the string"
Use safe evaluation. Unlike JSON.parse, this doesn't require the keys or values to be quoted. Quote values only if they contain embedded commas.
const myStr = "{a:1, b:2, c:3}";
const myObj = string_exp(myStr);
console.log("dot: " + myObj.c);
function string_exp(sCmd) {
return Function(`'use strict'; return (${sCmd})`)();
}
https://dev.to/spukas/everything-wrong-with-javascript-eval-35on#:~:text=the%20variable%20exists.-,Alternatives,-The%20most%20simple

Categories

Resources