MongoDB dot (.) in key name - javascript

It seems mongo does not allow insertion of keys with a dot (.) or dollar sign ($) however when I imported a JSON file that contained a dot in it using the mongoimport tool it worked fine. The driver is complaining about trying to insert that element.
This is what the document looks like in the database:
{
"_id": {
"$oid": "..."
},
"make": "saab",
"models": {
"9.7x": [
2007,
2008,
2009,
2010
]
}
}
Am I doing this all wrong and should not be using hash maps like that with external data (i.e. the models) or can I escape the dot somehow? Maybe I am thinking too much Javascript-like.

MongoDB doesn't support keys with a dot in them so you're going to have to preprocess your JSON file to remove/replace them before importing it or you'll be setting yourself up for all sorts of problems.
There isn't a standard workaround to this issue, the best approach is too dependent upon the specifics of the situation. But I'd avoid any key encoder/decoder approach if possible as you'll continue to pay the inconvenience of that in perpetuity, where a JSON restructure would presumably be a one-time cost.

As mentioned in other answers MongoDB does not allow $ or . characters as map keys due to restrictions on field names. However, as mentioned in Dollar Sign Operator Escaping this restriction does not prevent you from inserting documents with such keys, it just prevents you from updating or querying them.
The problem of simply replacing . with [dot] or U+FF0E (as mentioned elsewhere on this page) is, what happens when the user legitimately wants to store the key [dot] or U+FF0E?
An approach that Fantom's afMorphia driver takes, is to use unicode escape sequences similar to that of Java, but ensuring the escape character is escaped first. In essence, the following string replacements are made (*):
\ --> \\
$ --> \u0024
. --> \u002e
A reverse replacement is made when map keys are subsequently read from MongoDB.
Or in Fantom code:
Str encodeKey(Str key) {
return key.replace("\\", "\\\\").replace("\$", "\\u0024").replace(".", "\\u002e")
}
Str decodeKey(Str key) {
return key.replace("\\u002e", ".").replace("\\u0024", "\$").replace("\\\\", "\\")
}
The only time a user needs to be aware of such conversions is when constructing queries for such keys.
Given it is common to store dotted.property.names in databases for configuration purposes I believe this approach is preferable to simply banning all such map keys.
(*) afMorphia actually performs full / proper unicode escaping rules as mentioned in Unicode escape syntax in Java but the described replacement sequence works just as well.

The latest stable version (v3.6.1) of the MongoDB does support dots (.) in the keys or field names now.
Field names can contain dots (.) and dollar ($) characters now

The Mongo docs suggest replacing illegal characters such as $ and . with their unicode equivalents.
In these situations, keys will need to substitute the reserved $ and . characters. Any character is sufficient, but consider using the Unicode full width equivalents: U+FF04 (i.e. “$”) and U+FF0E (i.e. “.”).

A solution I just implemented that I'm really happy with involves splitting the key name and value into two separate fields. This way, I can keep the characters exactly the same, and not worry about any of those parsing nightmares. The doc would look like:
{
...
keyName: "domain.com",
keyValue: "unregistered",
...
}
You can still query this easy enough, just by doing a find on the fields keyName and keyValue.
So instead of:
db.collection.find({"domain.com":"unregistered"})
which wouldn't actually work as expected, you would run:
db.collection.find({keyName:"domain.com", keyValue:"unregistered"})
and it will return the expected document.

