Why can't I access JSON objects by key in JavaScript? - javascript

This is my JSON object:
{ text: 'stuff',
user: 'user1
}
when I run a typeof jsonObj, I get object. When I run an jsonOb.length, I get undefined. When I tried to access the text property via console.log(jsonObj.text), I get undefined.
So how can I properly access everything in JavaScript?
I don't want to use jQuery as this is all node.js programming so it's serverside.
UPDATED - full JSON
{ text: '#junk_666 おかえりか',
user:
{ display_name: 'mono',
screen_name: 'monochrm',
klout_score: null,
location_str: '画面の前',
utc_offset: '32400' },
venue_id: 1304409836517,
match_type: 'twitter',
tweet_id: '116494264137023489',
created_at_unix: 1316609371,
meta:
{ matchedPhrase: 'junk',
venueName: 'deletemepls really long name' },
tags: [ '' ],
indexed_at_unix: 1316609416 }

The json seems to be invalid
{
"text": "stuff",
"user": "user1"
}

I copied and pasted your object into a FireBug console and it recognized it.
If you need to count the number of key/value pairs, you can use a function such as this one to do it:
function numMembers(o) {
var i=0;
for (a in o) {
i++;
}
return i;
}
You should be able to access the value of the text property via jsonObj.text. Are you sure that your object is being referenced by jsonObj? Also, can you access the values for simpler objects such as the ones mentioned in other posts if you create them? Furthermore, does anything work if you use only ASCII characters? For some reason, it might not be handling some of the non-Latin characters properly.

First, what you have is not JSON because JSON requires property name to be in double quotes. It is a valid JavaScript object literal though, so I'll assume that's how you're using it.
Secondly, JavaScript objects in general do not have a length property. Arrays do.
There's no problem with your object literal so there must be some other problem elsewhere in your code.

Try this:
{ text: 'stuff',
user: 'user1'
}
You left off an apostrophe.
Now that you've posted your full JS code (that's not JSON, as #josnidhin points out)... works fine in jsFiddle. http://jsfiddle.net/Rs9R4/ I don't believe a JS Object has .length, just Arrays.

Related

stringify in query-string module not working as expected in Jest tests

