javascript - Vanskeligheter med JSON.parse?


Jeg har snakket med utviklingsanden min de siste timene og kan ikke for livet få rubber ducky-debugget denne koden. I bunn og grunn returnerer den [object Object] for et subobjekt i JSON. Det spennende er at hvis jeg kopierer og limer inn den loggede rå JSON-teksten før den blir analysert, og deretter parser den, så parses den helt fint.

Her er den ovennevnte koden, med verdiene som mates inn:

/*
We are feeding in:
{
    'src' : './template.html',
    'format' : 'plain',
    'input' : {
        'noun' : 'World'
    },
    'replace' : 'templateExampleSkeleton'
}
*/

// Locals.
let tmpScripts:Array<string> = [];
let tmpScriptIds:Array<string> = [];
let tmpStrings:Array<string> = [];
let tmpStringIds:Array<string> = [];

// Replace scripts with placeholder IDs, and store their contents in a temporary location.
// They will be restored later, because they would cause issues with the JSON parser.
// This isn't used in this case but is used in general.
args = args.replace(/js{{(.|\s)*}}/g, (substring:string) => {
    let tmpScriptId:string = this.#utils.genRandomId(false, tmpScriptIds);
    tmpScripts.push(substring.replace('js{{','').replace('}}',''));
    return `%%{{${tmpScriptId}}}%%`;
})

// Replace 's with "s.
.replace(/'/gm, '"')

// Replace whitespace.
.replace(/(\s|\n|\t|\r)*/gm, '')

// Restore the strings using their IDs.
.replace(/##{{.{32}}}##/gm, (substring:string) => {
    let tmpStringValue:string = '';
    tmpStringIds.forEach((id:string, i:number) => {
        if (substring.includes(id)) tmpStringValue = tmpStrings[i];
    });
    return tmpStringValue;
});

// Add curly brackets so that the JSON parser doesn't yell.
args = '{' + args + '}';

console.log(args); // ==> {"src":"./template.html","format":"plain","input":{"noun":"World"},"replace":"templateExampleSkeleton"}

// Parse the arguments as JSON.
let argsJson = JSON.parse(args);

// Using the new object, iterate through its keys in order to
// restore the scripts that were removed for parsing as JSON.
// This isn't(?) used in this case but is used in general.
Object.keys(argsJson).forEach((argKey, i) => {
    argsJson[argKey] = argsJson[argKey].toString().replace(/%%{{.*}}%%/gm, (substring:string) => {
        substring = substring.replace(/%%{{/, '').replace(/}}%%/, '');
        let tmpScriptValue:string = '';
        tmpScriptIds.forEach((id:string, i:number) => {
            if (id === substring) tmpScriptValue = tmpScripts[i];
        });
        return tmpScriptValue;
    });
});
// Log the object for debug.
console.log(argsJson); // ==> Object { src: "./template.html", format: "plain", input: "[object Object]", replace: "templateExampleSkeleton" }

All hjelp blir veldig satt pris på :^)

Svar #1

For å avslutte dette spørsmålet med et svar, som påpekt av @LexWebb:

Object.keys(argsJson).forEach((argKey, i) => {
    argsJson[argKey] = argsJson[argKey].toString().replace(/%%{{.*}}%%/gm, (substring:string) => {
        substring = substring.replace(/%%{{/, '').replace(/}}%%/, '');
        let tmpScriptValue:string = '';
        tmpScriptIds.forEach((id:string, i:number) => {
            if (id === substring) tmpScriptValue = tmpScripts[i];
        });
        return tmpScriptValue;
    });
});

Bør være:

Object.keys(argsJson).forEach((argKey, i) => {
    if (typeof argsJson[argKey] === 'string') {
        argsJson[argKey] = argsJson[argKey].replace(/%%{{.*}}%%/gm, (substring:string) => {
            substring = substring.replace(/%%{{/, '').replace(/}}%%/, '');
            let tmpScriptValue:string = '';
            tmpScriptIds.forEach((id:string, i:number) => {
                if (id === substring) tmpScriptValue = tmpScripts[i];
            });
            return tmpScriptValue;
        });
    }
});