Search code examples
javascriptstringpaypalpaypal-adaptive-payments

Convert string to object hierarchy


I have the following string returned from an API and I want to convert it to an object hierarchy using javascript.

The string received is:

"paymentInfoList.paymentInfo(0).receiver.amount":"12.00"

I want to convert it to a javascript object like:

{
    paymentInfoList: {
        PaymentInfo: [{
             receiver: {
                 amount: 12.0
             }
        }]
    }
}

I could write my own parser but wonder if there is some code already out there.

Update

Based on the answer from @JasonCust here is a parser to parse a full response from the PayPal Adaptive Payments Pay method: https://github.com/danielflippance/paypal-ap-parser


Solution

  • I don't know of an existing parser that handles that format. Maybe something on Paypal's developer site? If you roll your own you could do so using a recursive function like the example below. I haven't tested it thoroughly but it's a POC that it's easy enough to do.

    function setObjVal(obj, paths, val) {
      var path;
      var arrayInfo;
    
      if (paths.length === 0) {
        return val;
      }
    
      obj = obj || {};
      path = paths.shift();
      arrayInfo = path.match(arrayRegExp);
    
      if (arrayInfo) {
        path = arrayInfo[1];
    
        if (!Array.isArray(obj[path])) {
          obj[path] = [];
        }
    
        obj[path][arrayInfo[2]] = setObjVal(obj[path][arrayInfo[2]], paths, val);
      }
      else {
        obj[path] = setObjVal(obj[path], paths, val);
      }
    
      return obj;
    }
    

    var arrayRegExp = /^(\w+)\((\d+)\)$/;
    
    var input = '"paymentInfoList.paymentInfo(0).receiver.amount":"12.00"';
    var pair = input.split(':').map(function (str) { return str.replace(/"/g, ''); });
    var newObj = setObjVal({}, pair[0].split('.'), pair[1]);
    
    function setObjVal(obj, paths, val) {
      var path;
      var arrayInfo;
      
      if (paths.length === 0) {
        return val;
      }
    
      obj = obj || {};
      path = paths.shift();
      arrayInfo = path.match(arrayRegExp);
      
      if (arrayInfo) {
        path = arrayInfo[1];
        
        if (!Array.isArray(obj[path])) {
          obj[path] = [];
        }
        
        obj[path][arrayInfo[2]] = setObjVal(obj[path][arrayInfo[2]], paths, val);
      }
      else {
        obj[path] = setObjVal(obj[path], paths, val);
      }
      
      return obj;
    }
    
    document.write('<pre>' + JSON.stringify(newObj, null, 4) + '</pre>');

    Alternatively if you want to use lodash you could use _.set():

    var newObj = _.set({}, pair[0].replace(/\(/g, '[').replace(/\)/g, ']'), pair[1]);
    

    var input = '"paymentInfoList.paymentInfo(0).receiver.amount":"12.00"';
    var pair = input.split(':').map(function (str) { return str.replace(/"/g, ''); });
    
    var newObj = _.set({}, pair[0].replace(/\(/g, '[').replace(/\)/g, ']'), pair[1]);
    
    document.write('<pre>' + JSON.stringify(newObj, null, 4) + '</pre>');
    <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.0/lodash.min.js"></script>