Copy link to clipboard
Copied
I have ran a test with two different JSON objects.
In my js I run this:
csiRun.evalScript(`setupPlateTemplate('${jsonOrders}')`);
then my JSX I run the following:
function setupPlateTemplate(orders) {
try {
var orderParsed = JSON.parse(orders);
alert(orderParsed);
} catch(error) {
alert('Cannot parse data, error: ' + error)
}
}
When I run it with this:
const testMe = [{order: '35'}, {something: 'ya here'}];
const jsonOrders = JSON.stringify(testMe);
It works perfect. From jsx I can alert orderParsed[0]['order'] and I get 35. JSON.parse works, all good.
However when I run a more complex JSON data:
[{
"order": "#110008",
"productId": "9338073870",
"customInputs": [{
"value": "THE DON DJ"
}, {
"value": ""
}, {
"value": "https://example.com/02830277864684594.png"
}],
"quantity": 1
}, {
"order": "#110009",
"productId": "1308169306180",
"customInputs": [{
"value": "HWDHWP"
}, {
"value": ""
}, {
"value": "https://example.com/3288503754929334.png"
}],
"quantity": 1
}, {
"order": "#110010",
"productId": "9338073870",
"customInputs": [{
"value": "MASON'S "
}, {
"value": "11/11/19"
}, {
"value": "https://example.com/4215610236292262.png"
}],
"quantity": 1
}, {
"order": "#110045",
"productId": "9503265230",
"customInputs": [{
"value": "Jun"
}, {
"value": "1976"
}, {
"value": "CREEPSHOW"
}, {
"value": "KUSTOMS"
}, {
"value": ""
}],
"quantity": 1
}]
This does not work. No error no catch it just doesn't function.
The library I'm using for json is this by Douglas C.
Any ideas what I'm doing wrong?
Escape single quate in your JSON (MASON'S) and retry.
Probably, Your template literal closed this place and you can't pass correct JSON string.
Copy link to clipboard
Copied
Hi again, where is the JSON coming from? Are you reading from a .json file, or are you constructing and stringifying it at runtime?
Copy link to clipboard
Copied
We're becoming good friends.. lol. It's coming from an ajax call.
var orders is built form that ajax call.
Specifically I build it like this:
orders['orderDetails'] = [];
if(item.node.product) {
if(item.node.product.tags.includes("Hat")) {
const orderDetails = {
order: order.node.name,
productId: item.node.product.id.replace('gid://shopify/Product/','') ,
customInputs: item.node.customAttributes,
quantity: item.node.quantity,
}
orders.orderDetails.push(orderDetails);
}
Copy link to clipboard
Copied
Admittedly this one does throw me for a loop a bit, since I made a quick attempt to do it myself and got the same result. This is pretty odd -- I've passed large JSONs between JS/JSX with no issue, but in trying yours the entire script stops executing when passing it through as a string. I'm not sure what the cause of it would be, unless Crockford's function doesn't support nested Arrays (similar to other database JSON structures like Firebase). To make sure this is a parsing issue, some things I'd try:
I'm supposed to be doing homework right now! But if I get everything done and have more time I'll come back to this tonight or tomorrow. As of right now, it's hard to tell if the issue originates in Crockford's JSON implementation, or if some kind of error is thrown at the level of the evalScript call itself -- but once you can figure out which, we'll be closer to a solution
Copy link to clipboard
Copied
Escape single quate in your JSON (MASON'S) and retry.
Probably, Your template literal closed this place and you can't pass correct JSON string.
Copy link to clipboard
Copied
Are you referring to this?
csiRun.evalScript(`setupPlateTemplate(\'${jsonOrders}\')`);
Copy link to clipboard
Copied
This is a very good catch! I didn't notice it. You have a line in the JSON like this:
"customInputs": [{
"value": "MASON'S "
}, {
Since single-quotes are used in the evalScript, it likely pairs the first single quote of the evalScript with this one. He probably means to add the escape to the above though, like so:
"customInputs": [{
"value": "MASON\'S "
}, {
Since you don't know the content before it arrives, you could sanitize your JSON recursively prior to sending it via the escape() method. This is a bit sloppy with if/else and improvised/untested (there's likely a much better function or library out there for it) but maybe something like:
function sanitizeJSON(obj) {
Object.keys(obj).forEach(key => {
if (typeof obj[key] === 'object' && !isArray(obj[key]))
sanitizeJSON(obj[key])
else if (typeof obj[key] === 'string')
obj[key] = escape(obj[key])
else if (isArray(obj[key]))
obj[key].forEach(entry => {
if (typeof obj[key][entry] === 'string')
obj[key][entry] = escape(obj[key][entry])
else if (typeof obj[key][entry] === 'object')
sanitizeJSON(obj[key][entry])
})
})
}
Copy link to clipboard
Copied
Thank you for outlining this code. I tried this first and it worked:
csiRun.evalScript(`setupPlateTemplate(\'${jsonOrders}\')`);
I'll use what you wrote above if I run into any problems.
Copy link to clipboard
Copied
Actually my assumption was incorrect. After I ran it on another ajax call I had the same problems, I ended up just escaping the single quotes and it worked.