Two methods to escape JSON in Make

For as well as JSON works with make, I wish there would be a simple module to escape JSON. Sometimes you grab some text somewhere and want to fill it into some JSON somewhere else. Create JSON isn’t always an option with more dynamic structures, and in those cases, I’ve found there are options to escape JSON.

We can take some inspiration from this post: Do you know a solid way to Create JSON? - #11 by Runcorn

and use a chain of replace functions to try and escape JSON.

{{replace(replace(replace(replace(replace(replace(replace(49.`3`; "/\n/g"; space); "/\r/g"; space); "/\t/g"; space); "/\f/g"; space); "/\//g"; "/"); "/\\/g"; "\\"); "/""/g"; "\""")}}

It’s ugly, but it works decently well and doesn’t take up any extra operations.

If an extra operation isn’t much of an issue, I prefer going with a different option. The Create JSON module escapes JSON for us reliably, but it does put it inside a JSON string.

So if we create an extremely simple data structure that only consists of one string, we can fill in some data.

Data structure:

Then, we can put some text in there that needs escaping.

Run it once and the output should be something like this:

{"Escape":"She said, \"Hello, how are you?\"He replied, \"I'm good, thanks!\"Let's meet at 5:00 pm."}

Which is great! Now all we need is to be able to remove the JSON bits at the start and at the end. To achieve this, we can use a replace function:

{{replace(2.json; "/^\{""Escape"":""|""}$/g"; "")}}

The end result is some nicely escaped JSON:

image

This one is more reliable than the first option but does require an extra operation, so there’s something to be said for both.

I hope this helps out anyone else!

1 Like

The third way is to create a custom function (Enterprise) to do either the “chain of replace functions”, or simply call

JSON.stringify(object)

samliewrequest private consultation

Join the unofficial Make Discord server to chat with other makers!

2 Likes

I wish we had a function for this outside of Enterprise. Would make my life a bit easier!

Why not use the Transform to JSON module in the JSON app? Doesn’t that create properly escaped JSON text? And you can throw any object (array, collection, anything really) and it will create perfect JSON for you without needing to know anything about the incoming object.

No need for functions, no need for replace(), no need for Enterprise. It’s all there.

Here’s an array being passed into it with nested array:

Have a look at this scenario snippet. Copy and paste into a scenario
{
    "subflows": [
        {
            "flow": [
                {
                    "id": 1,
                    "module": "util:SetVariables",
                    "version": 1,
                    "parameters": {},
                    "mapper": {
                        "variables": [
                            {
                                "name": "textstring",
                                "value": "She said \"Hello, how are you?\" He said \"I'm good thanks.\" Let's meet at 5:00pm."
                            }
                        ],
                        "scope": "roundtrip"
                    },
                    "metadata": {
                        "designer": {
                            "x": 0,
                            "y": 0
                        },
                        "restore": {
                            "expect": {
                                "variables": {
                                    "items": [
                                        null
                                    ]
                                },
                                "scope": {
                                    "label": "One cycle"
                                }
                            }
                        },
                        "expect": [
                            {
                                "name": "variables",
                                "type": "array",
                                "label": "Variables",
                                "spec": [
                                    {
                                        "name": "name",
                                        "label": "Variable name",
                                        "type": "text",
                                        "required": true
                                    },
                                    {
                                        "name": "value",
                                        "label": "Variable value",
                                        "type": "any"
                                    }
                                ]
                            },
                            {
                                "name": "scope",
                                "type": "select",
                                "label": "Variable lifetime",
                                "required": true,
                                "validate": {
                                    "enum": [
                                        "roundtrip",
                                        "execution"
                                    ]
                                }
                            }
                        ],
                        "interface": [
                            {
                                "name": "textstring",
                                "label": "textstring",
                                "type": "any"
                            }
                        ]
                    }
                },
                {
                    "id": 2,
                    "module": "json:TransformToJSON",
                    "version": 1,
                    "parameters": {
                        "space": ""
                    },
                    "mapper": {
                        "object": "{{1.textstring}}"
                    },
                    "metadata": {
                        "designer": {
                            "x": 300,
                            "y": 0,
                            "messages": [
                                {
                                    "category": "last",
                                    "severity": "warning",
                                    "message": "A transformer should not be the last module in the route."
                                }
                            ]
                        },
                        "restore": {
                            "parameters": {
                                "space": {
                                    "label": "Empty"
                                }
                            }
                        },
                        "parameters": [
                            {
                                "name": "space",
                                "type": "select",
                                "label": "Indentation",
                                "validate": {
                                    "enum": [
                                        "tab",
                                        "2",
                                        "4"
                                    ]
                                }
                            }
                        ],
                        "expect": [
                            {
                                "name": "object",
                                "type": "any",
                                "label": "Object"
                            }
                        ]
                    }
                }
            ]
        }
    ],
    "metadata": {
        "version": 1
    }
}


Alex Sirota
Director of NewPath Consulting - we are :superhero: Make Heroes! :woman_superhero:t4:

:heart_on_fire: Check out my series of videos and scenario walkthroughs for Make Newbies :heart_on_fire:

My Solutions on Make Community

2 Likes

Hi there! Is there a way to do the opposite of this? I mean like making sure the “json object” from the scenario is not stringified (or at least converted again in the module) before invoking the main custom app api? My problem is that my parameter gets escaped - twice before invoking …

I’m not exactly sure what you mean. Can you show what’s happening in a scenario example. I assume you’re making a custom app so this maybe a good idea to start a new thread in the appropriate category.

Thank you for your reply @alex.newpath ! I tried adding this issue in this post: Sending a «json object» through a custom app to a «json type" parameter fails, how to structure json? - #4 by samliew