Not able to send value to frontend [duplicate] - javascript

I must be missing something here, but the following code (Fiddle) returns an empty string:
var test = new Array();
test['a'] = 'test';
test['b'] = 'test b';
var json = JSON.stringify(test);
alert(json);
What is the correct way of JSON'ing this array?

JavaScript arrays are designed to hold data with numeric indexes. You can add named properties to them because an array is a type of object (and this can be useful when you want to store metadata about an array which holds normal, ordered, numerically indexed data), but that isn't what they are designed for.
The JSON array data type cannot have named keys on an array.
When you pass a JavaScript array to JSON.stringify the named properties will be ignored.
If you want named properties, use an Object, not an Array.
const test = {}; // Object
test.a = 'test';
test.b = []; // Array
test.b.push('item');
test.b.push('item2');
test.b.push('item3');
test.b.item4 = "A value"; // Ignored by JSON.stringify
const json = JSON.stringify(test);
console.log(json);

Nice explanation and example above. I found this (JSON.stringify() array bizarreness with Prototype.js) to complete the answer. Some sites implements its own toJSON with JSONFilters, so delete it.
if(window.Prototype) {
delete Object.prototype.toJSON;
delete Array.prototype.toJSON;
delete Hash.prototype.toJSON;
delete String.prototype.toJSON;
}
it works fine and the output of the test:
console.log(json);
Result:
"{"a":"test","b":["item","item2","item3"]}"

I posted a fix for this here
You can use this function to modify JSON.stringify to encode arrays, just post it near the beginning of your script (check the link above for more detail):
// Upgrade for JSON.stringify, updated to allow arrays
(function(){
// Convert array to object
var convArrToObj = function(array){
var thisEleObj = new Object();
if(typeof array == "object"){
for(var i in array){
var thisEle = convArrToObj(array[i]);
thisEleObj[i] = thisEle;
}
}else {
thisEleObj = array;
}
return thisEleObj;
};
var oldJSONStringify = JSON.stringify;
JSON.stringify = function(input){
if(oldJSONStringify(input) == '[]')
return oldJSONStringify(convArrToObj(input));
else
return oldJSONStringify(input);
};
})();

Another approach is the JSON.stringify() replacer function param. You can pass a 2nd arg to JSON.stringify() that has special handling for empty arrays as shown below.
const arr = new Array();
arr.answer = 42;
// {"hello":"world","arr":{"answer":42}}
JSON.stringify({ hello: 'world', arr }, function replacer(key, value) {
if (Array.isArray(value) && value.length === 0) {
return { ...value }; // Converts empty array with string properties into a POJO
}
return value;
});

Alternatively you can use like this
var test = new Array();
test[0]={};
test[0]['a'] = 'test';
test[1]={};
test[1]['b'] = 'test b';
var json = JSON.stringify(test);
alert(json);
Like this you JSON-ing a array.

Json has to have key-value pairs. Tho you can still have an array as the value part. Thus add a "key" of your chousing:
var json = JSON.stringify({whatver: test});

Related

Check a key on a JSON object

We are getting JSON string two ways:
"{"phoneNumber":[{"remove":["0099887769"]},{"add":["0099887765"]}]}"
Or
"{"phoneNumber":["0099887765"]}"
We have to convert "{"phoneNumber":[{"remove":["0099887769"]},{"add":["0099887765"]}]}" in "{"phoneNumber":["0099887765"]}" way
Is there any way to write a JavaScript to determine which JSON has "add" key and which one don't have.
When you parse the JSON, you'll have an array with two entries (each objects) if it's the first style, or an array with one entry that's a string. So:
function handle(theJSON) {
let parsed = JSON.parse(theJSON);
if (typeof parsed.phoneNumber[0] === "object") {
parsed.phoneNumber = [parsed.phoneNumber.find(o => o.add).add[0]];
}
console.log(parsed);
}
Live Example:
function handle(theJSON) {
let parsed = JSON.parse(theJSON);
if (typeof parsed.phoneNumber[0] === "object") {
parsed.phoneNumber = [parsed.phoneNumber.find(o => o.add).add[0]];
}
console.log(parsed);
}
handle('{"phoneNumber":[{"remove":["0099887769"]},{"add":["0099887765"]}]}');
handle('{"phoneNumber":["0099887765"]}');
Or if you need an ES5 version:
function handle(theJSON) {
var parsed = JSON.parse(theJSON);
if (typeof parsed.phoneNumber[0] === "object") {
parsed.phoneNumber = [parsed.phoneNumber.find(function(o) { return o.add; }).add[0]];
}
console.log(parsed);
}
You can use some to return true/false if "add" is a property on any object in the array. Here's a general solution:
const json = '{"phoneNumber":[{"remove":["0099887769"]},{"add":["0099887765"]}]}';
const data = JSON.parse(json);
function checkForKey(data, { arrayKey, searchKey }) {
return data[arrayKey].some(obj => obj[searchKey]);
}
const hasAdd = checkForKey(data, {arrayKey: 'phoneNumber', searchKey: 'add' });
console.log(hasAdd);
You can do it by using for..in loop and hasOwnProperty check, finally push only the phoneNumbers with add index. Hope this helps :)
const expected = {'phoneNumber':[]};
let str = '{"phoneNumber":[{"add":["0099844465"],"remove":["0099887769"]},{"add":["0099887765"]}]}';
const st_obj = JSON.parse(str);
for (var k in st_obj['phoneNumber']) {
if (st_obj['phoneNumber'][k].hasOwnProperty('add')) {
expected['phoneNumber'].push(st_obj['phoneNumber'][k]['add']);
}
}
console.log(expected);
use let obj = JSON.parse('{"phoneNumber":[{"remove":["0099887769"]},{"add":["0099887765"]}]}') to convert it to object.
then iterate it and fetch value and push it into new object
just check if add is top level propery
if(obj['add']) {....}
if it is exists then if will be true, if not it will return undefined and if will be false,
if you should check it in array of objects, you can use the same logic with find method from array prototype
phoneNumber.find(obj => obj['add']);
You can check whether the add key exists by converting the JSON into array:
How to convert JSON object to JavaScript array
With that you are able to check if the key exists by checking whether the key is undefined:
obj["phonenumber"]["add"] != undefined

