Mankind1023
Mankind1023

Reputation: 7732

Javascript - Iterate over deep nested object and change certain unknown values

I have an object with an unknown number of levels and types (array, object, string), here is an example:

var data = {
    ffs: false,
    customer: {
        customer_id: 1544248,
        z_cx_id: '123456',
    },
    selected_items: {
        '3600196': [{
            id: 4122652,
            name: 'Essential Large (up to 8\'x10\')',
            selected: true
        }]
    },
    service_partner: {
        id: 3486,
        name: 'Some String',
        street: '1234 King St.',
    },
    subject: 'Project-2810191 - Orange Juice Stain (Rug)',
    description: 'Product Type: \n\nIssue: (copy/paste service request details here)\n\nAction Required:',
}

I have to loop through every property using plain javascript and sanitize each string that has a ' to have '' (for use in a PostGres Query), I change it with the following code:

val = val.replace(/'/g, "''");

And I can loop through the object and display them with this, although this may not be the best solution:

function iterObj(obj) {
  for (var key in obj) {
    console.log(key + ': ' + obj[key]);
    if (obj[key] !== null && typeof obj[key] === "object") {
      // Recurse into children
      iterObj(obj[key]);
    }
  }
}

iterObj(data);

The problem is that I don't know how to actually do the sanitization part and update the original data array since this is going in circles.

I found plenty of people asking similar questions but couldn't quite get their answers to work in my case.

Any help is appreciated.

Upvotes: 12

Views: 18726

Answers (3)

Karl Adler
Karl Adler

Reputation: 16786

try using the reviver method to avoid accidentally breaking your JSON structure.

var data = {ffs: false, customer: {customer_id: 1544248, z_cx_id: '123456',}, selected_items: {'3600196': [{id: 4122652, name: 'Essential Large (up to 8\'x10\')', selected: true}]}, service_partner: {id: 3486, name: 'Some String', street: '1234 King St.',}, subject: 'Project-2810191 - Orange Juice Stain (Rug)', description: 'Product Type: \n\nIssue: (copy/paste service request details here)\n\nAction Required:',};

data = JSON.stringify(data);
data = JSON.parse(data, (key, value) => {
    return typeof value === 'string' ? value.replace(/'/g, '\\"') : value;
});

console.log(data);

Upvotes: 5

Nina Scholz
Nina Scholz

Reputation: 386560

You could check for an object and call the recursion again.

function iter(o) {
    Object.keys(o).forEach(function (k) {
        if (o[k] !== null && typeof o[k] === 'object') {
            iter(o[k]);
            return;
        }
        if (typeof o[k] === 'string') {
            o[k] = o[k].replace(/'/g, "''");
        }
    });
}

var data = { ffs: false, customer: { customer_id: 1544248, z_cx_id: '123456' }, selected_items: { '3600196': [{ id: 4122652, name: 'Essential Large (up to 8\'x10\')', selected: true }] }, service_partner: { id: 3486, name: 'Some String', street: '1234 King St.' }, subject: 'Project-2810191 - Orange Juice Stain (Rug)', description: 'Product Type: \n\nIssue: (copy/paste service request details here)\n\nAction Required:' };

iter(data);
console.log(data);

Upvotes: 29

KevBot
KevBot

Reputation: 18888

Why not convert the entire object to JSON, and then replace all ''s with a "? Then, you simplify the entire operation, without doing recursion.

var data = {ffs: false, customer: {customer_id: 1544248, z_cx_id: '123456',}, selected_items: {'3600196': [{id: 4122652, name: 'Essential Large (up to 8\'x10\')', selected: true}]}, service_partner: {id: 3486, name: 'Some String', street: '1234 King St.',}, subject: 'Project-2810191 - Orange Juice Stain (Rug)', description: 'Product Type: \n\nIssue: (copy/paste service request details here)\n\nAction Required:',};

data = JSON.stringify(data);
// or replace with two ' or whatever else
data = data.replace(/'/g, '\\"');
data = JSON.parse(data);

console.log(data);

Upvotes: 6

Related Questions