Search code examples
javascriptnode.jsblobbuffer

Can't extract string from buffer


How can I get the string extracted to the original value?

const buf = Buffer.from('Calling Mr. Jones', 'utf8');
const ob = {b: buf};

console.log(ob.b.toString());
    // outputs "Calling Mr. Jones"

const obS = JSON.stringify(ob);

const obExtracted = JSON.parse(obS);

console.log(obExtracted.b.toString());
    // outputs "[object Object]" instead of "Calling Mr. Jones"

console.log(obExtracted.b);
    /* outputs:

        {
          type: 'Buffer',
          data: [
             67,  97, 108, 108, 105, 110,
            103,  32,  77, 114,  46,  32,
             74, 111, 110, 101, 115
          ]
        }
    */

Solution

  • You can use a JSON.parse reviver function

    Note: this code may be more complex than needed, but, I tried to make it flexible enough to handle types of data, not just Buffer

    const reviver = (key, value) => {
        const defaultReviver = (data, type) => new globalThis[type](data);
        const revivers = {
            // new Buffer is deprecated, so use Buffer.from
            Buffer: data => Buffer.from(data), 
            //
            // add any other exceptions (I can't think of any)        
        };
    
        if (typeof value !== "object") {
            return value;
        }
        const keys = Object.keys(value);
        if (keys.length !== 2 || !keys.includes("type") || !keys.includes("data")) {
            return value;
        }
        // only concern ourselves with global classes with `.toJSON`
        // to be honest, perhaps Buffer is the only one
        // but, this code should be flexible
        if (typeof globalThis[value.type]?.prototype?.toJSON !== 'function') {
            return value;
        }
        try {
            const fn = revivers[value.type] || defaultReviver;
            return fn(value.data, value.type);
        } catch {
            return value;
        }
    };
    

    Part of your code with a single change

    const buf = Buffer.from("Calling Mr. Jones", "utf8");
    const ob = { b: buf };
    const obS = JSON.stringify(ob);
    
    const obExtracted = JSON.parse(obS, reviver); // use reviver
    
    console.log(obExtracted.b.toString());