Add JSON object to Another JSON Object at particular place - javascript

I have two JSON Objects:
var JSonData = {"li_ZPI":{},"li_ZIN":{"li_ISD":{},"li_AAH":{"li_AAD":{}},"li_EAH":{"li_EAD":{}},"li_REG":{},"li_PSC":{},"li_IMC":{},"li_GSP":{},"li_IES":{}}};
and
var additionalJSonData = {"li_AAH_1":{"li_AAD_1":{}}};
I want to add additionalJSonData object after JSONData "li_AAH" Object.

If you are using jQuery, you can easily do it using $.extend() function:
$.extend(true, JSonData,additionalJSonData);
In any other frameworks, there are similar functions.

The problem is that there's no after. These "JSON" objects (Javascript objects, really, JSON would be text strings that could convert to JS objects) are hashes, not arrays. Hashes have no order - that is,
for ( var f in JSonData ) {
}
there's no rule that the various keys ("li_ZPI", etc.) would show up in any particular order, or even the same order each time.
So you can certainly add the new item:
JSonData["li_AAH_1"] = {"li_AAD_1":{}};
but don't expect the eventual JSON string to be ordered the way you're hoping.

Related

Accessing Elements of JS Object

I have created array in a object,
var obj_report_dailog = { array_report_dailog : [] }
Then push data to object,
obj_report_dialog.array_report_dialog.push({from: fromDate})
obj_report_dialog.array_report_dialog.push({to: toDate})
obj_report_dialog.array_report_dialog.push({fabrika: fabrika})
Then,
var json = JSON.stringify(obj_report_dialog);
How can I access to elements of that object?
console.log("işte bu: " + json);
output:
işte bu: {"array_report_dialog":[{"from":"2017-08-01"},{"to":"2017-09-21"},{"fabrika":["Balçova"]}]}
Two things:
You don't want to JSON.stringify unless you're sending the resulting string somewhere that will parse it. Remember, JSON is a textual notation for data exchange; JSON.stringify gives you a string to send to some receiver. When you have the JSON string, you don't access the properties of the objects in it.
If you're receiving that JSON string, you'd parse it via JSON.parse and then access the properties on the result.
Leaving aside the JSON thing, you probably don't want to add data the way you're adding it. You're adding three separate objects as three entries in the array, each with one property. You probably want to push one object with all three properties:
obj_report_dialog.array_report_dialog.push({
from: fromDate,
to: toDate,
fabrika: fabrika
});
Then you'd access them as obj_report_dialog.array_report_dialog[0].from, obj_report_dialog.array_report_dialog[0].to, and obj_report_dialog.array_report_dialog[0].fabrika. Or more likely, you'd have a loop like this:
obj_report_dialog.array_report_dialog.forEach(function(entry) {
// Use entry.from, entry.to, and entry.fabrika here
});
(See this answer for more options for looping through arrays.)
But, if you really want to push them as separate objects, you'd access them as obj_report_dialog.array_report_dialog[0].from, obj_report_dialog.array_report_dialog[1].to, and obj_report_dialog.array_report_dialog[2].fabrika (note the indexes going up).
If you stringify a json, it's gonna create a string representation of your object.
To access data in a string like that we usually use JSON.parse that create an json object from a string. Which is the obj_report_dailog you had at start.
You can make object from json by using JSON.parse()
JSON.parse(json).array_report_dialog

Turn JSON string with duplicate keys into JSON string arrays

I'm trying to generate a JSON string which will contain all of my filters, but I constantly stuck with duplicate keys. So, I want to find a solution that turns the duplicate keys into a JSON array.
For example, I have this JSON object:
{
"filter-1": "value-1",
"filter-1": "value-2",
"filter-2": "value-3",
"filter-3": "value-4"
}
And I want to turn it into this:
{
"filter-1": ["value-1", "value-2"],
"filter-2": "value-3",
"filter-3": "value-4"
}
Can someone point me in the right direction? I would appreciate solutions in JavaScript but any method would be more than welcome! Thanks in advance!
The duplicate key-pairs are causing overwrite issues.
Javascript objects doesn't allow duplicate keys.
var testObj = JSON.parse('{"filter-1":"value-1","filter-1":"value-2","filter-2":"value-3","filter-3":"value-4"}'); will overwrite the first key-pair (filter-1: value-1) when it parses the second key-pair (filter1: value-2) since both key-pairs have the same key.
However, JSON specification (not Javscript objects) does not specifically mention whether duplicate keys are allowed or not. You may wish to write your own parsing function to handle the duplicate keys.
You will have to change the format of your JSON since keys in JS objects must be unique.
Then you can hard coded or use libraries like jquery or underscorejs to group them out.
https://jsfiddle.net/p5fkjcwt/1/
var objects =
{
0: {"filter": "filter-1", "value":"value-1"},
1: {"filter": "filter-1", "value":"value-2"},
2: {"filter": "filter-2", "value":"value-3"},
3: {"filter": "filter-3", "value":"value-4"}
}
var result = _.groupBy(objects,"filter")
console.log(result)

