Alexander Art
Alexander Art

Reputation: 1589

Node.js How To serialize colon separated key value pairs to JSON

Given (as a post response body):

RESULT: OK
RESULT_PS: FINISHED
RESULT_CODE: 000

I need to serialize it to json, I use node's request to get this from server. Surely I can parse it string by string.

  1. But isn't there an easier way?
  2. Maybe ready serializer or something to serialize such data to JSON?
  3. What format is this?

Upvotes: 0

Views: 1561

Answers (4)

Alexander Art
Alexander Art

Reputation: 1589

If you use node.js there is handy module called querystring:

const querystring = require('querystring'),
    payload =
        "RESULT: OK\n\r" +
        "RESULT_PS: FINISHED\n" +
        "RESULT_CODE: 000\n";

let parsed = querystring.parse(payload, '\n', ':', {decodeURIComponent: s =>  s.trim()});

console.log(parsed);

For browsers there is a lot of good methods described in answers. Here is another one (vanilla JS):

var payload =
	"RESULT: OK\n\r" +
	"RESULT_PS: FINISHED\n" +
	"RESULT_CODE: 000\n";

var browserParsed = payload.split("\n")
	.map(function (s) {
		return s.trim().split(":");
	})
	.filter(function (s) {
		return s.length && s.length > 1;
	})
	.reduce(function (acc, c) {
		acc[ c[ 0 ].trim() ] = c[ 1 ].trim();
		return acc;
	}, {});

console.log(browserParsed);

Upvotes: 0

nikc.org
nikc.org

Reputation: 16993

As far as I can tell, this is just a delimited plain text response. (Where are you getting it from? Transaction response?) However, since it's that simple it's easily parseable with a quick map-reduce operation.

function trim(str) {
    return str.replace(/^\s+|\s+$/g, "");
}

function nonEmpty(str) {
    return null != str && str.length > 0;
}

function splitKeyValue(row) {
    var tokens = row.split(":").map(trim);

    // My assumption that a row should only contain 2 colon separated tokens
    if (tokens.length > 2) {
        throw new Error("Malformed row: " + row);
    }

    return tokens;
}

function merge(acc, item) {
    // Normalise key to lower case, to guarantee spelling
    acc[item[0].toLowerCase()] = item[1];

    return acc;
}

function parseResponse(payload) {
    return payload.split("\n").
        filter(nonEmpty).
        map(splitKeyValue).
        reduce(merge, {});
}

Using the snippet of code above, the result should be:

var payload = 
    "RESULT: OK\n" +
    "RESULT_PS: FINISHED\n" +
    "RESULT_CODE: 000\n";

var parsed = parseResponse(payload);

console.log(parsed);

// Output:
// {
//   result: "OK",
//   result_ps: "FINISHED",
//   result_code: "000"
// }

// Each separate field is then accessible from it's name

console.log(parsed.result); // Output: "OK"

Upvotes: 1

Alexander Art
Alexander Art

Reputation: 1589

Ok, didn't find any ready solution. So wrote this function:

parseResponse = function(response) {
    var result = { };

    response.replace(/([^\s:]+)\s*:\s*([^\n\s]+)/gi, function() {
        var key = arguments[1], value = decodeURIComponent(arguments[2]);
        result[key] = !isNaN(parseFloat(value)) && isFinite(value) ? parseFloat(value) : value;
    });
    return result;
}

Upvotes: 0

KlwntSingh
KlwntSingh

Reputation: 1092

filter each line from following code

var jsonObject = {}

function parser(str){
var arr = str.split(":");
jsonObject[arr[0]] = arr[1];
}

your final jsonObject is json you needed.
Make sure that you need to pass RESULT: OK, RESULT_PS: FINISHED,RESULT_CODE: 000 as seperate strings from parser.

Upvotes: 1

Related Questions