Reputation: 13
How can I convert a string to an object when there is a reference inside the string?
String:
{ "field": "OrderNumber", "operator": "eq", "value" : e.data.OrderNumber }
I already tried with JSON.parse and eval but I'm still getting an error on "e.data.OrderNumber"
Upvotes: 1
Views: 218
Reputation: 13
It's worked with this:
private static rev(key: any, value: any): any {
if (key === "value") {
let [props, val] = [value.split(".").slice(1), void 0];
for (let prop of props) {
val = val === undefined ? this[prop] : val[prop];
}
return val;
}
return value;
}
And i use JSON.parse(relationString, this.rev.bind(e)) to call the method
Upvotes: 0
Reputation: 1
Set "value"
to empty string. Call JSON.parse()
with str
as parameter. Set .value
of resulting object.
var str = `{"field":"OrderNumber","operator":"eq","value":""}`;
var obj = JSON.parse(str);
obj.value = e.data.OrderNumber;
An alternative approach would be to utilize JSON.parse()
reviver
function, with this
set to e
using Function.prototype.bind()
. If key
is equal to "value"
within the function create a variable val
where the value is initially set to undefined
. Use .split()
to create an array of the property representations within the key
"value"
. .slice()
the indexes following 0
from resulting array. Use for..of
loop to get the value of obj[arrayIndex]
through obj[arrayIndex][propN]
where propN
is the nth index of array; assign the value to the variable val
. Return the variable val
following loop, else return value
parameter.
var e = {
data: {
OrderNumber: 1
}
};
var str = '{"field":"OrderNumber","operator":"eq","value":e.data.OrderNumber}';
str = str.replace(/((\w+.[\w.]+)(?=(\s+|)\}))/g, "\"$1\"");
var rev = function(key, value) {
if (key === "value") {
let [props, val] = [value.split(".").slice(1), void 0];
for (let prop of props) {
val = val === undefined ? this[prop] : val[prop];
}
return val;
}
return value;
};
var obj = JSON.parse(str, rev.bind(e));
console.log(obj);
You can also retrieve and set the value without having the property name using String.prototype.replace()
with RegExp
/((\w+.[\w.]+)(?=(\s+|)\}))/g
to match word character followed by .
followed by one of more word characters and .
characters; String.prototype.match()
to match word characters and create an array from the matches; Array.prototype.reduce()
to iterate each depth of object properties for the .length
of the array, return the last value at depth of array .length
corresponding to object properties within original string.
const e = {
data: {
OrderNumber: 1
}
};
let str = '{ "field": "OrderNumber", "operator": "eq", "value" : e.data.OrderNumber }';
str = str.replace(/((\w+.[\w.]+)(?=(\s+|)\}))/g, function(match) {
let [,...props] = match.match(/[^.]+/g);
return props.reduce(function(obj, prop) {
return obj[prop]
}, e);
});
let obj = JSON.parse(str);
console.log(obj);
With resulting array from calls to .match()
, .shift()
, .split()
on original string you can get the property values from e
with destructuring assignment; use .replace()
to set replacement string with corresponding value from e
; then call JSON.parse()
with resulting string as value to create a javascript
object.
const e = {
data: {
OrderNumber: 1
}
};
let str = '{ "field": "OrderNumber", "operator": "eq", "value" : e.data.OrderNumber }';
let re = /((\w+.[\w.]+)(?=(\s+|)\}))/g;
let obj = JSON.parse(str.replace(re
, (() => ([,...props] = str.match(re).shift().split(".")
, {[props[0]]:{[props[1]]:prop}} = e, prop)
)()
));
console.log(obj);
Upvotes: 2
Reputation: 8660
https://jsfiddle.net/hd3v29ra/2/
You would simply need to adjust the order number to reside within quotations when you insert it into the string to be converted into an object:
example 1 using concatenated strings
var obj = JSON.parse('{"field": "OrderNumber","operator": "eq","value":"' + e.data.orderNumber + '"}');
example 2 using ES6 Template Literals
var obj = JSON.parse(`{"field": "OrderNumber", "operator":"eq","value":"${e.data.orderNumber}"}`);
Upvotes: 1
Reputation: 207501
Only real option you have to to use eval or new Function since what you have is not valid JSON due to the object property reference. There are security concerns with new Function and eval, so that is why this solution is not the best idea.
var str = '{ "field": "OrderNumber", "operator": "eq", "value" : e.data.OrderNumber }';
var e = { data : { OrderNumber : 123456 } };
var x = new Function("return " + str)();
console.log(x.value);
BUT if I were you, I would see if there is a better way to do what you need instead of using a bandaid to fix the problem. What I would do is have an object and add the property or extend it.
var e = { data : { OrderNumber : 123456 } };
var obj = { "field": "OrderNumber", "operator": "eq" };
obj.value = e.data.OrderNumber;
or
var e = { data : { OrderNumber : 123456 } };
var obj = { "field": "OrderNumber", "operator": "eq" };
var result = {};
Object.assign(result, obj, {value : e.data.OrderNumber} );
Upvotes: 2
Reputation: 288100
There is the unsafe and evil eval
:
var e = {data: {OrderNumber: 123}};
var str = '{ "field": "OrderNumber", "operator": "eq", "value" : e.data.OrderNumber }';
console.log(eval('(' + str + ')'));
Do not use this with untrusted strings, it may run arbitrary code.
Upvotes: 0