Instead of going JSON a json string and using $.parseJSON, I need to take my object and store it in a variable as string representing JSON.
(A library I'm dealing with expects a malformed JSON type so I need to mess around with it to get it to work.)
What's the best way to do this?
Edit: You should use the json2.js library from Douglas Crockford instead of implementing the code below. It provides some extra features and better/older browser support.
Grab the json2.js file from: https://github.com/douglascrockford/JSON-js
// implement JSON.stringify serialization
JSON.stringify = JSON.stringify || function (obj) {
var t = typeof (obj);
if (t != "object" || obj === null) {
// simple data type
if (t == "string") obj = '"'+obj+'"';
return String(obj);
}
else {
// recurse array or object
var n, v, json = [], arr = (obj && obj.constructor == Array);
for (n in obj) {
v = obj[n]; t = typeof(v);
if (t == "string") v = '"'+v+'"';
else if (t == "object" && v !== null) v = JSON.stringify(v);
json.push((arr ? "" : '"' + n + '":') + String(v));
}
return (arr ? "[" : "{") + String(json) + (arr ? "]" : "}");
}
};
var tmp = {one: 1, two: "2"};
JSON.stringify(tmp); // '{"one":1,"two":"2"}'
Code from: http://www.sitepoint.com/blogs/2009/08/19/javascript-json-serialization/
I use
$.param(jsonObj)
which gets me the string.
Most browsers have a native JSON object these days, which includes parse and stringify methods. So just try JSON.stringify({}) and see if you get "{}". You can even pass in parameters to filter out keys or to do pretty-printing, e.g. JSON.stringify({a:1,b:2}, null, 2) puts a newline and 2 spaces in front of each key.
JSON.stringify({a:1,b:2}, null, 2)
gives
"{\n \"a\": 1,\n \"b\": 2\n}"
which prints as
{
"a": 1,
"b": 2
}
As for the messing around part of your question, use the second parameter. From http://www.javascriptkit.com/jsref/json.shtml :
The replacer parameter can either be a function or an array of
String/Numbers. It steps through each member within the JSON object to
let you decide what value each member should be changed to. As a
function it can return:
A number, string, or Boolean, which replaces the property's original value with the returned one.
An object, which is serialized then returned. Object methods or functions are not allowed, and are removed instead.
Null, which causes the property to be removed.
As an array, the values defined inside it corresponds to the names of
the properties inside the JSON object that should be retained when
converted into a JSON object.
The best way I have found is to use jQuery JSON
You could parse the JSON to an object, then create your malformed JSON from the ajavscript object. This may not be the best performance-wise, tho.
Otherwise, if you only need to make very small changes to the string, just treat it as a string, and mangle it using standard javascript.
Related
I have a an object jsonRes[0] containing values which need to be removed based on a condition. The following works to remove null, missing values and those equal to zero in the stringified object:
function replacer(key, value) {
// Filtering out properties
if (value === null || value === 0 || value === "") {
return undefined;
}
return value;
}
JSON.stringify(jsonRes[0], replacer, "\t")
However, when I add a condition using the the includes method, I receive an error:
function replacer(key, value) {
// Filtering out properties
if (value === null || value === 0 || value === "" || value.includes("$")) {
return undefined;
}
return value;
}
Uncaught TypeError: value.includes is not a function
Why is this the case and is there a workaround?
You can use String.indexOf() instead of String.includes, As it is available in ES6 and not supported in IE at all.
typeof value == "string" && value.indexOf('$') > -1
Also note if value is not string type it will still raise an error boolean, Number doesn't the the method. You can use typeof to validate whether value is a string.
The .includes() API is part of the String and Array data type.
So what the error is trying to tell you is that the value for variable value, e.g. an integer or object, does not have the property .includes.
You could do checks like
typeof a_string === 'string'
an_array instanceof Array
before the .includes() api to prevent this.
Obviously this will make your if statement rather ugly due to the number of checks you have.
Based on the way your code is written I suspect you are more interested in checking "String" than array. So becareful of arrays. Your code may not work properly if it is array.
Anyway here is a refractored version of your code.
function replacer(key, value) {
// Filtering out properties
if (!value || typeof value === "string" && value.includes("$")) {
return undefined;
}
return value;
}
console.log("NULL returns:" + replacer('test', null));
console.log("$Test returns:" + replacer('test', '$test'));
console.log("Blah returns:" + replacer('test', 'Blah'));
Just one more possibility: Maybe your value is not a string type object.
(typeof(value) == "string" && value.includes("$"))
I solved this error, which I was getting when applying "includes" to a "window.location" value, by appending ".toString();"
var requestUrl = window.location.toString();
if (requestUrl.includes(urlBase + "#")) {
...
I actually am not sure what type of the variable named value is, but anyway, Array.prototype.includes and String.prototype.includes are only available in ES6. You need to use babel-polyfill or any other bundling modules like rollup.js, webpack with babel or something like that to use includes function.
I have a JSON object formatted like {"Foo": ["B","A","R"]}
I am trying to access the values of the array like this:
var json = '{"Foo": ["B","A","R"]}';
expression = JSON.Parse(json, function(key, value){
if(key == "Foo"){
console.log(value.length); // logs "3"
console.log(value[1]); // logs "undefined"
}
});
If I ask for the length of value it returns the correct length of the array, but if I ask for the value it returns undefined and I am not quite sure why.There are other values in the JSON that I am able to access just fine, but they are not arrays. Any insight would be appreciated. Thanks!
You should use JSON.parse like this:
var json = '{"Foo":["B","A","R"]}';
var object = JSON.parse(json);
// object is now and object containing the data from 'json'
var expression = object["Foo"][1]; // object["Foo"] refers to the
// value with key "Foo"
(Calling JSON.parse with a callback parameter is an advanced feature for transforming the JSON object, not reading it. In almost all cases, though, you want to use it like the above code, with no callbacks.)
As mentioned in another answer, if you simply want to retrieve the second element of Foo, you can do that easily enough after parsing using standard property access techniques such as obj.Foo[1].
Assuming you really want to use the optional second "reviver" parameter to JSON.parse, you need to return the value from the "reviver" callback;
expression = JSON.Parse(json, function(key, value){
if (key == "Foo"){
console.log(value[1]);
}
return value;
^^^^^^^^^^^^^
});
The reason it appears you can't access value[1] but you can access value.length is (as mentioned by user663031) you don't have a return value.
The reviver function replaces one value with another, if no return is specified all functions will return undefined. The order the reviver receives the values is: first each of the values in the array separately, then the array.
In your code each value has already been replaced with "undefined", so the array has three undefined values as reported by the length. value[1] really is returning the value at position 1 but it is set to "undefined".
When the json string has arrays the reviver function is called with index, [Object] as key, value parameters .
This sniped of code that filter object properties on parse phase will be helpful:
var json = '{"_embedded": [{"a":"A","b":"B","links": {"c":"C"}},{"a":"A2", "b":"B2","links": {"c":"C2"}}]}';
var schemaNames=["_embedded", "a"];
var result= JSON.parse(json, function(k, v) {
console.log(k,v);
if ("" === k){
return v;
}
// On arrays k is a number
else if (schemaNames.indexOf(k) > -1 || !isNaN(k)){
return v;
}
});
console.log(JSON.stringify(result));
Output: {"_embedded":[{"a":"A"},{"a":"A2"}]}
https://jsfiddle.net/pdorgambide/vphbmtk1/
use this code
var json = {'foo' : ['B', 'A', 'R']};
$.each(json, function(key, value){if(key == 'foo'){console.log(value[1]);}});
you already have a json object so no need to parse it again.
I just start learning JavaScript and I faced with problem: I don't know how to check what exactly I can do with my variables (for example, how I can manage string or array). In Python there are very useful methods dir() and help() that allow user to get list of all applicable methods and find out how to use them:
>>>my_number = 1
>>>dir(my_number)
This will return
['bit_length', 'conjugate', 'denominator', 'from_bytes', 'imag', 'numerator', 'real', 'to_bytes']
the list of methods I can apply to my_number variable
Then I can get description of each method:
>>>help(my_number.real)
Help on int object:
class int(object)
| int(x=0) -> integer
| int(x, base=10) -> integer
|
| Convert a number or string to an integer, or return 0 if no arguments
| are given. If x is a number, return x.__int__(). For floating point
| numbers, this truncates towards zero...
So is there any similar function in JavaScript so I can call it like console.log(getAllMethodsFor(myNumber)) ? This could significantly simplify process of language learning...
you can get the properties of a variable and check if the typeof property is a function
function getAllFunctions(myvar)
{
var allMethods = [];
for( var property in myvar)
{
if (typeof myvar[property] == "function")
{
allMethods.push(property);
}
}
return allMethods ;
}
Nothing built-in, but easy to write:
function dir(obj) {
if(obj === null)
return [];
var uniq = a => a.filter((x, i) => a.indexOf(x) === i);
return uniq(dir(Object.getPrototypeOf(obj)).concat(
Object.getOwnPropertyNames(obj).filter(p => typeof obj[p] === 'function')
));
}
document.write(dir(1))
document.write("<hr>");
document.write(dir("abc"))
Regarding help, there's no such thing either, but typing mdn <method name> in google usually does the trick.
There is no such thing by default, but you could write one simply by iterating the properties of the given object:
for (var prop in obj) {
if (typeof obj[prop] == 'function') {
console.log(prop);
}
}
Having said that, that's still missing the integrated docstrings for help(). Typically in Javascript development you're reading the (hopefully) accompanying documentation and/or use an interactive console like Chrome's Web Inspector to inspect objects in a more GUI-like manner.
I have a string variable that is a string representation of an object. Like this:
{
"column": "'asdf'",
"sort": "true",
"search": "{\"asdf\":\"searchval\"}"
}
I would like to transform the above string into an object that looks like this:
{
column: 'asdf',
sort: 'true',
search: {
asdf: 'searchval'
}
}
I am planning on doing a search and replace regex expression for quotes and back slashes, and then using eval(), but that seems unsafe and innefficient. Is there an alternative method that would work better?
I am planning on assigning the object value of the string to an object variable.
Have you tried JSON.parse(); yet?
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse
var myOriginalData = JSON.stringify({"column": "'asdf'","sort": "true","search": "{\"asdf\":\"searchval\"}"});
myNewData = JSON.parse(myOriginalData, function (key, value) {
var type;
if (value && typeof value === 'object') {
type = value.type;
if (typeof type === 'string' && typeof window[type] === 'function') {
return new (window[type])(value);
}
}
return value;
});
console.log('myNewData -----------------------------------------------------------');
console.log(myNewData);
Working Example: http://plnkr.co/edit/2jLGIxx3AVEceVQsOpxL?p=preview
Immediately after posting this, I found out there is a JSON.parse(); function. The only reason I don't delete the question, is it might save someone time later.
All you need to do is pass the string variable as a parameter and it will output an object.
If anyone sees any problems with this solution, or knows a better solution, please make an answer!
There seems to have many question asked similar on counting number of element already but I am failing to implement them with mine problem.
After jquery ajax I get JSON data returned which looks something like this
Object {0: Object, 1: Object , xxxx:"asdf" ,yyyy:"asdf", zzzz:"asdf"}
I want to get number of object between this { } braces ( not counting those xxx,yyy element )
I tried .length which doesn't work
I also tried using this Length of a JavaScript object but that return the number of element in each object. I just want the number of object
Thank You
Try this:
var json = { 0: {}, 1: {}, xxxx: "asdf", yyyy: "asdf", zzzz: "asdf" };
function typeOf( obj ) {
return ({}).toString.call( obj )
.match(/\s([a-zA-Z]+)/)[1].toLowerCase();
}
var total = 0;
for ( var o in json ) {
if ( typeOf( json[o] ) == 'object' ) {
total++;
}
}
console.log( total ); //=> 2
Everything is an object in JavaScript. The typeof operator is misleading and won't work in this case. You can use the typeOf function above that I extracted from this blog post: Fixing the JavaScript typeof operator (worth reading). There are other ways of doing it but this seems like the most straightforward.
If it's not just a coincidence that the objects are the ones with numeric property names, and the numeric properties count up sequentially, you could do something like this:
var obj = { /* your object here */ }
for (var i=0; i in obj; i++) {
// use obj[i] for something
}
// i is now equal to the number of numeric properties
This works because as soon as i is high enough that you've run out of properties the in operator will return false. Feel free to use .hasOwnProperty() instead if you prefer.
Obviously this is a specialised solution that doesn't test the type of the different properties at all. (To actually test the type see elclanrs' solution - and either way read the page he linked to.)
Say that the entire json is in a variable called json:
var total_objects = 0;
$.each(json, function () {
if (typeof this == 'object') {
total_objects++;
}
});
However, I am curious as to why you would need to know this.
You can use a customized version from the code of this question Length of Javascript Object (ie. Associative Array) and check for element's type using typeof operator and count only those which are an object (or an array).
Object.sizeObj = function(obj) {
var size = 0, key;
for (key in obj) {
if (typeof key[obj] === 'object' && obj.hasOwnProperty(key)) size++;
}
return size;
};
// Get the count of those elements which are an object
var objectsCount = Object.sizeObj(myArray);