Issues Parsing JSON String and Returning JSON Object in Custom JS Module

Hi I’m having several problems I’m basically trying to parse a long string value that I believe is formatted as a json which isn’t working and then return a json object using a custom js module.

Before I continue its worth mentioning I’m not familiar with Json and being assisted by GPT through most of this so forgive me for any rookie mistakes.

To give some context I am taking the question and answers provided from a calendly form that someone fills upon scheduling, that is stored as a long string value in a data storage(reasons stored the array like this is for a different conversation).

Now the problems I’m having upon retrieving the long string to show you an example of is formatting first is…
[{"answer":"Redacted number","position":0,"question":"Telephone"},{"answer":"gd","position":1,"question":"Your business website (if you don't have one please type no website). "},{"answer":"$20,000 to $50,000","position":2,"question":"From your business, what is the range of your monthly income? "},{"answer":"gd","position":3,"question":"What's your monthly income goal?"},{"answer":"g","position":4,"question":"What’s the #1 biggest obstacle holding you back from hitting your revenue goal? (don’t skip this part, we need to know as much as possible to help you best)"},{"answer":"Yes, of course!","position":5,"question":"Have you got a working funnel setup?"},{"answer":"g","position":6,"question":"Have you used Facebook ads before? If so, what was your experience?"},{"answer":"Absolutely! I have the means and I'm ready to take things to the next level. ","position":7,"question":"Are you at a stage where investing in your business is a possibility? "},{"answer":"Without a doubt! I'm all in with my business, ready to invest and grow quickly.","position":8,"question":"If I were to advise a monthly ad budget of at least $500 to meet your financial goals, would you say: "},{"answer":"I recognize that if I don't have a funnel in place, there might be costs involved in repairing or constructing it, to ensure that we can direct traffic to it.","position":9,"question":"Final note: "}]

1.When I use a parse to json module I end up with 3 variables which are just parts of the first elements of the array not the entire string/array as I’d want it formatted as a json object to use in my code.

2.When I’m trying to parse it within the custom js module I keep getting the error

[500] {“error”:“Unexpected token , in JSON at position 1361”}

I also have another issue with trying a different approach without trying to convert that long string into json is with my custom cs I’m unable to return a json object and getting the error:

Validation failed for 1 parameter(s).
Missing value of required parameter ‘json’.

This is the new code I’m trying to achieve this:

let dataString = input;

function escapeRegex(text) {
  return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
}

function getAnswer(questionText) {
  let questionPattern = escapeRegex(questionText);
  let regex = new RegExp('"question":"' + questionPattern + '","answer":"(.*?)"', 'i');
  let match = regex.exec(dataString);
  if (match && match[1]) {
    return match[1];
  } else {
    return null;
  }
}

let incomeRangeQuestion = "From your business, what is the range of your monthly income? ";
let investmentReadinessQuestion = "Are you at a stage where investing in your business is a possibility? ";
let adBudgetResponseQuestion = "If I were to advise a monthly ad budget of at least $500 to meet your financial goals, would you say: ";
let telephoneQuestion = "Telephone";

let incomeRange = getAnswer(incomeRangeQuestion);
let investmentReadiness = getAnswer(investmentReadinessQuestion);
let adBudgetResponse = getAnswer(adBudgetResponseQuestion);
let telephone = getAnswer(telephoneQuestion);

let textReminderNumber = "";

let phoneNumberUsing = textReminderNumber.trim() !== "" ? textReminderNumber.trim() : (telephone ? telephone.trim() : null);

let leadQuality = "";

if (
  adBudgetResponse === "No chance! That amount is just too high!" ||
  adBudgetResponse === "Yes... I could stomach that. Let’s talk numbers a bit more." ||
  investmentReadiness === "No way... My finances are stretched thin, and I'm at my limit."
) {
  leadQuality = "Bad Lead";
} else if (
  investmentReadiness === "Absolutely! I have the means and I'm ready to take things to the next level." &&
  adBudgetResponse === "Without a doubt! I'm all in with my business, ready to invest and grow quickly." &&
  incomeRange === "Below $10,000"
) {
  leadQuality = "Good Lead";
} else if (
  investmentReadiness === "Absolutely! I have the means and I'm ready to take things to the next level." &&
  adBudgetResponse === "Without a doubt! I'm all in with my business, ready to invest and grow quickly." &&
  incomeRange !== "Below $10,000"
) {
  leadQuality = "Very Good Lead";
} else {
  leadQuality = "Unqualified";
}

