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));
Related
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});
I have taken a string that is "title:artist" and used str.split :
res = song.split(":");
Which gives me an output of :
["Ruby","Kaiser Chiefs"]
I was wondering how I could add name to this so that it appears as :
["name":"Ruby", "artist":"Kaiser Chiefs"]
var res = song.split(':');
var jsonString = JSON.stringify({ name: res[0], artist: res[1] });
You can find more information about how to use JSON.stringify here but basically what it does is takes a JavaScript object (see how I'm passing the data as an object in my answer) and serializes it into a JSON string.
Be aware that the output is not exactly as you have described in your question. What you have is both invalid JavaScript and invalid JSON. The output that I have provided will look more along the lines of {"name":"Ruby", "artist":"Kaiser Chiefs"}. Notice how there is {} instead of [].
["name":"Ruby", "artist":"Kaiser Chiefs"] isn't a valid format I guess you want to create an object so you could use just the split like :
var my_string = "Ruby:Kaiser Chiefs";
var my_string_arr = my_string.split(':');
var my_object = {'name': my_string_arr[0],"artist": my_string_arr[1]};
console.log(my_object);
Or also assign the values to the attributes separately like:
var my_string = "Ruby:Kaiser Chiefs";
var my_string_arr = my_string.split(':');
var my_object = {};
my_object.name = my_string_arr[0];
my_object.artist = my_string_arr[1];
console.log(my_object);
Hope this helps.
What you're looking for is: Object. Here is how you do it:
var str = "Ruby:Kaiser Chiefs";
var res = str.split(':');
// this is how to declare an object
var myObj = {};
// this is one way to assigne to an object
// using: myObj["key"] = value;
myObj["name"] = res[0];
// this is another way to assign to an object
// using: myObj.key = value;
myObj.artist = res[1];
console.log(myObj);
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"}
I need implement this in one line, if possible:
I have an object
var object1 = {};
object1['key_1'] = "value_1";
object1['key_2'] = "value_2";
object1['key_3'] = "value_3";
I need pass to an function one item from object (not only value ), key - only string value
for (var key in object1)
FunctionTemp({key:object1[key]}); // - this don't work as I need, and eval() method I don't want
maybe there is something like this
FunctionTemp((new {})[key]=object1[key]) - its don't work!!! :)
Since you really want it in one line you can do it like this:
var temp;
for (var key in object1)
FunctionTemp(((temp = {}) && (temp[key] = object1[key]))? temp: null);
but I think it is no longer readable as it is, the most ideal solution would be to break it down into several lines.
var temp;
for (var key in object1) {
temp = {};
temp[key] = object1[key];
FunctionTemp(temp);
}
What you're asking for is not possible without a function.
What you want to do is this:
var key = getKey(); //some means of determining a key dynamically
var val = getVal(); //some means of determining a value dynamically
var obj = {};
obj[key] = val;
this.doSomething(obj);
What you need is another method that assembles the object based on the dynamic key/value.
this.doSomething(_.object([[getKey(), getVal()]]));
Im using this 'map' on js:
var myMap = new Object();
myMap[key1]=value1; //like this n times...
but i want to use the key as some combination of two strings meaning:
function getMapValue(str1,str2){...}
i dont mind joining the two strings into one long string and use the function with the long string
any ideas?
You can make a map of maps (just be sure to check that the intermediate map exists when accessing it)
var myMap = {}; //dont use "new Object()". It is evil.
function insert(k1, k2, v){
if(!(k1 in myMap)){ myMap[k1] = {}; }
myMap[k1][k2] = v;
}
function get(k1, k2){
return myMap[k1] && myMap[k1][k2];
}
And if you want to join two substrings into a single one you can use the plus operator to concatenate things.
var customKey = k1 + '|' + k2;
Just be sure your separator can't be used in a normal key to avoid conflicts.
If I got you right, the following should help:
var myMap = {"key1" : "something1", "key2" : "something2"};
to get value for a key, you you use, either: return myMap.key1;
Or: return myMap.["key1"];
If you had/did: myMap["key1key2"] = "MagicHappens!";
you could use myMap.key1key2 to get the value or myMap["key1key2"], or even: return myMap["key1"+"key2"];
Or:
var x = "key1";
var y = "key2";
return myMap[x+y];
in your getter function, you get the two variables for the keys which you can then directly use.