skip to Main Content

I’m trying to pass through information from a gravity form submission on a Woocommerce order for use in another app using Zapier. I need to split the form entry information so that the information is not all on a single line and can be individually accessed.

As I’m quite new to JavaScript, I have been struggling for hours trying to get this to work… The code I am using is from the woocommerce documentation. The problem is that a chunk of information can be cut off if said information continues onto a new line. Please see the result of the split below and refer to Question 2 to see what I am talking about.

Code:

 // Define "metaData" in the Input Data section. Ignore the "No Data" label.
// Reformat Resource Meta Data to generate keyvalue pairs.
// In case of multiple equal keys, only the last value available.
const buffer = {};
const metaData = inputData.metaData.split(/n+/);
metaData.forEach((dataString, index) => {
  if (dataString.includes('id:')) {
    const key = metaData[index + 1].replace('key:', '').trim();
    const value = metaData[index + 2].replace('value:', '').trim();
    buffer[key] = value;
  }
});
return buffer;

An example form submission would like like this:

Name: John
Last Name: Doe
Email: [email protected]
Question 1: this is my first question
Question 2: hi there,
            this is my second question..

            regards, john doe
Question 3: This is my third question

What the result of the split looks like:

Name: John

Last Name: Doe

Email: [email protected]

Question 1: this is my first question

Question 2: hi there,

Question 3: This is my third question

As you can see, Question 2 basically missing.. I have been unable to figure out a way to get this working. I hope that someone is able to lend me a hand here…

EDIT:
__________________

RAW as requested:

id: 419*** key: _gravity_forms_history value: {'_gravity_form_cart_item_key': '************************************', '_gravity_form_linked_entry_id': ****, '_gravity_form_lead': {'2': 'This is my first question', '6': '[email protected]', '7': '2020-08-01', '8': 'hi there,rnthis is my second question..rnrnregards, john doe', '9': 'This is my third question', '11': 0, '12': this is a random form entry', 'form_id': '3', 'source_url': 'https://***************************/', 'ip': ***************', '5.2': '', '5.3': 'John', '5.4': '', '5.6': 'Doe', '5.8': '', '10.1': 'Product Name', '10.2': '$0.00', '10.3': '1'}, '_gravity_form_data': {'id': '3', 'bulk_id': 0, 'display_title': False, 'display_description': False, 'disable_woocommerce_price': 'no', 'price_before': '', 'price_after': '', 'disable_calculations': 'yes', 'disable_label_subtotal': 'yes', 'disable_label_options': 'yes', 'disable_label_total': 'yes', 'disable_anchor': 'no', 'label_subtotal': 'Subtotal', 'label_options': 'Options', 'label_total': 'Total', 'use_ajax': 'no', 'enable_cart_edit': 'no', 'enable_cart_edit_remove': 'yes', 'keep_cart_entries': 'no', 'send_notifications': 'no', 'enable_cart_quantity_management': 'no', 'cart_quantity_field': '', 'update_payment_details': 'no', 'display_totals_location': 'after', 'structured_data_override': 'no', 'structured_data_low_price': '', 'structured_data_high_price': '', 'structured_data_override_type': 'append'}}
 
id: 419***
key: Name
value: John Doe

id: 419***
key: Email
value: [email protected]

id: 419***
key: Date of Birth
value: 01.08.2020

id: 419***
key: Question 1
value: This is my first question

id: 419***
key: Question 2
value: hi there,
this is my second question..
regards, john doe

id: 419***
key: Question 3
value: This is my third question

id: 419***
key: Final Entry (Optional)
value: this is a random form entry

Expected result as requested:

Name: John Doe

Email: [email protected]

Date of Birth: 01.08.2020

Question 1: This is my first question

Question 2 :Hi There,
            This Is My Second Question..

            Regards, John Doe

Question 3: This is my third question

Final Entry: this is a random form entry

id: ******************************

runtime_meta:

memory_used_mb: 72

duration_ms: 100

logs:

async: false

Current result as requested:

Name: John Doe

Email: [email protected]

Date of Birth: 01.08.2020

Question 1: This is my first question

Question 2 :Hi There,

Question 3: This is my third question

Final Entry: this is a random form entry

id: ******************************

runtime_meta:

memory_used_mb: 72

duration_ms: 100

logs:

async: false

2

Answers


  1. What the result of the split looks like:

    Name: John
    Last Name: Doe
    
    Email: [email protected]
    
    Question 1: this is my first question
    
    Question 2: hi there,
    
    Question 3: This is my third question
    

    No, no, no, no, no. This is what you think the result of splitting is. You have a bug in your code and you have chosen to believe that the split function is at fault rather than your code.

    In your forEach loop, add a line such as

    console.log('XXXX', dataString);
    

    immediately above the line if (dataString.includes('id:')) {. You will see every line of your input logged out with the XXXX prefix, including those you claim to be missing.

    So why is your code not doing what you want? Well, let’s take a look at the contents of the function called by forEach:

    if (dataString.includes('id:')) {
      const key = metaData[index + 1].replace('key:', '').trim();
      const value = metaData[index + 2].replace('value:', '').trim();
      buffer[key] = value;
    }
    

    What does it do? If one line of a file contains id:, take the key and value from the next line and the line after that. If a line of a file doesn’t contain id:, don’t do anything with it.

    In your case, question 2 contains more than one line, which, as we can see, your code completely ignores.

    If, instead of just reading the line-after-next into the value, you want to read all lines up to but not including the next line with id: in it, try the following:

      if (dataString.includes('id:')) {
        const key = metaData[index + 1].replace('key:', '').trim();
        let value = metaData[index + 2].replace('value:', '').trim();
        
        let index2 = index + 3;
        while (index2 < metaData.length && !metaData[index2].includes('id:')) {
          value += "n" + metaData[index2].trim();  
          index2 += 1;
        }
        
        buffer[key] = value.trim();
      }
    
    Login or Signup to reply.
  2. You can separate your entries using a regular expression and then reduce the result into key value pairs

    const inputMatch = inputData.metaData.match(/id(.|n|r)+?(?=$|id)/g)
    
    const buffer = inputMatch.reduce((acc, objectString) => {
        const key = objectString.substring(objectString.indexOf('key:') + 4, objectString.indexOf('value:')).trim()
        const value = objectString.substring(objectString.indexOf('value:') + 6, objectString.length).trim()
        return {
            ...acc,
            [key]: value
        }
    }, {})
    

    JsFiddle

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search