output = {
  leadQuality: leadQuality,
  phoneNumberUsing: phoneNumberUsing
};

You can just use a Parse JSON module.

Hope this helps! Let me know if there are any further questions or issues.

@samliew

P.S.: Investing some effort into the Make Academy will save you lots of time and frustration using Make.

1 Like

Thanks for the suggestion however everytime I tried using a parse to json it didn’t work, I’m very surprised it appears to have worked for you. I think it maybe because you did it as a json string and the text above I sent is formatted as json but is stored as a string text NOT json.

Is there a way I can convert it into a json string first?

JSON is already a string type variable, but in a specific format structure.

There is something else going on in your scenario.

Did you know, this forum has a Hire a Pro category, where you can post your request for off-site specialised help on other platforms (video call/screenshare/private messaging/etc.)? This may help you get your issue resolved faster especially if it is urgent. It is important to post your request in the Hire a Pro category, as forum members are not allowed to advertise their services (even offer FREE assistance to help) in other categories like here. Once you have posted in the Hire a Pro category, that will allow other members like me to provide booking links to our calendars for a free consultation and video assistance (including screenshare)!
Hope this helps! Let me know if there are any further questions or issues.

@samliew

P.S.: Investing some effort into the Make Academy will save you lots of time and frustration using Make.


So I was able to convert with the parse to json which is something I already tried I forgot but the issue mentioned in my initial post as shown in this screenshot is that it only give me access to a few variables rather than all of them and also makes it difficult to work with, within the code itself.

1 Like

@samliew can you please help me with this issue, not sure if you work with make.com since you help a lot but my last post may not have been quite so clear. Basically I could parse to json the long string variable I mentioned but rather than it being a single json object or something that I can input into the custom js module, it just give me those 3 individual variables as shown in the above screenshot.

I think the only thing that could work is trying to parse it within the code but that kept giving me errors.

Following this in a related post you responded to:

You mentioned about passing all of the variables into a single json object, should I make all of them a json object first following this?

Sorry, this is not something I can help on the forum, as it will take a lot more information from you, and time to put together an answer.

I suggest following the instructions in my previous post.

If you have any further questions, please repost in the Hire a Pro category if you find it easier to book a free expert consultation to explain your problem over screenshare. There is only so much we can do for you on a text-based forum.

@samliew

P.S.: Investing some effort into the Make Academy will save you lots of time and frustration using Make.

Ok I can understand you may be limited to how much you offer to support for free or via this forum but your previous post didn’t take into consideration what I said about how it doesn’t give just one parsed object to work with. It gives 3 variables so that aren’t even all of the available variables within that long string either so your last post was invalid can you not at least assist with that?

and what do you mean by people can’t offer free help whats the point in this community if people can’t help?

Hello @AdamZ, what you get is the list of items in your JSON, parsed as different bundles.


And each bundle contains the fields that Calendly provided: “answer”, “position”, “question”.

What you see when you configure Custom JS is normal, Make provides you with the 3 fields that were parsed when you used Parse JSON. And the text you see in grey besides the field names, is just a sample data, picked from Bundle 1.

Because it’s different bundles, your Custom JS will be called for each bundle (10 times from the sample JSON you sent).

@samliew provided you with the best answer to help you parse the JSON string, but we still need to understand how you want your Custom JS to work. Because:

  • if you want to execute it for each individual answer (telephone, your business website, etc), you just need to map the relevant fields from Parse JSON to the relevant place in your JS. Make will automatically call Custom JS for each individual answer (bundle).

  • if you want to send all answers at once, meaning grouping all answers into an individual document, in order to send it once to you Custom JS module, you will need to use an Aggregator. But you have to know the exact format you need (and provide it to us if you want us the give you guidance).

  • if you want to send only one of the answers (for example only “What’s your monthly income goal?”) to your Custom JS, you just need to add a filter before your Custom JS (for example Position numeric operator:equals to 3).