There is any rule for define a json key in JavaScript?

I'm learning JavaScript and I was looking for a while about this and I have not got any answer about this. My question is if there is any rule to define a JSON key in JavaScript.
For example, in python there is a rule defining dict and is All the keys must be of an immutable data type such as strings, numbers, or tuples.
var json = {};
json[""] = "White space";
json[" "] = "Two white space";
var emptyJSON = {};
var emptyArray = [];
function a (){}
json[a] = "Function";
json[emptyJSON] = "Json";
json[emptyArray]= "Array";
//I don't know why this property whit an empty array does not appear when I console the json
console.log("Print the entire object =>", json);
//But it appears when I console the specific property
console.log("Print empty array property =>", json[emptyArray]);
Object keys are strings. Anything that is not a string is converted to a string.
var obj = {};
obj[1] = 1;
console.log(obj["1"]);
obj[{}] = 2;
console.log(obj["[Object object]"]);
obj[[1, 2]] = 3;
console.log(obj["1,2"]);

Merging 2 arrays in local storage in javascript

I am trying to append an array of objects(new) to the local storage which already has some array of objects(previous) built in. Specifically, I want to merge these 2 arrays (previous and new) in the local storage.
Have tried the below code :
function appendToStorage(name, data)
{
var old = localStorage.getItem(name);
if(old === null)
old = "";
localStorage.setItem(name, old.concat(data));
}
appendToStorage('ObjAry', JSON.stringify(objectIdArray));
And this is the output that I am getting :
["IrGszUBa0F","l366vn6mPa","2qn7JUoRwg","s2fZa0mXnb","WIaXLwmXRa"]["ZKHtnHoHgH","rtbI1sDfPm","U1eVDi9bNM","tUGNCl6hNl","lkq6tswVsZ"]
All I want is that, the second array should append to the first array so the output becomes :
["IrGszUBa0F","l366vn6mPa","2qn7JUoRwg","s2fZa0mXnb","WIaXLwmXRa","ZKHtnHoHgH","rtbI1sDfPm","U1eVDi9bNM","tUGNCl6hNl","lkq6tswVsZ"]
Can anyone guide me on what I am doing wrong ?
You are pretty close, there are just three small mistakes:
You are stringifying the array before concatenating it (so you are attaching a string to an array).
The default value for old is a string, which should probably be an array?
In order to use the array from localstorage, you need to parse it again using JSON.parse.
The resulting code would then be:
function appendToStorage(name, data)
{
var old = localStorage.getItem(name);
if(old == null) {
old = [];
} else {
old = JSON.parse(old);
}
localStorage.setItem(name, JSON.stringify(old.concat(data)));
}
appendToStorage('ObjAry', objectIdArray);
If your local storage entry could contain other values as well, you could add a try ... catch block to your code to make sure that JSON.parse doesn't blow up if it fails to parse the value:
function appendToStorage(name, data)
{
var old = localStorage.getItem(name);
try {
old = JSON.parse(old);
} catch(e) {
old = [];
}
localStorage.setItem(name, JSON.stringify(old.concat(data)));
}
appendToStorage('ObjAry', objectIdArray);
You're concatenating the whole object returning from
JSON.stringify(objectIdArray)
Try
appendToStorage('ObjAry', objectIdArray);
LocalStorage stores a string values by a string key. To store arrays/objects as string we serialize them into JSON. So you need to parse JSON after getItem, merge parsed value with new portion of data, convert merged object to JSON and pass it to setItem.
function appendToStorage(name, data) {
var old = localStorage.getItem(name) || '[]';
var oldObject = JSON.parse(old) || [];
var merged = oldObject.concat(data);
localStorage.setItem(name, JSON.stringify(merged));
}
appendToStorage('ObjAry', objectIdArray);

accessing JSON value if key is array element