I'm writing a unit test in Jest.
In the unit under test I am importing
import queryString from 'query-string'
and it is executing the code:
queryString.stringify(ids)
where ids is an array in the following format:
[{ id: '123' },{ id: '321' }]
This code works perfectly when running in my deployed webpage, but in a JEST test it gives the following output:
id=%5Bobject%20Object%5D&id=%5Bobject%20Object%5D
whereas the same code in a browser gives:
id=123&id=321
As per the requisites of the query-string module, I am using a verison of node > 6.
I have also added:
/* jest commonjs */
to the top of my test file as query-string targets node.
Additionally I have tried setting various options in stringify but to no avail.
Can anyone tell me why I'm getting different results in these different environments and how I can get my test to work? i.e. not render the string as "%5Bobject%20".
Sure, I could implement my own stringify method, but this library is built to do this!
Can you please define what the expected behavior would be?
According to the documentation, stringify() converts an object into a query. Since you are passing ids, an array of elements, there are different possible behaviors you may get.
Please note that, in javascript, an array is an object with numbers as keys, so [ { id: '123' }, { id: '456' } ] actually looks like { '0': { 'id': '123' }, '1': { 'id': '456' } } (take a look at Object.keys of the array, you'll see it's ['0','1']).
So, that being said, what queryString is doing is converting each pair key-value into key=value, where both key and values have been "stringified" (I'm assuming through the String constructor). Since the value is an object, it returns that things you're seeing (indeed, String({}) is [object Object]. What I would expect (and I'm indeed getting) from the stringification of an array of objects is therefore something like 0=[object Object]&1=[object Object] (with the square brackets converted to %5B and %5D and spaces to %20).
I don't really know where that questionId is coming from, so a little more context should be provided (e.g. showing the actual object being stringified could be useful) but, to get to the point, in order to avoid having your object be converted to [object Object] you should use a key extractor, that returns the value you actually want to be shown as value.
So, for example, if your array is as described above and the result you'd like to get is 0=123&1=456, you would do something like:
const ids = [ {id: '123'}, {id: '456'} ];
queryString.stringify(ids.map(v => v.id))
Instead, if the expected behavior is id=123&id=456, you need to convert the array to the object { id: ['123','456'] }. You can do that with the following
const ids = [ {id: '123'}, {id: '456'} ];
queryString.stringify({ id: ids.reduce( (c,v) => c.concat(v.id), []) })
So, you need to transform your original ids array into an object that is suitable for stringify.
You can use this npm package https://www.npmjs.com/package/qs
It has a working qs.stringify

How to break down an array of objects within a string

I have some code that returns something like this:
body: '[
{
name: "name",
lastname: "lastname"
},
{
name: "name",
lastname: "lastname"
},
{
name: "name",
lastname: "lastname"
}
]'
Of course extracting the body is a simple object.body however, to get rid of the '' that wraps the array is just destroying me. I tried doing object.body.slice(1,-1) to get rid of them, it didnt work. I'm clearly not using the object properly.
How can I "extract" the array from within the body into a usable array?
It sounds like you want to evaluate the content of the string. Assuming whatever code building this string can't actually build JS objects to begin with, you can use eval or Function to generate the objects you need.
var data = eval(string);
Note that you must be sure that the source of the string is safe and reliable, otherwise you could be evaluating malicious code. There may also be performance consequences to using eval.
Using Function is a tiny bit safer, only because the code can not access your local variables. It should also avoid the performance costs of eval.
var data = Function("return (" + string + ");")();
Same warning about malicious code though.
If the string data was valid JSON, you could use JSON.parse, but it isn't, so you can't. To avoid security issues, either have the source provide valid JSON data, or write your own minimal parser to parse the data.
With a valid JSON string, you could just parse the string for an object with JSON.parse, if you have .
array = JSON.parse(string);
You can use split function and then take the first element, let me say
var a = '[{name: "name",lastname: "lastname"},{name: "name",lastname: "lastname"},{name: "name",lastname: "lastname"}]';
var s = a.split("'");
s[0] will return you the desired result

Why can't commas be in Javascript object keys?

This is an odd thing to ask I am aware, but I am very much a newbie and can't seem to wrap my head around this. I have a Javascript object sent to me via firebase that looks like this:
var blob = {
matt#email,com: { //notice the comma because periods are illegal in keys
email: "matt#email.com" //actual email with period
name: "Matt Sanford"
pic: "https://lh3.googleusercontent.com/-LeQrq-_KjJE/AAAAAAAAAAI/AAAAAAAAAoI/4l6r2HNdock/photo.jpg"
provider: "google"
uid: "0000000000000000"
}
}
}
I am trying to access the inner most tree via the console like so: console.log(blob.matt#email,com) //throws an error because of an invalid token
even though it should return the object with email, name, etc.
However when I tried the same structure like so:
var blob = {foo: {bar: true} }
console.log(blob.foo) //output '{bar: true}'
There are two things I am wondering, is having the initial key with the modified email illegal because of the commas or is there not a way to read such a key in javascript? Recommendations are appreciated because I am just learning as I go along here.
Update
How would I go about accessing the keys dynamically? Clearly it would be impossible to input each key dynamically. How would I read it without knowing what exactly the key name is?
What you posted is not a json object, it's a javascript object. JSON would have all its keys quoted.
Comma's are definitely allowed, but you cannot use the standard obj.property syntax like this:
console.log(blob.matt#email,com)
You must do:
console.log(blob['matt#email,com']);

Sort Json Array with LoDash

I have a JSON array whose general structure is like this:
var json = [
{ key: 'firstName', value: 'Bill' },
{ key: 'lastName', value: 'Mans' },
{ key: 'phone', value: '123.456.7890' }
];
In reality, there will be a lot more key/value pairs. Either way, I'm trying to sort this array by the key value using Lodash. Currently, I'm trying the following:
_.map(_.sortBy(json, key), _.values);
However, that causes an error that says:
[ReferenceError: key is not defined]
I suspect its because key is not wrapped in quotes as shown in the docs. Unfortunately, I do not actually have control over the format of the json. In reality its being used by other developers and I'm the last to use it. Is there a way for me to sort the json array, by key names, using lodash? If so, how?
thank you
You need to put the key in quotes only when calling sortBy. It doesn't have to be in quotes in the data itself.
_.sortBy(json, "key")
Also, your second parameter to map is wrong. It should be a function, but using pluck is easier.
_.pluck( _.sortBy(json, "key") , "value");
_.map(_.sortBy(json, 'key'), 'value');
NOTE: In the latest version of lodash, _.pluck no longer exists. Use _.map instead as a drop-in replacement

JavaScript object data extraction (JSON Stringify/Parse or without?)

I am trying to figure out if I JSON.Stringify an object like this:
{"m_id":"xxx","record":
{"USER":"yyy","PWD","zzz","_createdAt":
11111."_updatedAt":00000},"state":"valid"}
and then try to JSON.Parse out only the USER and PWD, not have to just call the object, but go through stringify. how would that work?
thanks.
I'm not sure why you're talking about stringifying your object. You'd stringify it if you needed to send the data across a network or something, not when you need to manipulate it in JS.
...how do I extract the strings in {...USER: "aaa", PWD: "zzz"...}?
Assuming you have a variable referring to the object, something like the following (with or without nice line breaks and indenting to make it readable, and with or without quotes around the property names):
var obj = {
"m_id": "xxx",
"record": {
"USER": "yyy",
"PWD" : "zzz",
"_createdAt": 11111,
"_updatedAt": 00000
},
"state": "valid"
};
Then you can access the properties in the nested record object as follows:
console.log( obj.record.USER ); // outputs "yyy"
console.log( obj.record.PWD ); // outputs "zzz"
// etc.
(Note: in your question you had two typos, a comma that should've been a colon in between "PWD" and "zzz", and a dot that should've been a comma in between 11111 and "_updatedAt". There's no way that JSON.stringify() would have produced the string that you showed with those mistakes.)
If you want the strings "USER", "PWD" etc as an array, then use Object.keys.
If you want to iterate them, just use a normal for-in enumeration.
I might have misunderstood the question, but if I think it is what it is then try using
var tmp = JSON.parse(string_to_convert)
this should suffice to convert your string to a proper Javascript Object
Then you can do
for(var index in tmp){
console.log(tmp[index]);
}
and this should list all the keys on the first set of properties. If you want to do a nested thing, then use recursion on the properties. Hope this makes sense...

Categories

Resources