You can try using a hash in the key instead of the value, and then store that value in the JSON value.
var crypto = require("crypto");
function md5(value) {
return crypto.createHash('md5').update( String(value) ).digest('hex');
}
var data = {
"_id": {
"$oid": "..."
},
"make": "saab",
"models": {}
}
var version = "9.7x";
data.models[ md5(version) ] = {
"version": version,
"years" : [
2007,
2008,
2009,
2010
]
}
You would then access the models using the hash later.
var version = "9.7x";
collection.find( { _id : ...}, function(e, data ) {
var models = data.models[ md5(version) ];
}

It is supported now
MongoDb 3.6 onwards supports both dots and dollar in field names.
See below JIRA: https://jira.mongodb.org/browse/JAVA-2810
Upgrading your Mongodb to 3.6+ sounds like the best way to go.

You'll need to escape the keys. Since it seems most people don't know how to properly escape strings, here's the steps:
choose an escape character (best to choose a character that's rarely used). Eg. '~'
To escape, first replace all instances of the escape character with some sequence prepended with your escape character (eg '~' -> '~t'), then replace whatever character or sequence you need to escape with some sequence prepended with your escape character. Eg. '.' -> '~p'
To unescape, first remove the escape sequence from all instance of your second escape sequence (eg '~p' -> '.'), then transform your escape character sequence to a single escape character(eg '~s' -> '~')
Also, remember that mongo also doesn't allow keys to start with '$', so you have to do something similar there
Here's some code that does it:
// returns an escaped mongo key
exports.escape = function(key) {
return key.replace(/~/g, '~s')
.replace(/\./g, '~p')
.replace(/^\$/g, '~d')
}
// returns an unescaped mongo key
exports.unescape = function(escapedKey) {
return escapedKey.replace(/^~d/g, '$')
.replace(/~p/g, '.')
.replace(/~s/g, '~')
}

From the MongoDB docs "the '.' character must not appear anywhere in the key name". It looks like you'll have to come up with an encoding scheme or do without.

A late answer, but if you use Spring and Mongo, Spring can manage the conversion for you with MappingMongoConverter. It's the solution by JohnnyHK but handled by Spring.
#Autowired
private MappingMongoConverter converter;
#PostConstruct
public void configureMongo() {
converter.setMapKeyDotReplacement("xxx");
}
If your stored Json is :
{ "axxxb" : "value" }
Through Spring (MongoClient) it will be read as :
{ "a.b" : "value" }

As another user mentioned, encoding/decoding this can become problematic in the future, so it's probably just easier to replace all keys that have a dot. Here's a recursive function I made to replace keys with '.' occurrences:
def mongo_jsonify(dictionary):
new_dict = {}
if type(dictionary) is dict:
for k, v in dictionary.items():
new_k = k.replace('.', '-')
if type(v) is dict:
new_dict[new_k] = mongo_jsonify(v)
elif type(v) is list:
new_dict[new_k] = [mongo_jsonify(i) for i in v]
else:
new_dict[new_k] = dictionary[k]
return new_dict
else:
return dictionary
if __name__ == '__main__':
with open('path_to_json', "r") as input_file:
d = json.load(input_file)
d = mongo_jsonify(d)
pprint(d)
You can modify this code to replace '$' too, as that is another character that mongo won't allow in a key.

I use the following escaping in JavaScript for each object key:
key.replace(/\\/g, '\\\\').replace(/^\$/, '\\$').replace(/\./g, '\\_')
What I like about it is that it replaces only $ at the beginning, and it does not use unicode characters which can be tricky to use in the console. _ is to me much more readable than an unicode character. It also does not replace one set of special characters ($, .) with another (unicode). But properly escapes with traditional \.

Not perfect, but will work in most situations: replace the prohibited characters by something else. Since it's in keys, these new chars should be fairly rare.
/** This will replace \ with ⍀, ^$ with '₴' and dots with ⋅ to make the object compatible for mongoDB insert.
Caveats:
1. If you have any of ⍀, ₴ or ⋅ in your original documents, they will be converted to \$.upon decoding.
2. Recursive structures are always an issue. A cheap way to prevent a stack overflow is by limiting the number of levels. The default max level is 10.
*/
encodeMongoObj = function(o, level = 10) {
var build = {}, key, newKey, value
//if (typeof level === "undefined") level = 20 // default level if not provided
for (key in o) {
value = o[key]
if (typeof value === "object") value = (level > 0) ? encodeMongoObj(value, level - 1) : null // If this is an object, recurse if we can
newKey = key.replace(/\\/g, '⍀').replace(/^\$/, '₴').replace(/\./g, '⋅') // replace special chars prohibited in mongo keys
build[newKey] = value
}
return build
}
/** This will decode an object encoded with the above function. We assume the structure is not recursive since it should come from Mongodb */
decodeMongoObj = function(o) {
var build = {}, key, newKey, value
for (key in o) {
value = o[key]
if (typeof value === "object") value = decodeMongoObj(value) // If this is an object, recurse
newKey = key.replace(/⍀/g, '\\').replace(/^₴/, '$').replace(/⋅/g, '.') // replace special chars prohibited in mongo keys
build[newKey] = value
}
return build
}
Here is a test:
var nastyObj = {
"sub.obj" : {"$dollar\\backslash": "$\\.end$"}
}
nastyObj["$you.must.be.kidding"] = nastyObj // make it recursive
var encoded = encodeMongoObj(nastyObj, 1)
console.log(encoded)
console.log( decodeMongoObj( encoded) )
and the results - note that the values are not modified:
{
sub⋅obj: {
₴dollar⍀backslash: "$\\.end$"
},
₴you⋅must⋅be⋅kidding: {
sub⋅obj: null,
₴you⋅must⋅be⋅kidding: null
}
}
[12:02:47.691] {
"sub.obj": {
$dollar\\backslash: "$\\.end$"
},
"$you.must.be.kidding": {
"sub.obj": {},
"$you.must.be.kidding": {}
}
}

There is some ugly way to query it not recommended to use it in application rather than for debug purposes (works only on embedded objects):
db.getCollection('mycollection').aggregate([
{$match: {mymapfield: {$type: "object" }}}, //filter objects with right field type
{$project: {mymapfield: { $objectToArray: "$mymapfield" }}}, //"unwind" map to array of {k: key, v: value} objects
{$match: {mymapfield: {k: "my.key.with.dot", v: "myvalue"}}} //query
])

For PHP I substitute the HTML value for the period. That's ".".
It stores in MongoDB like this:
"validations" : {
"4e25adbb1b0a55400e030000" : {
"associate" : "true"
},
"4e25adb11b0a55400e010000" : {
"associate" : "true"
}
}
and the PHP code...
$entry = array('associate' => $associate);
$data = array( '$set' => array( 'validations.' . str_replace(".", `"."`, $validation) => $entry ));
$newstatus = $collection->update($key, $data, $options);

Lodash pairs will allow you to change
{ 'connect.sid': 's:hyeIzKRdD9aucCc5NceYw5zhHN5vpFOp.0OUaA6' }
into
[ [ 'connect.sid',
's:hyeIzKRdD9aucCc5NceYw5zhHN5vpFOp.0OUaA6' ] ]
using
var newObj = _.pairs(oldObj);

You can store it as it is and convert to pretty after
I wrote this example on Livescript. You can use livescript.net website to eval it
test =
field:
field1: 1
field2: 2
field3: 5
nested:
more: 1
moresdafasdf: 23423
field3: 3
get-plain = (json, parent)->
| typeof! json is \Object => json |> obj-to-pairs |> map -> get-plain it.1, [parent,it.0].filter(-> it?).join(\.)
| _ => key: parent, value: json
test |> get-plain |> flatten |> map (-> [it.key, it.value]) |> pairs-to-obj
It will produce
{"field.field1":1,
"field.field2":2,
"field.field3":5,
"field.nested.more":1,
"field.nested.moresdafasdf":23423,
"field3":3}

Give you my tip: You can using JSON.stringify to save Object/ Array contains the key name has dots, then parse string to Object with JSON.parse to process when get data from database
Another workaround:
Restructure your schema like:
key : {
"keyName": "a.b"
"value": [Array]
}

Latest MongoDB does support keys with a dot, but java MongoDB-driver is not supporting. So to make it work in Java, I pulled code from github repo of java-mongo-driver and made changes accordingly in their isValid Key function, created new jar out of it, using it now.

Replace the dot(.) or dollar($) with other characters that will never used in the real document. And restore the dot(.) or dollar($) when retrieving the document. The strategy won't influence the data that user read.
You can select the character from all characters.

The strange this is, using mongojs, I can create a document with a dot if I set the _id myself, however I cannot create a document when the _id is generated:
Does work:
db.testcollection.save({"_id": "testdocument", "dot.ted.": "value"}, (err, res) => {
console.log(err, res);
});
Does not work:
db.testcollection.save({"dot.ted": "value"}, (err, res) => {
console.log(err, res);
});
I first thought dat updating a document with a dot key also worked, but its identifying the dot as a subkey!
Seeing how mongojs handles the dot (subkey), I'm going to make sure my keys don't contain a dot.

Like what #JohnnyHK has mentioned, do remove punctuations or '.' from your keys because it will create much larger problems when your data starts to accumulate into a larger dataset. This will cause problems especially when you call aggregate operators like $merge which requires accessing and comparing keys which will throw an error. I have learnt it the hard way please don't repeat for those who are starting out.

In our case the properties with the period is never queried by users directly. However, they can be created by users.
So we serialize our entire model first and string replace all instances of the specific fields. Our period fields can show up in many location and it is not predictable what the structure of the data is.
var dataJson = serialize(dataObj);
foreach(pf in periodFields)
{
var encodedPF = pf.replace(".", "ENCODE_DOT");
dataJson.replace(pf, encodedPF);
}
Then later after our data is flattened we replace instances of the encodedPF so we can write the decoded version in our files
Nobody will ever need a field named ENCODE_DOT so it will not be an issue in our case.
The result is the following
color.one will be in the database as colorENCODE_DOTone
When we write our files we replace ENCODE_DOT with .

/home/user/anaconda3/lib/python3.6/site-packages/pymongo/collection.py
Found it in error messages. If you use anaconda (find the correspondent file if not), simply change the value from check_keys = True to False in the file stated above. That'll work!

Related

JSON.stringify is distorting code adding \ inside strings?

I am trying to save local storage info but what happens is I am getting \ added to all the items that are strings I mean as some answers stated it is caused by double stringfy ? issue is my blob action that saves the local storage refuse to handle the it unless is it is stringifed, long story short could this double stringfy needed for the function cause issues later, I have no problem when parsing back but the look of the saved elements looks really weird ?
//const ls = JSON.stringify(localStorage);
// "id":"\"159e17e9-19b7-453d-8e10-a411c7424586\"
// "groups":"{\"bee7bdc4-d888-46e6-93d7-ed0c\" : :[{\"id\":\"0e6e6426-4d79-4eea-9180-06111dd2a0e3\"}]
const config = {a: 'fdfgdg', b: 2}
console.log(JSON.stringify(config))
When saving to localStorage use JSON.stringify (since Storage accepts only String values):
const myData = {some: "data", other: "stuff"};
localStorage.appData = JSON.stringify(myData);
When reading from localStorage, use JSON.parse:
const myData = JSON.parse(localStorage.appData || "{}");
console.log(myData); // {some: "data", other: "stuff"}
Don't be afraid of escaped double-quotes with backslash! Otherwise it would end up in an invalid String format
const test = "this is \"something\""; // properly escaped quotes
Get used to see in console (on in LocalStorage) the escaped strings used for Keys os String properties of a JSON stringified Object literal:
"{\"prop\": \"some value\"}" // Valid stringified JSON
perfectly fine.
Learn more about the JSON format.
JSON, in order to be valid, its keys need to be enclosed in double quotes. JSON.stringify will take care of adding quotes to a JS Object Literal keys for you.
When you are getting a stringfied object and you want him to become an object again, there is another command to do so
JSON.parse(obj)
var obj = {
id: '159e17e9-19b7-453d-8e10-a411c7424586',
groups: '000e17e9-19b7-453d-8e10-a411c7424500'
}
var stringfiedObject = JSON.stringify(obj)
console.log(stringfiedObject)
var objectFromStringfiedObject = JSON.parse(stringfiedObject)
console.log(objectFromStringfiedObject)
There's no "extra backslash", it's just your means of output show that extra backslash, because it is the way it renders string values (you probably use browser console for that, didn't you?).
Be sure, the actual stringified value does not contain any characters that are not supposed to be there.
As others have pointed out, things aren't going as planned because you are stringifying localStorage itself, as well as improperly stringifying and parsing your data.
It would be much easier just to save the object directly to localStorage and then retrieve it as needed, without having to fool around with stringifying and parsing. While these methods are necessary, all they accomplish is to convert your data into the format useable by localStorage anyway, but the data itself stays converted, that is, a float 122.55 is converted into a string "122.55" and it stays that way.
Wouldn't it be so much easier if you could directly store the number 122.55 and retrieve it that way also?
Have a look at localDataStorage, where you can transparently set/get any of the following "types": Array, Boolean, Date, Float, Integer, Null, Object or String. It seamlessly converts your data, stores it, and allows you to retrieve it just the way it went it. Store an object and get it back. Store a date and get it back. Store a number or a boolean and get those back.
Examples:
localDataStorage.set( 'key1', false );
localDataStorage.get( 'key1' ); --> false (boolean)
localDataStorage.set( 'key2', 122.55 );
localDataStorage.get( 'key2' ); --> 122.55 (float)
var obj = {
id: '159e17e9-19b7-453d-8e10-a411c7424586',
groups: '000e17e9-19b7-453d-8e10-a411c7424500'
}
localDataStorage.set( 'key3', obj );
localDataStorage.get( 'key3' ); --> {id: '159e17e9-19b7-453d-8e10-a411c7424586', groups: '000e17e9-19b7-453d-8e10-a411c7424500'} (object)
localDataStorage.set( 'key4', "this is \"something\"" );
localDataStorage.get( 'key4' ); --> 'this is "something"' (string)
All of the conversion work is done in the background for you: just set/get and go.
[DISCLAIMER] I am the author of the utility [/DISCLAIMER]

How to make JSON.parse() to treat all the Numbers as BigInt?

I have some numbers in json which overflow the Number type, so I want it to be bigint, but how?
{"foo":[[0],[64],[89],[97]],"bar":[[2323866757078990912,144636906343245838,441695983932742154,163402272522524744],[2477006750808014916,78818525534420994],[18577623609266200],[9008333127155712]]}
TLDR;
You may employ JSON.parse() reviver parameter
Detailed Solution
To control JSON.parse() behavior that way, you can make use of the second parameter of JSON.parse (reviver) - the function that pre-processes key-value pairs (and may potentially pass desired values to BigInt()).
Yet, the values recognized as numbers will still be coerced (the credit for pinpointing this issue goes to #YohanesGultom).
To get around this, you may enquote your big numbers (to turn them into strings) in your source JSON string, so that their values are preserved upon converting to bigint.
As long as you wish to convert to bigint only certain numbers, you would need to pick up appropriate criteria (e.g. to check whether the value exceeds Number.MAX_SAFE_INTEGER with Number.isSafeInteger(), as #PeterSeliger has suggested).
Thus, your problem may be solved with something, like this:
// source JSON string
const input = `{"foo":[[0],[64],[89],[97]],"bar":[[2323866757078990912,144636906343245838,441695983932742154,163402272522524744],[2477006750808014916,78818525534420994],[18577623609266200],[9008333127155712]]}`
// function that implements desired criteria
// to separate *big numbers* from *small* ones
//
// (works for input parameter num of type number/string)
const isBigNumber = num => !Number.isSafeInteger(+num)
// function that enquotes *big numbers* matching
// desired criteria into double quotes inside
// JSON string
//
// (function checking for *big numbers* may be
// passed as a second parameter for flexibility)
const enquoteBigNumber = (jsonString, bigNumChecker) =>
jsonString
.replaceAll(
/([:\s\[,]*)(\d+)([\s,\]]*)/g,
(matchingSubstr, prefix, bigNum, suffix) =>
bigNumChecker(bigNum)
? `${prefix}"${bigNum}"${suffix}`
: matchingSubstr
)
// parser that turns matching *big numbers* in
// source JSON string to bigint
const parseWithBigInt = (jsonString, bigNumChecker) =>
JSON.parse(
enquoteBigNumber(jsonString, bigNumChecker),
(key, value) =>
!isNaN(value) && bigNumChecker(value)
? BigInt(value)
: value
)
// resulting output
const output = parseWithBigInt(input, isBigNumber)
console.log("output.foo[1][0]: \n", output.foo[1][0], `(type: ${typeof output.foo[1][0]})`)
console.log("output.bar[0][0]: \n", output.bar[0][0].toString(), `(type: ${typeof output.bar[0][0]})`)
.as-console-wrapper{min-height: 100% !important;}
Note: you may find RegExp pattern to match strings of digits among JSON values not quite robust, so feel free to come up with yours (as mine was the quickest I managed to pick off the top of my head for demo purposes)
Note: you may still opt in for some library, as it was suggested by #YohanesGultom, yet adding 10k to your client bundle or 37k to your server-side dependencies (possibly, to docker image size) for that sole purpose may not be quite reasonable.

How to parse and format strings out of irregular CSV in javascript?

I've scraped this allergy data string from a public website:
Cedar 679 gr/m3 High, Grass 20 gr/m3 Medium, Trees 80 gr/m3 Medium, Molds Low.
Sometimes the number of items is fewer, but the general format for trees and grasses is always like this, with commas separating each type of allergen:
TYPE AMOUNT g/m3 LEVEL
Molds is the exception; assume it will always be a string of text. Assume we don't require the molds data at all.
What library or technique would you use to parse this into a neat JSON object, for example:
{
"Cedar": "679",
"Grass": "20",
"Trees": "80"
}
As Sam stated in the comments, it'd be ideal to utilize npmjs.com/package/csv-parser
However, if you want to use vanilla JS, I wrote a basic script that works given your input:
//function takes a csv string and returns a list of Objects
//and only includes values with 4 parts
function parseCsv(csvString) {
let out = {};
let spacedValues = csvString.split(/,\s*/);
let values = spacedValues.map(str => str.split(" "));
values.forEach((value, index) => {
if (value.length === 4) {
//you can change the value from an object to value[1] if you only need the amount
out[`${value[0]}`] = {
AllergenAmount: value[1],
AllergenUnits: value[2],
AllergenLevel: value[3]
}
});
}
// add an else if here if you want to keep values with more/less than 4 parts of the string
});
return out;
}
//wrapper that implements the builtin JSON.stringify method
const csvToJSONString = csvString => JSON.stringify(parseCsv(csvString));
To use it, just pass the csv string into the csvToJSONString function, and it will return a JSON string. You can also change the properties from an object to value[1] if you only needed the amount (commented in code).
I worked with "csvtojsn" module before in a similar situation and it helped a lot.
https://www.npmjs.com/package/csvtojson
You should try csv-parse I'm using it in my current project and it works like a charm.

Best way to remove empty query strings from an API request

In my react app I am tasked with sending multiple GET requests, sometimes with some optional filter params attached. Additionally I'm storing the params in my redux store so that they are able to stack on subsequent requests. Here's the problem: There are times when I'll clear the values of a param but since their keys are still saved to my store I'll get requests sent out like this:
/restaurants/?search=&state_id=2
Notice how the search param value is empty (as expected). I was wondering what would be the best approach in removing these type of lingering params? I looked into lodash's _.omitBy combined with _.isEmpty but this throws a sort of false positive in dealing with numeric values like pagination.
_.omitBy(params, ._isEmpty);
I didn't think that providing how exactly the params are via react/redux was necessary stored but am happy to provide it if it helps.
Note: I'm using axios and passing my params in as an object as opposed to a string:
axios.get('restaurants', {
params
});
Considering your params are stored in an object (as you mentioned in your latest edit), you can just remove properties containing empty strings:
const params = {
search: "",
state_id: 2
};
for (const key of Object.keys(params)) {
if (params[key] === "") {
delete params[key];
}
}
console.info(params);
This alternative has the advantage of being short and easy to maintain.
But for those with a string containing all params already serialized, it's easy to do using regular expressions:
function removeEmptyParams(query) {
return query.replace(/[^=&]+=(?:&|$)/g, "");
}
const testQuery = "f=1&search=&state_id=2&foo=&bar=12";
console.info(removeEmptyParams(testQuery));
Also very simple and easy to maintain.
The best and easiest way is to use a Spread Object literal on every optional param,
like this
params:{
...( CONDITION && {param_key: param_value}),
...( this.state_id != null && {state_id: this.state_id})
}
If condition is TRUE, the encapsulated key:value pair will be unwrapped, if condition is false , there will be no empty value or key.
You might need to parse that manually. Split on the & then split on the = and check if there's a value based on the length of the split - remove accordingly from there. If you're comfortable with regex you can check if there are values after the = instead of splitting.
This solution is a little crude, but it works. Let's assume your query params are stored in a Map, something like:
const params = {
foo: 'bar',
bang: 0,
buzz: '' // this value has been removed from your store
}
You could create an array of keys from your params Map, filter out the items that don't have a value and then join them all back together as query params.
const queryString = Object.keys(params).map(filter => {
if (params[filter] || Number.isInteger(params[filter])) {
return `${filter}=${params[filter]}`;
}
return null;
}).filter(item => item).join('&');
Which would result in foo=bar&bang=0

JSON - Access field named '*' asterisk

I am trying to access a JSON field that has the key '*':
{
"parse": {
"text": {
"*": "text i want to access"
}
}
}
Neither myObject.parse.text.* nor myObject.parse.text[0] works.
I have searched for an hour but haven't found any hint that an asterisk has special meaning. If I just traverse the complete tree and make String comparison with if (key == "*") I can retrieve the text, but I would like to access this field directly. How can I do that?
json.parse.text["*"]
Yucky name for an object member.
Asterisks have no special meaning; it's a string like any other.
myObject.parse.text.* doesn't work because * isn't a legal JS identifier. Dot notation requires legal identifiers for each segment.
myObject.parse.text[0] doesn't work because [n] accesses the element keyed by n or an array element at index n. There is no array in the JSON, and there is nothing with a 0 key.
There is an element at the key '*', so json.parse.text['*'] works.
Try use the index operator on parse.text:
var value = object.parse.text["*"];
try to use
var text = myObject.parse.text['*']
You could do:
var json = {"parse":
{"text":
{"*":"text i want to access"}
}
}
alert(json.parse.text['*']);

Categories

Resources