suppose i receive JSON object from the server as this
{ "asdf[zxcv]": "qwer" }
how do i access asdf, zxcv, and qwer in javascript, so i can use the object this way ?
theobj.asdf[zxcv] = 'qwer'
Bracket notation is not in the JSON RFC. You can only read it as string.
var simpleObj = {
"simpleKey": "simpleValue"
}
console.log(simpleObj)
var advObj = {
"advKey[1]": "advValue"
}
console.log(JSON.parse(advObj)); // SyntaxError
console.log(advObj.advKey[1]) // TypeError
console.log(advObj["advKey[1]"]) // can only read as string
You would need to refactor the source JSON into something more meaningful so you can access the values in regular JavaScript way.
Run the following snippet to check how you can solve the issue:
var x = '{ "asdf[zxcv]": "qwer" }';
var y = JSON.parse(x);
var result = Object.keys(y).reduce(function(result, key) {
var parentKey = key.substring(0, key.indexOf("["));
var innerKey = /[a-z]+\[([a-z]+)\]/i.exec(key)[1];
if (!result.hasOwnProperty(key))
result[parentKey] = {};
result[parentKey][innerKey] = y[key];
return result;
}, {});
document.getElementById("structure").textContent = JSON.stringify(result);
var zxcv = result["asdf"]["zxcv"];
document.getElementById("someValue").textContent = zxcv;
<h2>Refactored data structure as nested objects:</h2>
<div id="structure"></div>
<h2>Accessing some value: result["asdf"]["zxcv"] or result.asdf.zxcv</h2>
<div id="someValue"></div>
It's all about creating nested objects to represent the associative keys in the source JSON properties representing a conceptual associative array...
This is one of the way to access all elements without reconstructing object.
jQuery.each(JSON.parse('{ "asdf[zxcv]": "qwer" }'), function(index, value) {
var i = index;// i = "asdf[zxcv]"
var v = value;// v = "qwer"
var iOfInnerValue = (/\[(.*?)\]/g).exec(i)[1];// innerValue = "zxcv"
var iOfOuterValue = index.replace("["+(/\[(.*?)\]/g).exec(i)[1]+"]",""); // outerValue = "asdf"
});
You'll need to assign the data to a variable and then you can use Object keys to get the key which is the part before the :. Here's an example.
var j = { "asdf[zxcv]": "qwer" };
console.log(Object.keys(j)); //["asdf[zxcv]"]
console.log(j); //{asdf[zxcv]: "qwer"}

javascript object to string

I'm trying to serialize a javascript object but with a particular form(I think it has to be a method).
Example:
var media = new Object();
media.url = "localhost";
media.foo = "asd"
var data=new Object();
data.title = "myTitle";
data.description = "myDescription";
data.media.push(media);
I need to serialize data this way:
"title=myTitle&description=myDescription&media[0].url=localhost&media[0].foo=asd"
The important thing is the way the array is written.
Check out Convert a JSON object's keys into dot notation paths and Convert complex JavaScript object to dot notation object. You can easily adapt those to handle your array keys special:
function transform(obj) {
var result = {};
recurse(obj, "");
return result;
function recurse(o, name) {
if (Object(o) !== o)
result[name] = o;
else if (Array.isArray(o))
for (var i=0; i<o.length; i++)
recurse(o[i], name+"["+i+"]");
else // if plain object?
for (var p in o)
recurse(o[p], name?name+"."+p:p);
}
}
You can then apply $.param on the result to get the URL encoding etc:
$.param(transform(data))
(or just pass it into the data parameter of $.ajax).
There are multiple ways to serialize an object into a list (string) of parameters, have a look:
How to serialize an Object into a list of parameters?
One example is a method such as the below:
var str = "";
for (var key in obj) {
if (str != "") {
str += "&";
}
str += key + "=" + obj[key];
}
You can modify it to suit the style you need.
jQuery provides this via jQuery.param
var params = $.param(data);
console.log(params);
Produces:
title=myTitle&description=myDescription&media%5B0%5D%5Burl%5D=localhost&media%5B0%5D%5Bfoo%5D=asd
As you can see, it handles the nested array and object as you wish (%5B and %5D are URL encodings for [ and ]).
If you're using $.ajax() or one of its shortcuts, you don't need to call this explicitly. If you supply the object as the data argument or option, jQuery will automatically serialize it using this method.
you can use jQuery.param to do this:
$.param({a:'2', b: 1.2, c: "hello world"})// -> a=2&b=1.2&c=hello+world
EDIT
What I was missing above is the array support sorry bout that.
For this you'll need to decodeURIComponent()
var media = new Object();
media.url = "localhost";
media.foo = "asd"
var data=new Object();
data.title = "myTitle";
data.description = "myDescription";
data.media = [];
data.media.push(media);
alert(decodeURIComponent($.param(data)));
Output:
title=myTitle&description=myDescription&media[0][url]=localhost&media[0][foo]=asd
http://jsfiddle.net/bLu8Q/
Sorry, but I need to change. Thought it was easier but when looking at the result I saw that it was not so straight forward. If you're using jquery though you can simply do it like this:
var media = new Object();
media.url = "localhost";
media.foo = "asd"
var data=new Object();
data.title = "myTitle";
data.description = "myDescription";
data.media = []; // you forgot this...
data.media.push(media);
var data = $.param(data));

Categories

Resources