Does js EVAL function change position of elements?

I have an application in PHP and JS. When I EVAL the json encoded PHP array the array sort changes. For example, if I have an array in PHP like this:
<?php
$array = [148 => 'Plane', 149 => 'Car'];
?>
<script>
var array = eval(<?php echo json_encode($array)?>);
</script>
When I print the array in console, the elements doesn't have the same position. Do you know how can this happens?
UPDATE
Thanks for the answers but I want to keep the exactly same order in a JS structure, so I don't want to order the array by a specific field. Maybe the order get from the DB is like:
[148 => object, 155 => object, 133 => object]
I want to create an array like this in JS with the order that it has (the position come from DB and it has to be that order). Is it possible?
<?php echo json_encode($array)?>
Since the array is sparse, this resolves to
{"148":"Plane","149":"Car"}
which is an object and object property order is not guaranteed in JS.
http://php.net/manual/en/function.json-encode.php
Note:
When encoding an array, if the keys are not a continuous numeric sequence starting from 0, all keys are encoded as strings, and specified explicitly for each key-value pair.
You can solve this by creating an array from the object, like this:
var obj = <?php echo json_encode($array)?>; // note, eval not needed
var arr = [];
Object.keys(obj).forEach(function(key) {
arr[key] = obj[key];
});
Concerning the update:
You need to save the order of the keys separately.
var order = <?php echo json_encode(array_keys($array))?>;
var obj = <?php echo json_encode($array)?>;
order.forEach(function(key) {
console.log(key, obj[key]); // or whatever you need
});
You can even construct an ordered map (which PHP's arrays actually are, unlike the arrays in JS) if you use ES6 or a polyfill.
The earlier posters have already answered the question. Just to add to it:
Many people get confused because they think of Javascript Objects as associative arrays in PHP. However that is quite not the case. While its true that we can (sort of) simulate a data structure close to a PHP associative array by using objects in Javascript, they are totally different data structures and do not work quite the same way as arrays do.
In arrays the integrity of index position is important from a data structure and index relation perspective, which is why their order is maintained. However the same rule does not matter to objects since their "pseudo-named-index" (which really is just the property name), is not place-dependent. It can exist in any order as long as that property still has the same value assigned to it.
Hope this helps.
There are two types of JSON data structures you should distinguish here. Make sure the JSON parser is putting your data into the structure you want. I'd suggest it's probably putting it into an object, not an array.
Plagiarizing directly from this answer: From RFC 7159 -The JavaScript Object Notation (JSON) Data Interchange Format (emphasis mine):
An object is an unordered collection of zero or more name/value pairs, where a name is a string and a value is a string, number, boolean, null, object, or array.
An array is an ordered sequence of zero or more values.
The terms "object" and "array" come from the conventions of JavaScript.
And further quoting from this answer:
The order of elements in an array ([]) is maintained. The order of elements (name:value pairs) in an "object" ({}) is not, and it's usual for them to be "jumbled", if not by the JSON formatter/parser itself then by the language-specific objects (Dictionary, NSDictionary, Hashtable, etc) that are used as an internal representation.

Deserializing JavaScript object instance

I am working on an app that heavily uses JavaScript. I am attempting to include some object-oriented practices. In this attempt, I have created a basic class like such:
function Item() { this.init(); }
Item.prototype = {
init: function () {
this.data = {
id: 0,
name: "",
description: ""
}
},
save: function() {
alert("Saving...");
$.ajax({
url: getUrl(),
type: "POST",
data: JSON.stringify(this.data),
contentType: "application/json"
});
}
}
I am creating Item instances in my app and then saving them to local storage like such:
Item item = new Item();
window.localStorage.setItem("itemKey", JSON.stringify(item));
On another page, or at another time, I am retriving that item from local storage like such:
var item = window.localStorage.getItem("itemKey");
item = JSON.parse(item);
item.save();
Unfortunately, the "save" function does not seem to get reached. In the console window, there is an error that says:
*save_Click
(anonymous function)
onclick*
I have a hunch that the "(anonymous function)" is the console window's way of saying "calling item.save(), but item is an anonymous type, so I am trying to access an anonymous function". My problem is, I'm not sure how to convert "var item" into an Item class instance again. Can someone please show me?
Short answer:
Functions cannot be serialized into JSON.
Explanation:
JSON is a cross-platform serialization scheme based on a subset of JS literal syntax. This being the case, it can only store certain things. Per http://www.json.org/ :
Objects: An object is an unordered set of name/value pairs. An object begins with { (left brace) and ends with } (right brace). Each name is followed by : (colon) and the name/value pairs are separated by , (comma).
Arrays: An array is an ordered collection of values. An array begins with [ (left bracket) and ends with ] (right bracket). Values are separated by , (comma).
values: A value can be a string in double quotes, or a number, or true or false or null, or an object or an array. These structures can be nested.
Functions cannot be serialized into JSON because another non-JS platform would not be able to unserialize and use it. Consider the example in reverse. Say I had a PHP object at my server which contained properties and methods. If I serialized that object with PHP's json_encode() and methods were included in the output, how would my JavaScript ever be able to parse and understand PHP code in the methods, let alone use those methods?
What you are seeing in your resulting JSON is the toString() value of the function on the platform you're using. The JSON serilizer calls toString() on anything being serialized which isn't proper for JSON.
I believe your solution is to stop storing instances in JSON/local storage. Rather, save pertinent data for an instance which you set back to a new instance when you need.
I know this question is answered already, however I stumbled upon this by accident and wanted to share a solution to this problem, if anyone is interested.
instead of doing this:
var item = window.localStorage.getItem("itemKey");
item = JSON.parse(item);
item.save();
do something like this:
// get serialized JSON
var itemData = window.localStorage.getItem("itemKey");
//instantiate new Item object
var item = new Item();
// extend item with data
$.extend(item, JSON.parse(itemData));
// this should now work
item.save();
this will work so long as the function you are wanting to call (ie, save()) is prototypal and not an instance method (often times the case, and is indeed the case in the OP's original question.
the $.extend method is a utility method of jquery, but it is trivial to roll your own.
You cant do that, how can javascript possibly knows that item have a save function ? json doesnt allow functions as datas. just read the json spec , you cant save functions.
what you need to do is to create a serialize and deserialize method in the hash you want to stock. that will specifiy what to export and how you can "wake up" an object after parsing the corresponding json string.
You can only store plain Objects in DOMstorages (cookies, urlparams..., everything that needs [de]serialisation through JSON.stringify/JSON.parse). So what you did when sending the ajax data
ajaxsend(this.data);
also applies to string serialisation. You can only store the data, not the instance attributes (like prototype, constructor etc.). So use
savestring(JSON.stringify(item.data));
which is possible because item.data is such a plain Object. And when restoring it, you will only get that plain data Object back. In your case it's easy to reconstruct a Item instance from plain data, because your Items hold their values (only) in a public available property:
var item = new Item;
item.data = JSON.parse(getjsonstring());
Disclaimer
Not a full time time J.S. Developer, answer may have some minor bugs:
Long Boring Explanation
As mentioned by #JAAulde, your object cannot be serialized into JSON, because has functions, the technique that you are using doesn't allow it.
Many people forget or ignore that the objects that are used in an application, may not be exactly the same as saved / restored from storage.
Short & quick Answer
Since you already encapsulate the data members of your object into a single field,
you may want to try something like this:
// create J.S. object from prototype
Item item = new Item();
// assign values as you app. logic requires
item.data.name = "John Doe";
item.data.description = "Cool developer, office ladies, love him";
// encoded item into a JSON style string, not stored yet
var encodedItem = JSON.stringify(item.data)
// store string as a JSON string
window.localStorage.setItem("itemKey", encodedItem);
// do several stuff
// recover item from storage as JSON encoded string
var encodedItem = window.localStorage.getItem("itemKey");
// transform into J.S. object
item.data = JSON.parse(encodedItem);
// do other stuff
Cheers.

Convert a javascript associative array into json object using stringify and vice versa

I have a javascript associative array like one below
var my_cars= new Array()
my_cars["cool"]="Mustang";
my_cars["family"]="Station Wagon";
my_cars["big"]="SUV";
I want to convert it using Stringify to json object. I want to know after conversion how the json object will look like.
Also when i have this object How I can convert it back to associative array again.
First of all, by making my_cars an array and stringifying it, you don't get what you expect.
var my_cars= new Array()
my_cars["cool"]="Mustang";
my_cars["family"]="Station Wagon";
my_cars["big"]="SUV";
alert(JSON.stringify(my_cars));
This alerts [].
What you want is to start with {}:
var my_cars= {};
my_cars["cool"]="Mustang";
my_cars["family"]="Station Wagon";
my_cars["big"]="SUV";
alert(JSON.stringify(my_cars));
This alerts
{"cool":"Mustang","family":"Station Wagon","big":"SUV"}
To get your object back from the string, use JSON.parse().
var s = JSON.stringify(my_cars);
var c = JSON.parse(s);
alert(c.cool);
This alerts "Mustang".
See http://jsfiddle.net/Y2De9/
No,But the user want to use array not json.
Normal JavaScript arrays are designed to hold data with numeric indexes. You can stuff named keys on to them (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.
If you want named keys, use an Object, not an Array.
*source
var test = []; // Object
test[0] = 'test'; //this will be stringified
Now if you want key value pair inside the array
test[1] = {}; // Array
test[1]['b']='item';
var json = JSON.stringify(test);
output
"["test",{"b":"item"}]"
so you can use an index with array,so alternatively
var my_cars= [];
my_cars[0]={};
my_cars[0]["cool"]="Mustang";
my_cars[1]={};
my_cars[1]["family"]="Station Wagon";
my_cars[2]={};
my_cars[2]["big"]="SUV";
console.log(JSON.stringify(my_cars));
Output
"[{"cool":"Mustang"},{"family":"Station Wagon"},{"big":"SUV"}]"
Moving my comment into an answer so I can show you a code example.
These types of array are no-no's in javascript. You should ONLY use an object for non-numeric keys like this. Array indexes should be numbers. Javascript objects can use arbitrary values for keys (like in your example). Arrays happen to "appear" to work because Arrays themselves are objects, but you will not find normal Array methods will work on them. For example, look at this code example.
var my_cars= new Array()
my_cars["cool"]="Mustang";
my_cars["family"]="Station Wagon";
my_cars["big"]="SUV";
alert(my_cars.length); // alerts 0
You have only added properties to the underlying object, not actually added elements to the Array. You should use an Object for this, not an Array. Javascript does not actually have an Associative Array. It has an Object who's properties can often be used like one would use an Associate Array in other languages. But, it's an Object, not an Array.
"JavaScript does not support arrays with named indexes"
The most close state to an associative array is an array with entries converted to properties (as in your case), so I provide a solution for this exact case.
The fun thing is that Chrome's console makes it feel like an associative array: ["cool":"Mustang", "family":"Station Wagon", "big":"SUV"] (Check with F12)
NOTE: open browser's console before running the snippet
var my_cars= new Array()
my_cars["cool"]="Mustang";
my_cars["family"]="Station Wagon";
my_cars["big"]="SUV";
let toAssociative=(keys, values)=>
values.reduce((acc, cv)=>{
acc[acc.shift()]=cv
return acc;
}, keys)
let fromAssociative = (assArr)=>({...assArr})
let serialized = JSON.stringify(fromAssociative(my_cars))
let o = JSON.parse(serialized)
let restored = toAssociative(Object.keys(o) , Object.values(o))
//NOTE: Look at the browser's console before executing (not SO console)
console.log("orig:",my_cars)
//[cool: "Mustang", family: "Station Wagon", big: "SUV"]
console.log("serialized:",serialized)
//{"cool":"Mustang","family":"Station Wagon","big":"SUV"}
console.log("restored:",restored) //NOTE: look at the browser's console (F12)
//[cool: "Mustang", family: "Station Wagon", big: "SUV"]
If for some reason you cannot convert your array into object, for instance you are working on a big framework or legacy code that you dont want to touch and your job is only to add som feature which requires JSON API use, you should consider using JSON.stringify(json,function(k,v){}) version of the API.
In the function you can now decide what to do with value of key is of a specific type.

Categories

Resources