json string containing function calls - javascript

for example my json string is like this :
{
"v1" : [],
"v2": 2,
"v3": f()
}
Now the context in which I need to decode this has a definition of f and f() gives right answer in that context(checked via debugger). But JSON.parse(jsonstring) gives me Unexpected token. eval also gives error. What should I do?
See an example Here

Why it does not work
Look at the definition of a JSON, it can not contain function calls.
Possible workarounds
One way is to do something like this, return a string of the function you want to call.
{
"v1" : [],
"v2": 2,
"v3": "f"
}
Now when you need to access it, you can call the function.
var myJSON = JSON.parse(jsonstring);
var myFunctionResult = window[myJSON.v3](); //works if global variable
Other option is to change how your code works and make an async script call [jQuery would be getScript, regular JavaScript createElement("script") with appendChild() and use a callback like JSONP does.

JSON strings cannot contain functions.
JSON is not the same things as a JavaScript object, even though the former is derived from the latter. Ultimately, it is a string.

You should not use any callbacks or function calls in JSON (It is not valid JSON, it is insecure and it is absurd - two last things if you somehow make it work) , there is always way to do it in script.
EDIT: You REALLY don't need to call function from JSON - please return back to "drawing board" and design app to not use this pattern

Related

trying to access object property makes it empty - javascript [duplicate]

Below, you can see the output from these two logs. The first clearly shows the full object with the property I'm trying to access, but on the very next line of code, I can't access it with config.col_id_3 (see the "undefined" in the screenshot?). Can anyone explain this? I can get access to every other property except field_id_4 as well.
console.log(config);
console.log(config.col_id_3);
This is what these lines print in Console
The output of console.log(anObject) is misleading; the state of the object displayed is only resolved when you expand the Object tree displayed in the console, by clicking on >. It is not the state of the object when you console.log'd the object.
Instead, try console.log(Object.keys(config)), or even console.log(JSON.stringify(config)) and you will see the keys, or the state of the object at the time you called console.log.
You will (usually) find the keys are being added after your console.log call.
I've just had this issue with a document loaded from MongoDB using Mongoose.
When running console.log() on the whole object, all the document fields (as stored in the db) would show up. However some individual property accessors would return undefined, when others (including _id) worked fine.
Turned out that property accessors only works for those fields specified in my mongoose.Schema(...) definition, whereas console.log() and JSON.stringify() returns all fields stored in the db.
Solution (if you're using Mongoose): make sure all your db fields are defined in mongoose.Schema(...).
Check if inside the object there's an array of objects. I had a similar issue with a JSON:
"terms": {
"category": [
{
"ID": 4,
"name": "Cirugia",
"slug": "cirugia",
"description": "",
"taxonomy": "category",
"parent": null,
"count": 68,
"link": "http://distritocuatro.mx/enarm/category/cirugia/"
}
]
}
I tried to access the 'name' key from 'category' and I got the undefined error, because I was using:
var_name = obj_array.terms.category.name
Then I realised it has got square brackets, that means that it has an array of objects inside the category key, because it can have more than one category object. So, in order to get the 'name' key I used this:
var_name = obj_array.terms.category[0].name
And That does the trick.
Maybe it's too late for this answer, but I hope someone with the same problem will find this as I did before finding the Solution :)
I had the same issue. Solution for me was using the stringified output as input to parsing the JSON. this worked for me. hope its useful to you
var x =JSON.parse(JSON.stringify(obj));
console.log(x.property_actually_now_defined);
The property you're trying to access might not exist yet. Console.log works because it executes after a small delay, but that isn't the case for the rest of your code. Try this:
var a = config.col_id_3; //undefined
setTimeout(function()
{
var a = config.col_id_3; //voila!
}, 100);
In my case I was passing an object to a promise, within the promise I was adding more key/values to the object and when it was done the promise returned the object.
However, a slight over look on my part, the promise was returning the object before it was fully finished...thus the rest of my code was trying to process the updated object and the data wasn't yet there. But like above, in the console, I saw the object fully updated but wasn't able to access the keys - they were coming back undefined. Until I saw this:
console.log(obj) ;
console.log(obj.newKey1) ;
// returned in console
> Object { origKey1: "blah", origKey2: "blah blah"} [i]
origKey1: "blah"
origKey2: "blah blah"
newKey1: "this info"
newKey2: "that info"
newKey3: " more info"
> *undefined*
The [i] is a little icon, when I hovered over it it said Object value at left was snapshotted when logged, value below was evaluated just now. Thats when it occurred to me that my object was being evaluated before the promise had fully updated it.
I just encountered this issue with objects generated by csv-parser from a CSV file that was generated by MS Excel. I was able to access all properties except the first property - but it would show up ok if I wrote the whole object using console.log.
Turned out that the UTF-8 CSV format inserts 3 bytes (ef bb bf) at the start corresponding to an invisible character - which were being included as part of the first property header by csv-parser. Solution was to re-generate the CSV using the non-UTF option and this eliminated the invisible character.
I struggled with this issue today, and thought I'll leave a reply with my solution.
I was fetching a data object via ajax, something like this:
{"constants": {"value1":"x","value2":"y"},"i18n" {"data1":"x", "data2":"y"}}
Let's say this object is in a variable called data. Whenever I referenced data.i18n I got undefined.
console.log(data) showed the object as expected
console.log(Object.keys(data)) said ["constants","i18n"] as expected
Renaming i18n to inter didn't change anything
I even tried to switch the data to make "i18n" the first object
Moved code around to make absolutely sure the object was completely set and there was no problem with the ajax promise.
Nothing helped... Then on the server side I wrote the data to the php log, and it revealed this:
{"constants": {"value1":"x","value2":"y"},"\u045618n" {"data1":"x", "data2":"y"}}
The "i" in the index key was actually a u0456 (cyrillic i). This was not visible in my php editor or the browser console log. Only the php log revealed this... That was a tricky one...
My data was just json data string . (This variable was stored as json string in the session).
console.log(json_string_object)
-> returns just the representation of this string and there is no way to make difference whether is string or object.
So to make it work I just needed to convert it back to real object:
object = JSON.parse(json_string_object);
In 2018 Mozilla warns us in the Mozilla Docs here!
I quote "Logging Objects":
Don't use console.log(obj);,
use console.log(JSON.parse(JSON.stringify(obj)));.
This way you are sure you are seeing the value of obj at the moment
you log it.
If this is an issue occurring when working with Mongoose, the following may happen:
console.log(object)
returns everything, including the desired key.
console.log(object.key)
returns undefined.
If that is happening, it means that the key is missing from the Mongoose Schema. Adding it in will resolve the issue.
For me it turned out to be a Mongoose-related problem.
I was looping over objects that I got from a Mongo query. I just had to remove:
items = await Model.find()
And replace it by:
items = await Model.find().lean()
This might help somebody as I had a similar issue in which the JSON.parse() was returning an object that I could print on the console.log() but I couldn't acccess the specific fields and none of the above solution worked for me. Like using the combination of JSON.parse() with JSON.stringify().
var jsonObj = JSON.parse(JSON.stringify(responseText))
// where responseText is a JSON String returned by the server.
console.log(jsonObj) ///Was printing the object correctly
console.log(jsonObj.Body) /// Was printing Undefined
I ended up solving the problem by using a different parser provided by ExtJs Ext.decode();
var jsonObj = Ext.decode(responseText)
console.log(jsonObj.Body) //Worked...
I had the same issue and no solution above worked for me and it sort of felt like guess work thereafter. However, wrapping my code which creates the object in a setTimeout function did the trick for me.
setTimeout(function() {
var myObj = xyz; //some code for creation of complex object like above
console.log(myObj); // this works
console.log(myObj.propertyName); // this works too
});
I've just had the same issue with a document loaded from MongoDB using Mongoose.
Turned out that i'm using the property find() to return just one object, so i changed find() to findOne() and everything worked for me.
Solution (if you're using Mongoose): Make sure to return one object only, so you can parse its object.id or it will be treated as an array so you need to acces it like that object[0].id.
In My case, it just happens to be that even though i receive the data in the format of a model like myMethod(data:MyModelClass) object till the received object was of type string.
Which is y in console.log(data) i get the content.
Solution is just to parse the JSON(in my case)
const model:MyMOdelClass=JSON.parse(data);
Thought may be usefull.
I've had similar issue, hope the following solution helps someone.
You can use setTimeout function as some guys here suggesting, but you never know how exactly long does your browser need to get your object defined.
Out of that I'd suggest using setInterval function instead. It will wait until your object config.col_id_3 gets defined and then fire your next code part that requires your specific object properties.
window.addEventListener('load', function(){
var fileInterval = setInterval(function() {
if (typeof config.col_id_3 !== 'undefined') {
// do your stuff here
clearInterval(fileInterval); // clear interval
}
}, 100); // check every 100ms
});
if you're using TYPESCRIPT and/or ANGULAR, it could be this!
.then((res: any) => res.json())
setting the response type to any fixed this issue for me, I couldn't access properties on the response until i set res: any
see this question Property '_body' does not exist on type 'Response'
I had a similar issue or maybe just related.
For my case I was accessing properties of an object but one was undefined. I found the problem was a white-space in the server side code while creating the key,val of the object.
My approach was as follows...
After removing the white-space from the server-side code creating the object, I could now access the property as below...
This might not be the issue with the case of the subject question but was for my case and may be so for some one else. Hope it helps.
I just encountered this issue as well, and long story short my API was returning a string type and not JSON. So it looked exactly the same when you printed it to the log however whenever I tried to access the properties it gave me an undefined error.
API Code:
var response = JsonConvert.DeserializeObject<StatusResult>(string Of object);
return Json(response);
previously I was just returning:
return Json(string Of object);
First thing check the type like below:
console.log(typeof config);
If the command above prints object then it is very easy you just use the bracket notation. Bracket notation can be quite useful if you want to search for a property’s values dynamically.
Execute the command below:
console.log(config[col_id_3]);
If it a string you need to parse in object first. To do that you need to execute the command below:
var object = JSON.parse(config);
And after that use bracket notation to access the property like below:
console.log(object[col_id_3]);
I had an issue like this, and found the solution was to do with Underscore.js. My initial logging made no sense:
console.log(JSON.stringify(obj, null, 2));
> {
> "code": "foo"
> }
console.log(obj.code);
> undefined
I found the solution by also looking at the keys of the object:
console.log(JSON.stringify(Object.keys(obj)));
> ["_wrapped","_chain"]
This lead me to realise that obj was actually an Underscore.js wrapper around an object, and the initial debugging was lying to me.
I had similar problem (when developing for SugarCRM), where I start with:
var leadBean = app.data.createBean('Leads', {id: this.model.attributes.parent_id});
// This should load object with attributes
leadBean.fetch();
// Here were my attributes filled in with proper values including name
console.log(leadBean);
// Printed "undefined"
console.log(leadBean.attributes.name);
Problem was in fetch(), its async call so I had to rewrite my code into:
var leadBean = app.data.createBean('Leads', {id: this.model.attributes.parent_id});
// This should load object with attributes
leadBean.fetch({
success: function (lead) {
// Printed my value correctly
console.log(lead.attributes.name);
}
});
Just in case this is helpful for someone, I had a similar problem, and it's because someone created an override for .toJSON in the object I was working with. So the object was something like:
{
foo: {
bar: "Hello"
baz: "World"
}
}
But .toJSON() was:
toJSON() {
return this.foo
}
So when I called JSON.stringify(myObject) it returned "{"bar": "Hello", "baz": "World"}". However, Object.keys(myObject) revealed the "foo".
I faced the same problem today. In my case the keys were nested, i.e key1.key2.
I split the keys using split() and then used the square bracket notation, which did work for me.
var data = {
key1: {
key2: "some value"
}
}
I split the keys and used it like this, data[key1][key2] which did the job for me.
I had the same issue today. Problem was caused by uglify-js. After I executed same non-uglified code problem was solved. Removing of
--mangle-props
from uglify-js was enough to have working uglified code.
Perhaps, the best practice is to use some prefix for properties that has to be mangled with regex rule for uglify-js.
Here is the source:
var data = JSON.parse( content);
...
this.pageIndex = parseInt(data.index);
this.pageTotal = parseInt(data.total);
this.pageLimit = parseInt(data.limit);
and here is how it was uglified:
var n = JSON.parse( t);
...
this._ = parseInt(n.index), this.g = parseInt(n.total), this.D = parseInt(n.C)
None of the JSON stringify/parse worked for me.
formValues.myKey: undefined
formValues.myKey with timeout: content
I wanted the value of formValues.myKey and what did the trick was a setTimeout 0 like in the example below. Hope it helps.
console.log('formValues.myKey: ',formValues.myKey);
setTimeout( () => {
console.log('formValues.myKey with timeout: ', formValues.myKey);
}, 0 );
I had a similar issue today in React. Eventually realised that the problem was being caused by the state not being set yet. I was calling user.user.name and although it was showing up in the console, I couldn't seem to access it in my component till I included a check to check if user.user was set and then calling user.user.name.
Check whether you had applied any filters in the console. It happens to me in chrome console.
I also had this frustrating problem, I tried the setTimeout() and the JSON.stringify and JSON.parse solutions even if I knew it wouldn't work as I think they're mostly JSON or Promise related problems, sure enough it didn't work. In my case though, I didn't notice immediately that it was a silly mistake. I was actually accessing a property name with a different casing. It's something like this:
const wrongPropName = "SomeProperty"; // upper case "S"
const correctPropName = "someProperty"; // lower case "s"
const object = { someProperty: "hello world!" };
console.log('Accessing "SomeProperty":', object[wrongPropName]);
console.log('Accessing "someProperty":', object[correctPropName])
It took me a while to notice as the property names in my case can have either all lower case or some having mixed case. It turned out that a function in my web application has something that makes a mess of my property names (it has a .toLowerCase() next to the generated key names 🤣).
So, lesson learned, check property name casing more properly.

parsing nested javascript objects [duplicate]

Below, you can see the output from these two logs. The first clearly shows the full object with the property I'm trying to access, but on the very next line of code, I can't access it with config.col_id_3 (see the "undefined" in the screenshot?). Can anyone explain this? I can get access to every other property except field_id_4 as well.
console.log(config);
console.log(config.col_id_3);
This is what these lines print in Console
The output of console.log(anObject) is misleading; the state of the object displayed is only resolved when you expand the Object tree displayed in the console, by clicking on >. It is not the state of the object when you console.log'd the object.
Instead, try console.log(Object.keys(config)), or even console.log(JSON.stringify(config)) and you will see the keys, or the state of the object at the time you called console.log.
You will (usually) find the keys are being added after your console.log call.
I've just had this issue with a document loaded from MongoDB using Mongoose.
When running console.log() on the whole object, all the document fields (as stored in the db) would show up. However some individual property accessors would return undefined, when others (including _id) worked fine.
Turned out that property accessors only works for those fields specified in my mongoose.Schema(...) definition, whereas console.log() and JSON.stringify() returns all fields stored in the db.
Solution (if you're using Mongoose): make sure all your db fields are defined in mongoose.Schema(...).
Check if inside the object there's an array of objects. I had a similar issue with a JSON:
"terms": {
"category": [
{
"ID": 4,
"name": "Cirugia",
"slug": "cirugia",
"description": "",
"taxonomy": "category",
"parent": null,
"count": 68,
"link": "http://distritocuatro.mx/enarm/category/cirugia/"
}
]
}
I tried to access the 'name' key from 'category' and I got the undefined error, because I was using:
var_name = obj_array.terms.category.name
Then I realised it has got square brackets, that means that it has an array of objects inside the category key, because it can have more than one category object. So, in order to get the 'name' key I used this:
var_name = obj_array.terms.category[0].name
And That does the trick.
Maybe it's too late for this answer, but I hope someone with the same problem will find this as I did before finding the Solution :)
I had the same issue. Solution for me was using the stringified output as input to parsing the JSON. this worked for me. hope its useful to you
var x =JSON.parse(JSON.stringify(obj));
console.log(x.property_actually_now_defined);
The property you're trying to access might not exist yet. Console.log works because it executes after a small delay, but that isn't the case for the rest of your code. Try this:
var a = config.col_id_3; //undefined
setTimeout(function()
{
var a = config.col_id_3; //voila!
}, 100);
In my case I was passing an object to a promise, within the promise I was adding more key/values to the object and when it was done the promise returned the object.
However, a slight over look on my part, the promise was returning the object before it was fully finished...thus the rest of my code was trying to process the updated object and the data wasn't yet there. But like above, in the console, I saw the object fully updated but wasn't able to access the keys - they were coming back undefined. Until I saw this:
console.log(obj) ;
console.log(obj.newKey1) ;
// returned in console
> Object { origKey1: "blah", origKey2: "blah blah"} [i]
origKey1: "blah"
origKey2: "blah blah"
newKey1: "this info"
newKey2: "that info"
newKey3: " more info"
> *undefined*
The [i] is a little icon, when I hovered over it it said Object value at left was snapshotted when logged, value below was evaluated just now. Thats when it occurred to me that my object was being evaluated before the promise had fully updated it.
I just encountered this issue with objects generated by csv-parser from a CSV file that was generated by MS Excel. I was able to access all properties except the first property - but it would show up ok if I wrote the whole object using console.log.
Turned out that the UTF-8 CSV format inserts 3 bytes (ef bb bf) at the start corresponding to an invisible character - which were being included as part of the first property header by csv-parser. Solution was to re-generate the CSV using the non-UTF option and this eliminated the invisible character.
I struggled with this issue today, and thought I'll leave a reply with my solution.
I was fetching a data object via ajax, something like this:
{"constants": {"value1":"x","value2":"y"},"i18n" {"data1":"x", "data2":"y"}}
Let's say this object is in a variable called data. Whenever I referenced data.i18n I got undefined.
console.log(data) showed the object as expected
console.log(Object.keys(data)) said ["constants","i18n"] as expected
Renaming i18n to inter didn't change anything
I even tried to switch the data to make "i18n" the first object
Moved code around to make absolutely sure the object was completely set and there was no problem with the ajax promise.
Nothing helped... Then on the server side I wrote the data to the php log, and it revealed this:
{"constants": {"value1":"x","value2":"y"},"\u045618n" {"data1":"x", "data2":"y"}}
The "i" in the index key was actually a u0456 (cyrillic i). This was not visible in my php editor or the browser console log. Only the php log revealed this... That was a tricky one...
My data was just json data string . (This variable was stored as json string in the session).
console.log(json_string_object)
-> returns just the representation of this string and there is no way to make difference whether is string or object.
So to make it work I just needed to convert it back to real object:
object = JSON.parse(json_string_object);
In 2018 Mozilla warns us in the Mozilla Docs here!
I quote "Logging Objects":
Don't use console.log(obj);,
use console.log(JSON.parse(JSON.stringify(obj)));.
This way you are sure you are seeing the value of obj at the moment
you log it.
If this is an issue occurring when working with Mongoose, the following may happen:
console.log(object)
returns everything, including the desired key.
console.log(object.key)
returns undefined.
If that is happening, it means that the key is missing from the Mongoose Schema. Adding it in will resolve the issue.
For me it turned out to be a Mongoose-related problem.
I was looping over objects that I got from a Mongo query. I just had to remove:
items = await Model.find()
And replace it by:
items = await Model.find().lean()
This might help somebody as I had a similar issue in which the JSON.parse() was returning an object that I could print on the console.log() but I couldn't acccess the specific fields and none of the above solution worked for me. Like using the combination of JSON.parse() with JSON.stringify().
var jsonObj = JSON.parse(JSON.stringify(responseText))
// where responseText is a JSON String returned by the server.
console.log(jsonObj) ///Was printing the object correctly
console.log(jsonObj.Body) /// Was printing Undefined
I ended up solving the problem by using a different parser provided by ExtJs Ext.decode();
var jsonObj = Ext.decode(responseText)
console.log(jsonObj.Body) //Worked...
I had the same issue and no solution above worked for me and it sort of felt like guess work thereafter. However, wrapping my code which creates the object in a setTimeout function did the trick for me.
setTimeout(function() {
var myObj = xyz; //some code for creation of complex object like above
console.log(myObj); // this works
console.log(myObj.propertyName); // this works too
});
I've just had the same issue with a document loaded from MongoDB using Mongoose.
Turned out that i'm using the property find() to return just one object, so i changed find() to findOne() and everything worked for me.
Solution (if you're using Mongoose): Make sure to return one object only, so you can parse its object.id or it will be treated as an array so you need to acces it like that object[0].id.
In My case, it just happens to be that even though i receive the data in the format of a model like myMethod(data:MyModelClass) object till the received object was of type string.
Which is y in console.log(data) i get the content.
Solution is just to parse the JSON(in my case)
const model:MyMOdelClass=JSON.parse(data);
Thought may be usefull.
I've had similar issue, hope the following solution helps someone.
You can use setTimeout function as some guys here suggesting, but you never know how exactly long does your browser need to get your object defined.
Out of that I'd suggest using setInterval function instead. It will wait until your object config.col_id_3 gets defined and then fire your next code part that requires your specific object properties.
window.addEventListener('load', function(){
var fileInterval = setInterval(function() {
if (typeof config.col_id_3 !== 'undefined') {
// do your stuff here
clearInterval(fileInterval); // clear interval
}
}, 100); // check every 100ms
});
if you're using TYPESCRIPT and/or ANGULAR, it could be this!
.then((res: any) => res.json())
setting the response type to any fixed this issue for me, I couldn't access properties on the response until i set res: any
see this question Property '_body' does not exist on type 'Response'
I had a similar issue or maybe just related.
For my case I was accessing properties of an object but one was undefined. I found the problem was a white-space in the server side code while creating the key,val of the object.
My approach was as follows...
After removing the white-space from the server-side code creating the object, I could now access the property as below...
This might not be the issue with the case of the subject question but was for my case and may be so for some one else. Hope it helps.
I just encountered this issue as well, and long story short my API was returning a string type and not JSON. So it looked exactly the same when you printed it to the log however whenever I tried to access the properties it gave me an undefined error.
API Code:
var response = JsonConvert.DeserializeObject<StatusResult>(string Of object);
return Json(response);
previously I was just returning:
return Json(string Of object);
First thing check the type like below:
console.log(typeof config);
If the command above prints object then it is very easy you just use the bracket notation. Bracket notation can be quite useful if you want to search for a property’s values dynamically.
Execute the command below:
console.log(config[col_id_3]);
If it a string you need to parse in object first. To do that you need to execute the command below:
var object = JSON.parse(config);
And after that use bracket notation to access the property like below:
console.log(object[col_id_3]);
I had an issue like this, and found the solution was to do with Underscore.js. My initial logging made no sense:
console.log(JSON.stringify(obj, null, 2));
> {
> "code": "foo"
> }
console.log(obj.code);
> undefined
I found the solution by also looking at the keys of the object:
console.log(JSON.stringify(Object.keys(obj)));
> ["_wrapped","_chain"]
This lead me to realise that obj was actually an Underscore.js wrapper around an object, and the initial debugging was lying to me.
I had similar problem (when developing for SugarCRM), where I start with:
var leadBean = app.data.createBean('Leads', {id: this.model.attributes.parent_id});
// This should load object with attributes
leadBean.fetch();
// Here were my attributes filled in with proper values including name
console.log(leadBean);
// Printed "undefined"
console.log(leadBean.attributes.name);
Problem was in fetch(), its async call so I had to rewrite my code into:
var leadBean = app.data.createBean('Leads', {id: this.model.attributes.parent_id});
// This should load object with attributes
leadBean.fetch({
success: function (lead) {
// Printed my value correctly
console.log(lead.attributes.name);
}
});
Just in case this is helpful for someone, I had a similar problem, and it's because someone created an override for .toJSON in the object I was working with. So the object was something like:
{
foo: {
bar: "Hello"
baz: "World"
}
}
But .toJSON() was:
toJSON() {
return this.foo
}
So when I called JSON.stringify(myObject) it returned "{"bar": "Hello", "baz": "World"}". However, Object.keys(myObject) revealed the "foo".
I faced the same problem today. In my case the keys were nested, i.e key1.key2.
I split the keys using split() and then used the square bracket notation, which did work for me.
var data = {
key1: {
key2: "some value"
}
}
I split the keys and used it like this, data[key1][key2] which did the job for me.
I had the same issue today. Problem was caused by uglify-js. After I executed same non-uglified code problem was solved. Removing of
--mangle-props
from uglify-js was enough to have working uglified code.
Perhaps, the best practice is to use some prefix for properties that has to be mangled with regex rule for uglify-js.
Here is the source:
var data = JSON.parse( content);
...
this.pageIndex = parseInt(data.index);
this.pageTotal = parseInt(data.total);
this.pageLimit = parseInt(data.limit);
and here is how it was uglified:
var n = JSON.parse( t);
...
this._ = parseInt(n.index), this.g = parseInt(n.total), this.D = parseInt(n.C)
None of the JSON stringify/parse worked for me.
formValues.myKey: undefined
formValues.myKey with timeout: content
I wanted the value of formValues.myKey and what did the trick was a setTimeout 0 like in the example below. Hope it helps.
console.log('formValues.myKey: ',formValues.myKey);
setTimeout( () => {
console.log('formValues.myKey with timeout: ', formValues.myKey);
}, 0 );
I had a similar issue today in React. Eventually realised that the problem was being caused by the state not being set yet. I was calling user.user.name and although it was showing up in the console, I couldn't seem to access it in my component till I included a check to check if user.user was set and then calling user.user.name.
Check whether you had applied any filters in the console. It happens to me in chrome console.
I also had this frustrating problem, I tried the setTimeout() and the JSON.stringify and JSON.parse solutions even if I knew it wouldn't work as I think they're mostly JSON or Promise related problems, sure enough it didn't work. In my case though, I didn't notice immediately that it was a silly mistake. I was actually accessing a property name with a different casing. It's something like this:
const wrongPropName = "SomeProperty"; // upper case "S"
const correctPropName = "someProperty"; // lower case "s"
const object = { someProperty: "hello world!" };
console.log('Accessing "SomeProperty":', object[wrongPropName]);
console.log('Accessing "someProperty":', object[correctPropName])
It took me a while to notice as the property names in my case can have either all lower case or some having mixed case. It turned out that a function in my web application has something that makes a mess of my property names (it has a .toLowerCase() next to the generated key names 🤣).
So, lesson learned, check property name casing more properly.

Can't access object property, even though it shows up in a console log

Below, you can see the output from these two logs. The first clearly shows the full object with the property I'm trying to access, but on the very next line of code, I can't access it with config.col_id_3 (see the "undefined" in the screenshot?). Can anyone explain this? I can get access to every other property except field_id_4 as well.
console.log(config);
console.log(config.col_id_3);
This is what these lines print in Console
The output of console.log(anObject) is misleading; the state of the object displayed is only resolved when you expand the Object tree displayed in the console, by clicking on >. It is not the state of the object when you console.log'd the object.
Instead, try console.log(Object.keys(config)), or even console.log(JSON.stringify(config)) and you will see the keys, or the state of the object at the time you called console.log.
You will (usually) find the keys are being added after your console.log call.
I've just had this issue with a document loaded from MongoDB using Mongoose.
When running console.log() on the whole object, all the document fields (as stored in the db) would show up. However some individual property accessors would return undefined, when others (including _id) worked fine.
Turned out that property accessors only works for those fields specified in my mongoose.Schema(...) definition, whereas console.log() and JSON.stringify() returns all fields stored in the db.
Solution (if you're using Mongoose): make sure all your db fields are defined in mongoose.Schema(...).
Check if inside the object there's an array of objects. I had a similar issue with a JSON:
"terms": {
"category": [
{
"ID": 4,
"name": "Cirugia",
"slug": "cirugia",
"description": "",
"taxonomy": "category",
"parent": null,
"count": 68,
"link": "http://distritocuatro.mx/enarm/category/cirugia/"
}
]
}
I tried to access the 'name' key from 'category' and I got the undefined error, because I was using:
var_name = obj_array.terms.category.name
Then I realised it has got square brackets, that means that it has an array of objects inside the category key, because it can have more than one category object. So, in order to get the 'name' key I used this:
var_name = obj_array.terms.category[0].name
And That does the trick.
Maybe it's too late for this answer, but I hope someone with the same problem will find this as I did before finding the Solution :)
I had the same issue. Solution for me was using the stringified output as input to parsing the JSON. this worked for me. hope its useful to you
var x =JSON.parse(JSON.stringify(obj));
console.log(x.property_actually_now_defined);
The property you're trying to access might not exist yet. Console.log works because it executes after a small delay, but that isn't the case for the rest of your code. Try this:
var a = config.col_id_3; //undefined
setTimeout(function()
{
var a = config.col_id_3; //voila!
}, 100);
In my case I was passing an object to a promise, within the promise I was adding more key/values to the object and when it was done the promise returned the object.
However, a slight over look on my part, the promise was returning the object before it was fully finished...thus the rest of my code was trying to process the updated object and the data wasn't yet there. But like above, in the console, I saw the object fully updated but wasn't able to access the keys - they were coming back undefined. Until I saw this:
console.log(obj) ;
console.log(obj.newKey1) ;
// returned in console
> Object { origKey1: "blah", origKey2: "blah blah"} [i]
origKey1: "blah"
origKey2: "blah blah"
newKey1: "this info"
newKey2: "that info"
newKey3: " more info"
> *undefined*
The [i] is a little icon, when I hovered over it it said Object value at left was snapshotted when logged, value below was evaluated just now. Thats when it occurred to me that my object was being evaluated before the promise had fully updated it.
I just encountered this issue with objects generated by csv-parser from a CSV file that was generated by MS Excel. I was able to access all properties except the first property - but it would show up ok if I wrote the whole object using console.log.
Turned out that the UTF-8 CSV format inserts 3 bytes (ef bb bf) at the start corresponding to an invisible character - which were being included as part of the first property header by csv-parser. Solution was to re-generate the CSV using the non-UTF option and this eliminated the invisible character.
I struggled with this issue today, and thought I'll leave a reply with my solution.
I was fetching a data object via ajax, something like this:
{"constants": {"value1":"x","value2":"y"},"i18n" {"data1":"x", "data2":"y"}}
Let's say this object is in a variable called data. Whenever I referenced data.i18n I got undefined.
console.log(data) showed the object as expected
console.log(Object.keys(data)) said ["constants","i18n"] as expected
Renaming i18n to inter didn't change anything
I even tried to switch the data to make "i18n" the first object
Moved code around to make absolutely sure the object was completely set and there was no problem with the ajax promise.
Nothing helped... Then on the server side I wrote the data to the php log, and it revealed this:
{"constants": {"value1":"x","value2":"y"},"\u045618n" {"data1":"x", "data2":"y"}}
The "i" in the index key was actually a u0456 (cyrillic i). This was not visible in my php editor or the browser console log. Only the php log revealed this... That was a tricky one...
My data was just json data string . (This variable was stored as json string in the session).
console.log(json_string_object)
-> returns just the representation of this string and there is no way to make difference whether is string or object.
So to make it work I just needed to convert it back to real object:
object = JSON.parse(json_string_object);
In 2018 Mozilla warns us in the Mozilla Docs here!
I quote "Logging Objects":
Don't use console.log(obj);,
use console.log(JSON.parse(JSON.stringify(obj)));.
This way you are sure you are seeing the value of obj at the moment
you log it.
If this is an issue occurring when working with Mongoose, the following may happen:
console.log(object)
returns everything, including the desired key.
console.log(object.key)
returns undefined.
If that is happening, it means that the key is missing from the Mongoose Schema. Adding it in will resolve the issue.
For me it turned out to be a Mongoose-related problem.
I was looping over objects that I got from a Mongo query. I just had to remove:
items = await Model.find()
And replace it by:
items = await Model.find().lean()
This might help somebody as I had a similar issue in which the JSON.parse() was returning an object that I could print on the console.log() but I couldn't acccess the specific fields and none of the above solution worked for me. Like using the combination of JSON.parse() with JSON.stringify().
var jsonObj = JSON.parse(JSON.stringify(responseText))
// where responseText is a JSON String returned by the server.
console.log(jsonObj) ///Was printing the object correctly
console.log(jsonObj.Body) /// Was printing Undefined
I ended up solving the problem by using a different parser provided by ExtJs Ext.decode();
var jsonObj = Ext.decode(responseText)
console.log(jsonObj.Body) //Worked...
I had the same issue and no solution above worked for me and it sort of felt like guess work thereafter. However, wrapping my code which creates the object in a setTimeout function did the trick for me.
setTimeout(function() {
var myObj = xyz; //some code for creation of complex object like above
console.log(myObj); // this works
console.log(myObj.propertyName); // this works too
});
I've just had the same issue with a document loaded from MongoDB using Mongoose.
Turned out that i'm using the property find() to return just one object, so i changed find() to findOne() and everything worked for me.
Solution (if you're using Mongoose): Make sure to return one object only, so you can parse its object.id or it will be treated as an array so you need to acces it like that object[0].id.
In My case, it just happens to be that even though i receive the data in the format of a model like myMethod(data:MyModelClass) object till the received object was of type string.
Which is y in console.log(data) i get the content.
Solution is just to parse the JSON(in my case)
const model:MyMOdelClass=JSON.parse(data);
Thought may be usefull.
I've had similar issue, hope the following solution helps someone.
You can use setTimeout function as some guys here suggesting, but you never know how exactly long does your browser need to get your object defined.
Out of that I'd suggest using setInterval function instead. It will wait until your object config.col_id_3 gets defined and then fire your next code part that requires your specific object properties.
window.addEventListener('load', function(){
var fileInterval = setInterval(function() {
if (typeof config.col_id_3 !== 'undefined') {
// do your stuff here
clearInterval(fileInterval); // clear interval
}
}, 100); // check every 100ms
});
if you're using TYPESCRIPT and/or ANGULAR, it could be this!
.then((res: any) => res.json())
setting the response type to any fixed this issue for me, I couldn't access properties on the response until i set res: any
see this question Property '_body' does not exist on type 'Response'
I had a similar issue or maybe just related.
For my case I was accessing properties of an object but one was undefined. I found the problem was a white-space in the server side code while creating the key,val of the object.
My approach was as follows...
After removing the white-space from the server-side code creating the object, I could now access the property as below...
This might not be the issue with the case of the subject question but was for my case and may be so for some one else. Hope it helps.
I just encountered this issue as well, and long story short my API was returning a string type and not JSON. So it looked exactly the same when you printed it to the log however whenever I tried to access the properties it gave me an undefined error.
API Code:
var response = JsonConvert.DeserializeObject<StatusResult>(string Of object);
return Json(response);
previously I was just returning:
return Json(string Of object);
First thing check the type like below:
console.log(typeof config);
If the command above prints object then it is very easy you just use the bracket notation. Bracket notation can be quite useful if you want to search for a property’s values dynamically.
Execute the command below:
console.log(config[col_id_3]);
If it a string you need to parse in object first. To do that you need to execute the command below:
var object = JSON.parse(config);
And after that use bracket notation to access the property like below:
console.log(object[col_id_3]);
I had an issue like this, and found the solution was to do with Underscore.js. My initial logging made no sense:
console.log(JSON.stringify(obj, null, 2));
> {
> "code": "foo"
> }
console.log(obj.code);
> undefined
I found the solution by also looking at the keys of the object:
console.log(JSON.stringify(Object.keys(obj)));
> ["_wrapped","_chain"]
This lead me to realise that obj was actually an Underscore.js wrapper around an object, and the initial debugging was lying to me.
I had similar problem (when developing for SugarCRM), where I start with:
var leadBean = app.data.createBean('Leads', {id: this.model.attributes.parent_id});
// This should load object with attributes
leadBean.fetch();
// Here were my attributes filled in with proper values including name
console.log(leadBean);
// Printed "undefined"
console.log(leadBean.attributes.name);
Problem was in fetch(), its async call so I had to rewrite my code into:
var leadBean = app.data.createBean('Leads', {id: this.model.attributes.parent_id});
// This should load object with attributes
leadBean.fetch({
success: function (lead) {
// Printed my value correctly
console.log(lead.attributes.name);
}
});
Just in case this is helpful for someone, I had a similar problem, and it's because someone created an override for .toJSON in the object I was working with. So the object was something like:
{
foo: {
bar: "Hello"
baz: "World"
}
}
But .toJSON() was:
toJSON() {
return this.foo
}
So when I called JSON.stringify(myObject) it returned "{"bar": "Hello", "baz": "World"}". However, Object.keys(myObject) revealed the "foo".
I faced the same problem today. In my case the keys were nested, i.e key1.key2.
I split the keys using split() and then used the square bracket notation, which did work for me.
var data = {
key1: {
key2: "some value"
}
}
I split the keys and used it like this, data[key1][key2] which did the job for me.
I had the same issue today. Problem was caused by uglify-js. After I executed same non-uglified code problem was solved. Removing of
--mangle-props
from uglify-js was enough to have working uglified code.
Perhaps, the best practice is to use some prefix for properties that has to be mangled with regex rule for uglify-js.
Here is the source:
var data = JSON.parse( content);
...
this.pageIndex = parseInt(data.index);
this.pageTotal = parseInt(data.total);
this.pageLimit = parseInt(data.limit);
and here is how it was uglified:
var n = JSON.parse( t);
...
this._ = parseInt(n.index), this.g = parseInt(n.total), this.D = parseInt(n.C)
None of the JSON stringify/parse worked for me.
formValues.myKey: undefined
formValues.myKey with timeout: content
I wanted the value of formValues.myKey and what did the trick was a setTimeout 0 like in the example below. Hope it helps.
console.log('formValues.myKey: ',formValues.myKey);
setTimeout( () => {
console.log('formValues.myKey with timeout: ', formValues.myKey);
}, 0 );
I had a similar issue today in React. Eventually realised that the problem was being caused by the state not being set yet. I was calling user.user.name and although it was showing up in the console, I couldn't seem to access it in my component till I included a check to check if user.user was set and then calling user.user.name.
Check whether you had applied any filters in the console. It happens to me in chrome console.
I also had this frustrating problem, I tried the setTimeout() and the JSON.stringify and JSON.parse solutions even if I knew it wouldn't work as I think they're mostly JSON or Promise related problems, sure enough it didn't work. In my case though, I didn't notice immediately that it was a silly mistake. I was actually accessing a property name with a different casing. It's something like this:
const wrongPropName = "SomeProperty"; // upper case "S"
const correctPropName = "someProperty"; // lower case "s"
const object = { someProperty: "hello world!" };
console.log('Accessing "SomeProperty":', object[wrongPropName]);
console.log('Accessing "someProperty":', object[correctPropName])
It took me a while to notice as the property names in my case can have either all lower case or some having mixed case. It turned out that a function in my web application has something that makes a mess of my property names (it has a .toLowerCase() next to the generated key names 🤣).
So, lesson learned, check property name casing more properly.

JSON that contains functions

I have a website that returns a JSON-like data structure like this:
{
"name":"tom jones",
"no": 123,
"storedproc": function(){
callbuyer(0123);
}
}
I'm getting this data using $.ajax() with dataType "JSON". Unfortunately, my $.ajax() calls the error callback because my data contains a function().
How can I parse this correctly? I really need to store the function in a variable and call it later.
That is simply not legal JSON (as you know given the title of the question) See the offical JSON syntax. The nice thing about real JSON is that one can use JSON.parse which safely wraps an eval call.
While eval could be used, I would suggest revisiting the architecture of your application and find some other way to do what you are trying to do.
In particular, I would have the server return the 0123 only, and let your client keep the logic that lets it know, in certain cases, which functions apply (in the scenario here, the function would be callbuyer).
This should work because you say you want to call the function which is the value of the storedproc later. Since the body of this function contains a call to callbuyer it follows that your client side script knows what callbuyer is. The trick is for your server not to send back arbitrary, unconstrained functions, but rather data that your client can exploit somehow using the knowledge it has about the overall application.
Could you arrange to have the server return JSON like this:
{"name":"tom jones",
"no": 123,
"storeprocFn": callbuyer,
"arg": "0123"};
Then your callback function can call the callbuyer function and pass arg
Use eval to interpret the string as a javascript object. You won't be able to use the JSON data type though. I believe what you need to do is use 'text' as the dataType for the $.ajax call. Then do something like:
var data = eval('(' + text + ')');
Should work. Of course, eval is evil. But it would solve your problem. As long as you can guarantee there isn't anything malicious in the text (no unsanitized, user entered data) then you should be ok.
AFAIK, functions are left out when using JSON.stringify, it's just not meant to be used to clone full objects (props and methods). However, you might be able to pass the function body as a string.Say you decide on a string format like func=>var foo = 'bar'; return foo;. This should be passed as a regular JSON string, after parsing the object you could then iterate all properties, and convert those strings to functions like so:
for (var prop in parsedObj)
{
if (parsedObj.hasOwnProperty(prop) && parsedObj[prop].match(/^func\=\>/))
{
parsedObj[prop] = new Function(parsedObj[prop].replace('func=>',''));
}
}
Though, seriously, I'd say you might want to rethink your approach, this is not what JSON is for. It's unsafe, all JSON strings are eval'ed, after having made sure they contain no harmful code. This approach is creating a loophole/vulnerability that the JSON people worked hard for to seal off.
For your example will this work:
'user.storeproc = function() { callbuyer( user.no);};'
The Var 'user' is the object of the parsed json.
Ps: maybe you have to format user.no, from 123 to 0123
Following JSON extension, "JFON", does transport of functions and array-properties.
JFON uses eval and is intended for case if:
1) your data is from trusted source ( like not-derived from user input or is a code from your own server), and
2) you know there are no undesired side effects with context of "eval"
(it is a context of eval in function "fromJFON", line 127 )
3) it is costly to refactor your app to use "functionless" JSON;
4) JFON is one-day work, so may be needs more testing;
The idea: use selected property name to escape functions and arrays like
in strings when selected character "\" is used to pass \n and \ for itself.
In JFON, name "wrap" is selected to pass functions and itself: "wrap" : { "fun" : ... and "wrap" : { "esc" : ...
demo: http://landkey.org/Sandbox/z/spaceen86/js/btb/tests/jfon.htm
code ( use commit 0.0.86 ):
https://github.com/lancelab/spaceen/blob/master/js/btb/JFON.js
test: github.com/lancelab/spaceen/blob/master/js/btb/tests/jfon.htm
Here is another, "JWON" extension: JSON-comments, here-documents, monkey-patching of JSONs:
github.com/lancelab/Boardspirator/blob/master/diary/play/tp/jwon.js

Convert json object to json string and use it's functions?

I have a json object with a function:
var thread = {
title: "my title",
delete: function() {
alert("deleted");
}
};
thread.delete(); // alerted "deleted"
thread_json = JSON.encode(thread); // convert to json from object
thread_object = JSON.decode(thread_json); // convert to object from json
thread_object.delete(); // this didn't work
After I converted it back from json string to object, I could not use delete() function.
When you convert something to json, the functions are gone?
Are there ways to keep them in the json string?
I'm using Mootools.
You got it. Take a look at that JSON.encode output. Only simple data types are allowed in JSON representations, partly for ease of creation, and partly for security. (The reason we use something like JSON.decode instead of eval is the possibility of embedding functions.)
You'll have to modify the JSON library source code to accept functions, or write your own in order to preserve the literal definition of the object upon conversion to string.
Consider, though, the possibility that you don't really need to do this. There's probably a better solution, but I can't begin to address that without knowing your exact situation.

Categories