I hope I was clear. Please let us know the outcome of your investigation, and what exactly you want to get from these bundles of answers.

Kind regards,

Benjamin

2 Likes

Thanks Benjamin so for now to help make this easier I’m not going to add the additional phonenumber variable with the json string, just so we can see if we can get that to work first.

So I will need all of the questions and answers to be passed through, so I tried using the aggregator as suggested to take the json parsed version to the aggregator


Which appeared to have worked correctly and I believe each bundle as you shown above was stored as it’s own element.

However when I passed this into the custom js module when I tried to work with the array I got the error:

[500] {“error”:“qaArray.forEach is not a function”}

For the code (will show top portion let me know if you need to see more)

let qaArray = input;

let answers = {};

qaArray.forEach(item => {
  let question = item.question.trim();
  let answer = item.answer.trim();

  if (question === "From your business, what is the range of your monthly income? ") {
    answers.incomeRange = answer;
  } else if (question === "Are you at a stage where investing in your business is a possibility? ") {
    answers.investmentReadiness = answer;
  } else if (question === "If I were to advise a monthly ad budget of at least $500 to meet your financial goals, would you say: ") {
    answers.adBudgetResponse = answer;
  }
});

let leadQuality = "";

When I checked the logs the array when it reaches the custom js no longer appears to be the same as it was on the aggregator module and appears to have a series of collections:


Why is it being treated as a series of collections at the custom js module?

Hello @AdamZ,

According to the piece of JS you show, it seems to require an Array of collections with a field called “question” and one called “answer”.

What you could try and do is to transform the bundles you get into this array format.

To do this, try the following:

let’s start with your bundles, after Parse JSON

Add a “Create Json”, and for the Data Structure, click Add. Give the structure a name, and then add an Array called “questions”. It has to be of type “Collection”. In it, add a new item of type Text called “question” and one other called “answer”.

It should look like this:

Once you click ok you Create Json module should look like this

Click OK, and then right-click between your Parse JSON and Create JSON, and add an Aggregator. Set the Source Module to the Parse JSON, and select the Target Structure type to the “questions” Array you added in the Create JSON.
Your module should look like this:

Click OK, and edit again the Create JSON. click on the little “map” that appears besides “questions”, and map the Array from your Aggregator.

It should look like this


Click OK, and then, after Create JSON, add a “Parse JSON”, and map the output of Create JSON.

It will look like this

when you execute, you will see that the output contains an array “questions” that has all questions and answers in the format JS requires

Try to map “questions” from Parse JSON in the relevant place of you Custom JS module.

I’m not 100% sure your JS code is ok, but at least, you have an Array of items in the format we see in the code.

Another option is to change a bit the JS so that it directly gets the relevant fields from your initial Array Aggregator.

I hope it helps

Benjamin

1 Like

Hey Benjamin very much appreciate the detailed instructions, however I’ve unfortunately hit a block upon the first step. So I went to change the how the parse to json works for the array aggregator as you’ve suggested.

So I made data structure in it and set up like this which I believe is the same as yours:


However outside of the datastructure mine has a section for requiring a json string and doesn’t look like yours:

I don’t understand how/why yours doesn’t, following this how are you even able to make this work if it isn’t accepting the qna string data to parse in the first place?

Hi dear @AdamZ,

In fact, we are trying to map an array in a specific format (the source document) to another format (the one you just created), for this to work, you need to use an iterator on the source array to convert it to bundles, and then immediately after, group them into an array of your new structure. And for this you need an array aggregator.

Could you please try and send you an example document from the source system so that I show you how you can do it?

Benjamin

Sorry but I don’t fully understand your last response, please read my previous comment again how it is a different layout to yours which it isn’t clear to me why.

we are retrieving a long string which is being retrieved from a data storage in the format I sent above you’ve been using for demonstration purposes, that has personal info like telephone number redacted then parsing with the module to make it so its a json format.

