Create object from object literal string - javascript

Is there an easy way to parse an object literal as a string into a new object?
I'm looking to turn a string like the following:
'{ name: "A", list: [] }'
Into an object like:
{ name: 'A', list: [] }
Note:
I'm not looking for JSON.parse() as it accepts json strings and not object literal strings. I was hoping that eval would work but unfortunately it does not.

eval does indeed work, with one tweak: the problem is that the standalone line
{ name: 'A', list: [] }
gets parsed as the interpreter as the beginning of a block, rather than as the start of an object literal. So, just like arrow functions which implicitly return objects need to have parentheses surrounding the objects:
arr.map(item => ({ item }))
you need to put parentheses around the input string, so that the content inside (that is, the object, which starts with {) is parsed properly as an expression:
const input = '{ name: "A", list: [] }';
const obj = eval('(' + input + ')');
console.log(obj);
Of course, as with all cases when eval is involved, you should be very sure that the input is trustworthy first.

While I would never do this IRL, you could perhaps try this:
var myObjLiteralString = '{ name: "A", list: [] }';
var myObj;
eval('myObj = ' + myObjLiteralString);
console.log(myObj);

Related

Accessing object property through bracket notation regardless of the number of brackets

An object's properties can be accessed through bracket notation by doing the following:
let obj = {a: "test"}
obj["a"]
However, I was not aware that the same object's property could also be accessed by doing:
let v = ["a"] // An array
obj[v]
or
obj[["a"]]
or
obj[[[[[[[[[["a"]]]]]]]]]]
Just wondering, why is that?
I stumbled on this behaviour after storing an array into a variable and mistakingly using the variable/array, rather than the first item of the array, to access an object's property and surprisingly... it didn't throw an error but returned the value.
All object keys are strings. When you use bracket notation foo[bar] the variable you try to fetch will be converted to a string:
const bar = {
toString() {
return "hello";
}
}
const foo = {
hello: "world"
}
console.log(foo[bar]);
When arrays are converted to a string, join(",") is implicitly called on them. And if an array has a single value, the result is the single value as a string:
const arr = ["hello"];
console.log(arr.toString());
console.log(String(arr));
console.log(arr.join(","));
If you have nested arrays, each with one item, you'd still get a single string out of the conversion, since join() also converts all the members into strings, so with String([["hi"]]) you (roughly) get:
[["hi"]].join(",") -> String(["hi"]) -> ["hi"].join(",") -> String("hi")
So, if you supply an array as a key, it works, as long as you only have a single value in each array:
const foo = {
hello: "world"
};
const arr = [[["hello"]]];
console.log(foo[arr]);
console.log(foo[String(arr)]);
console.log(foo[arr.toString()]);
console.log(foo[arr.join(",")]);
console.log(['a'].toString()); // "a"
It's because a key needs to be a string and javascript does type coercion, converting the array to a string automatically.

adding an object to an empty <a/> in jQuery

I'm attempting
var a = $("<a/>");
then I'm trying to fill this empty variable with the contents of an object, set to variable 'obj'
obj = {
Name: " Ben",
number: 666,
}
I have tried to append a using the various methods
a.append(obj);
a.append("("+obj+")");
but if I then do:
console.log(a)
there is no way to tell if the object is now in the link tag. If I look in the console on the site I can see
([object Object])
rather than the contents. Am I missing something?
By just appending the object it is implicitly coerced to a string, hence you see [Object object].
You need to convert the object to a legible string manually. You can do that by using JSON.stringify(), like this:
var $a = $('<a href="#"/>').appendTo('body');
var obj = {
Name: " Ben",
number: 666
};
$a.text(JSON.stringify(obj));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
You have to use property of object
like below
var a = $("<a/>");
obj = {
Name: " Ben",
number: 666,
}
a.text(obj.Name + ' ' + obj.number);

Declare object from string

I want to declare 1 javascript object which its properties are generated from one sequence that was created earlier
example:
var x = '"property1": "abc",
"property2": "def",
"property3": "xyz",
';
var obj = {
// insert content of x here
}
what can i do?
You can declare
var x = {property1: "abc",
property2: "def",
property3: "xyz"};
var obj = {
data:x
}
Assuming you have a string that is a valid sequence of key/value pairs that are double-quoted then you can easily make it into JSON by concatenating '{' and '}', after removing any trailing comma (I notice your last property has a trailing comma). Then you can create an object by parsing that JSON. So:
var x = // Your string of quoted, comma-separated key/value pairs here
var obj = JSON.parse('{' + x.replace(/,\s+$/,'') + '}');
General note of disapproval: I don't know why you would create your properties as a string rather than just adding properties directly to an object, and in general you shouldn't hand-create JSON, and I'd like to note that a string literal enclosed by single-quotes can't have line-breaks in it so I'm hoping you just showed it that way for ease of reading.
Use JSON string here
var x = `{"property1": "abc",
"property2": "def",
"property3": "xyz"
}`;
var obj = JSON.parse(x)
After reading your comments OP I think you may be after bracket notation.
You can access an object's property via dot notation
obj.prop = foo;
var v = obj.prop;
Or you can use bracket notation
var propName = "prop"
obj[propName] = foo;
var v = obj[propName];
Note this is not accessing an array.
So you could do it this way
var data = [["property1", "abc"],["property2","def"],["property3","xyz"]]
var obj = {};
data.forEach(pk => { obj[pk[0]] = pk[1]; });
console.log(obj.property1); // output "abc"
You can use the eval API to parse the string too.
See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval
The eval() function evaluates JavaScript code represented as a string.
Example:
let y = "";
let x = ' "property1": "abc", "property2": "def", "property3": "xyz" ';
eval('y={' + x + '}');
Output:
Please note that using eval can be dangerous as noted in its documentation:
eval() is a dangerous function, which executes the code it's passed
with the privileges of the caller. If you run eval() with a string
that could be affected by a malicious party, you may end up running
malicious code on the user's machine with the permissions of your
webpage / extension.
Example: exposing it as a REST service to allow end-users to hit it with any 'object string' which can instead be a piece of malicious code - like downloading virus.

Declaring a property in a Javascript object that ISN'T a string

I'm trying to build a javascript object to be passed along to MongoDB. This database uses an operator $or which lets you search for multiple keys in a property at once.
Because of this, the $or operator cannot be in quotation marks, because it is actually an operator in the lookup function.
For reference, the lookup function looks like this:
db.inventory.find( { price:1.99, $or: [ { qty: { $lt: 20 } }, { sale: true } ] } )
I have found a way to 'build' an $or property out of some variables, but for some reason the property name keeps being treated as though it's a string. Here's my code:
var criteria = { $or: []};
properties.forEach(function(property) {
var propParts = property.split('=');
if(!(propParts[1].indexOf('&') === -1)){
var value = propParts[1].match(/[-'"\w\s]+/g);
for (var i = 0; i<value.length; i++){
var tempObj = {};
tempObj[propParts[0]] = value[i];
criteria.$or.push(tempObj);
}
}else{
criteria[propParts[0]] = new RegExp(propParts[1], "i");
}
});
if(criteria.$or.length<=0){
delete criteria.$or;
}
console.log(criteria);
In my console, this is being output as:
{ '$or': [ { designer: 'abc' }, { designer: 'def' } ] }
I am using similar code elsewhere (with $push instead of $or) and it works just fine, I'm declaring it in exactly the same way.
Is it possible to ensure that the property isn't being treated as a string? How can I achieve this here?
Javascript object keys are always coerced to strings. That you can specify some keys without quotes in object literals {key: 0} or using dot notation object.key = 0 is merely syntactic sugar for keys that also happen match the production for identifiers. '$or' is a valid javascript identifier, so you can say either:
{$or: [...]}
or
{"$or": [...]}
or
{'$or': [...]}
and they're all equivalent.

Curly braces inside JavaScript arguments for functions

What do the curly braces surrounding JavaScript arguments for functions do?
var port = chrome.extension.connect({name: "testing"});
port.postMessage({found: (count != undefined)});
A second possible answer has arisen since this question was asked. Javascript ES6 introduced Destructuring Assignment.
var x = function({ foo }) {
console.log(foo)
}
var y = {
bar: "hello",
foo: "Good bye"
}
x(y)
Result: "Good bye"
The curly braces denote an object literal. It is a way of sending key/value pairs of data.
So this:
var obj = {name: "testing"};
Is used like this to access the data.
obj.name; // gives you "testing"
You can give the object several comma separated key/value pairs, as long as the keys are unique.
var obj = {name: "testing",
another: "some other value",
"a-key": "needed quotes because of the hyphen"
};
You can also use square brackets to access the properties of the object.
This would be required in the case of the "a-key".
obj["a-key"] // gives you "needed quotes because of the hyphen"
Using the square brackets, you can access a value using a property name stored in a variable.
var some_variable = "name";
obj[ some_variable ] // gives you "testing"
Curly braces in javascript are used as shorthand to create objects. For example:
// Create an object with a key "name" initialized to the value "testing"
var test = { name : "testing" };
alert(test.name); // alerts "testing"
Check out Douglas Crockford's JavaScript Survey for more detail.
var x = {title: 'the title'};
defines an object literal that has properties on it. you can do
x.title
which will evaluate to 'the title;
this is a common technique for passing configurations to methods, which is what is going on here.

Categories