Search code examples
javascriptjsonsequelize.jsstringify

Replace Symbol Keys in Object With Text


I have the following object like this:

{ where: { [Symbol(or)]: [ [Object], [Object] ] },hooks: true, rejectOnEmpty: false }

I'm calling JSON.stringify on this, and it gets converted to:

{"where":{},"hooks":true,"rejectOnEmpty":false}

I think this is because [Symbol(or)] evaluates to undefined so stringify removes it.

This value is coming from Sequelize operators, specifically Op.or. Is there a way stringify can convert this to a String so I would instead receive:

{"where":{"[Symbol(or)]": [[<<stringifiedObject>>], [<<stringifiedObject>>]]},"hooks":true,"rejectOnEmpty":false}

I know I could pass a function to JSON.stringify which would replace undefined with something, but I would like to maintain the original Symbol in the string replacement, so that I can distinguish between Symbol(and) and Symbol(or), even though both would evaluate to undefined.


Solution

  • Solved with the following function:

    const cleanObject = (obj) => {
        try {
            const keys = Reflect.ownKeys(obj);
            const ret = {};
            keys.forEach((key) => {
                let val = obj[key];
                if (Object.prototype.toString.call(val) === '[object Object]') {
                    val = cleanObject(val);
                }
                if (typeof key === 'symbol') {
                    const newKey = `${String(key)}`;
                    ret[newKey] = val;
                } else {
                    ret[key] = val;
                }
            });
            return ret;
        } catch (ex) {
            console.log(ex);
        }
    };
    

    Reflect.ownKeys returns all keys, including Symbols.

    Next, I check if a given key is a Symbol and replace it with a string. I also call the function recursively to apply the same logic to all nested objects.