I don’t understand why what you’ve shown in your screenshot with the parsed json module is completely different and where and how is it even having the long string to work with in the first place. I had as shown above created the data structure within the module the exact same.

Also not sure what you mean by source system I’ve already provided the example long string that you’ve already been using for demonstrations it’s in this format because of what I had to do in a previous scenario to be able to store it in a datastructure.

[{“answer”:“Redacted number”,“position”:0,“question”:“Telephone”},{“answer”:“gd”,“position”:1,“question”:“Your business website (if you don’t have one please type no website). “},{“answer”:”$20,000 to $50,000”,“position”:2,“question”:"From your business, what is the range of your monthly income? "},{“answer”:“gd”,“position”:3,“question”:“What’s your monthly income goal?”},{“answer”:“g”,“position”:4,“question”:“What’s the #1 biggest obstacle holding you back from hitting your revenue goal? (don’t skip this part, we need to know as much as possible to help you best)”},{“answer”:“Yes, of course!”,“position”:5,“question”:“Have you got a working funnel setup?”},{“answer”:“g”,“position”:6,“question”:“Have you used Facebook ads before? If so, what was your experience?”},{“answer”:"Absolutely! I have the means and I’m ready to take things to the next level. ",“position”:7,“question”:"Are you at a stage where investing in your business is a possibility? "},{“answer”:“Without a doubt! I’m all in with my business, ready to invest and grow quickly.”,“position”:8,“question”:"If I were to advise a monthly ad budget of at least $500 to meet your financial goals, would you say: "},{“answer”:“I recognize that if I don’t have a funnel in place, there might be costs involved in repairing or constructing it, to ensure that we can direct traffic to it.”,“position”:9,“question”:"Final note: "}]

Important note the JS isn’t set in stone I just want to use any method including completely different JS so that it will return a value based on the answers provided so I can determine the quality of the lead, here’s the entire JS I was trying which may help explain what I’m trying to achieve:

let qaArray = input;

let answers = {};

qaArray.forEach(item => {
  let question = item.question.trim();
  let answer = item.answer.trim();

  if (question === "From your business, what is the range of your monthly income? ") {
    answers.incomeRange = answer;
  } else if (question === "Are you at a stage where investing in your business is a possibility? ") {
    answers.investmentReadiness = answer;
  } else if (question === "If I were to advise a monthly ad budget of at least $500 to meet your financial goals, would you say: ") {
    answers.adBudgetResponse = answer;
  }
});

let leadQuality = "";

if (
  answers.adBudgetResponse === "No chance! That amount is just too high!" ||
  answers.adBudgetResponse === "Yes... I could stomach that. Let’s talk numbers a bit more." ||
  answers.investmentReadiness === "No way... My finances are stretched thin, and I'm at my limit."
) {
  leadQuality = "Bad Lead";
} else if (
  answers.investmentReadiness === "Absolutely! I have the means and I'm ready to take things to the next level." &&
  answers.adBudgetResponse === "Without a doubt! I'm all in with my business, ready to invest and grow quickly." &&
  answers.incomeRange === "Below $10,000"
) {
  leadQuality = "Good Lead";
} else if (
  answers.investmentReadiness === "Absolutely! I have the means and I'm ready to take things to the next level." &&
  answers.adBudgetResponse === "Without a doubt! I'm all in with my business, ready to invest and grow quickly." &&
  answers.incomeRange !== "Below $10,000"
) {
  leadQuality = "Very Good Lead";
} else {
  leadQuality = "Unqualified";
}

output = leadQuality;

It’s basically meant to look at the answer to some of the specific questions to determine the lead quality.

Hello @AdamZ,

Ok, now , I think I understand what your problem is.
You need to send the Array, but since the received JSON has the array as the root element, Make won’t let you select it, but only the individual fields.

To overcome this, you can do the following:

So, this is you initial JSON document. It starts with the Array.

Use a Parse JSON, but wrap it into a Json document like shown in the screenshot

As a result, you will have an array “answers”, with the initial answers from the user

And now, in your Custom JS function, you will be able to map “answers”. I give you an example with a Make Custom funtion (only in the Enterprise plan), but do the same mapping in your Custom JS module:

From the example you provided, the user is “Unqualified”

Tell me if that worked.

Cheers,

Benjamin

Thanks again for your response Benjamin, however I’m finding it difficult to follow the example above as mentioned is coming from data storage as a long string in the format of a json string even though I don’t believe its classed as a json since its stored as a long string.

Following this what do you mean by JSON document do you mean a json object that has the array element values in it?


I made the datastructrure for the parse module but I never had the layout like you did which is odd

That aside if that is no longer important I followed your most recent example with using the string value and {“answers”: {{2.calendlyData.questionsAndAnswers}}} as the value


and it appeared to have worked.

However now I’m unsure of what to do with the array aggregator mine again doesn’t look like what you’ve demonstrated I have these options


After the aggregator is sorted what should we then be passing into the custom js as the value and will I need to adjust any of the js code?Thanks

@AdamZ

A long string is just a text. And the text you have contains a JSON document.
As we told you already, a json is a text with a specific content in a specific format.
We use parse JSON to « interpret » the document so that we can use it in mappings.

You don’t need the Aggregator, because what you get after Parse JSON is already an array.

What you need to map is the « answers » array you get from Parse JSON. I showed you an example screenshot.

Normally you don’t need to change anything in the JavaScript; I took it from your example and it worked immediately.
Maybe you will need to adjust a little the variables at the start of the script, but try without changing anything.

May I also suggest you to take the Make Academy trainings, since it gives all the basics you need to know if you want to be comfortable with Make?

Cheer

So I tried your suggestion and the json document was parsed in a collection as you described:


I was then getting a new error in the custom js saying:

RuntimeError

[500] {“error”:“qaArray.forEach is not a function”}

GPT claims : The error [500] {"error":"qaArray.forEach is not a function"} indicates that the input being passed to the Custom JS module (in this case, qaArray) is not being treated as an array within the JavaScript environment. This happens because the input is likely still a collection in Make.com’s format, not a native JavaScript array.

So it suggested Convert the Input to a JavaScript Array

so I tried this code:

let qaArray = Array.from(input.answers);

let answers = {};

qaArray.forEach(item => {
  let question = item.question.trim();
  let answer = item.answer.trim();

  if (question === "From your business, what is the range of your monthly income? ") {
    answers.incomeRange = answer;
  } else if (question === "Are you at a stage where investing in your business is a possibility? ") {
    answers.investmentReadiness = answer;
  } else if (question === "If I were to advise a monthly ad budget of at least $500 to meet your financial goals, would you say: ") {
    answers.adBudgetResponse = answer;
  }
});

let leadQuality = "";

if (
  answers.adBudgetResponse === "No chance! That amount is just too high!" ||
  answers.adBudgetResponse === "Yes... I could stomach that. Let’s talk numbers a bit more." ||
  answers.investmentReadiness === "No way... My finances are stretched thin, and I'm at my limit."
) {
  leadQuality = "Bad Lead";
} else if (
  answers.investmentReadiness === "Absolutely! I have the means and I'm ready to take things to the next level." &&
  answers.adBudgetResponse === "Without a doubt! I'm all in with my business, ready to invest and grow quickly." &&
  answers.incomeRange === "Below $10,000"
) {
  leadQuality = "Good Lead";
} else if (
  answers.investmentReadiness === "Absolutely! I have the means and I'm ready to take things to the next level." &&
  answers.adBudgetResponse === "Without a doubt! I'm all in with my business, ready to invest and grow quickly." &&
  answers.incomeRange !== "Below $10,000"
) {
  leadQuality = "Very Good Lead";
} else {
  leadQuality = "Unqualified";
}

output = leadQuality;

However now I’m getting the error:

RuntimeError

[500] {“error”:“undefined is not iterable (cannot read property Symbol(Symbol.iterator))”}
Can you see why this is happening since from what I can see the custom js is receiving the parsed collections I’ve shown above.

@AdamZ

I’m not a specialist in JavaScript… but can you show the mapping you did in the CustomJS module?