Hi, I am trying to replicate Inwise’s Add/Update Subscriber Action in my developer account. Everything is working fine except Dictionary input (Please check screenshot attached).
Error: Cannot read property 'length' of undefined
I have no idea why array.length is not working inside Zapier code mode but it works on any other IDE.
Can you please let me know how do we actually handle dictionary input fields? I
Page 1 / 1
The code you’re showing us above is referencing the response data - what your API returns to your integration. To figure out why that’s not an array as expected, I’d start by adding some z.console.log statements and watching the monitor section of the developer UI. Also have a look at your server logs and make sure you’re sending what you expect to be sending.
The data that the user mapped to a dictionary input field will be available to your code in bundle.inputData.keyofyourdict.
@adilalich Can you expand a bit on the use case here as I’m not getting it, unfortunately?
If all you want to do is to read the dictionary key-value pairs from the input data then you can just get it from bundle.inputData.fields which will return an object containing all the key-value pairs that were mapped in the zap editor.
The part I’m not understanding is why you’re parsing the fields from the response? Are you trying to compare bundle.inputData.fields with response.contact_details.fields?
@adilalich - Can you post the whole source code? Just make sure to replace any secret values with a placeholder.
@adilalich - Oh ok, no problem. Maybe you didn’t use the code block?
Anyway, here’s the updated code:
const fields = l]; for (let name in bundle.inputData.fields) { fields.push({ name, content: bundle.inputData.fieldsfname], }); }
return z.request(options).then((response) => { // The code in this block runs after the server has already responded to our request. response.throwForStatus(); return response.json; });
@ikbelkirasan IT WORKED! Thank you so much.
@adilalich - Awesome! Glad it worked for you :D
Hi @adilalich - Did you try to z.console.log(response.json) to make sure the API response is as expected?
Let’s say your dictionary input Field is called my_dict, in order to access field1 value, you should be able to get it from bundle.inputData.my_dict.field1. I hope this helpful to you!
@adilalich - Dictionary field type is basically a JavaScript object (Not an array of objects). So, according to the zap screenshot, you should get something like this:
Hey @ikbelkirasan - I have used bundle.inputData.fields in the response I don’t see see dictionary.
To get a response which also shows fields array, I had to tinker with the raw response.
Please suggest how I can achieve this?
Update: Since API request expects “fields” field to look like an array of objects, and our dictionary with key (fields) is an object of key/value pairs, I tried to reverse engineered the whole process.
Step 1: I converted dictionary into how api expects the request for “fields”
Step 2: I changed response to revert dictionary into how “fields” request is made in API call
Step 3: Check response
@ikbelkirasan
@adilalich I see. So, you need to send an array of objects containing the “name” and “content” values. However, you’re converting it to an array after making the request. You should be doing that before calling z.request(options). If you look closely, you’ll see that your options contains fields value before the conversion.
@ikbelkirasan How can I convert dictionary into an Array of objects before calling z.request(options)? Is it even possible? Looks like I will have to make the request like it is expected i.e Array of Objects and convert that into dictionary in response BUT still the input designer have fields input type set to dictionary - You see the dilemma.
@adilalich Yup, that’s possible. Can you copy & paste your code here so I can tweak it for you?
// dictionary value which user inputs var arr = bundle.inputData.fields // var arr = options.body.fields ????
// convert dictionary into how API expects fields var field = x]; for(var i in arr) { field.push({ "name": i, "content": arr i] });
} return result;
});
@ikbelkirasan PLEASE DO!
This is the code which converts dictionary into array of objects.
// dictionary value which user inputs var arr = bundle.inputData.fields // var arr = options.body.fields ????
// convert dictionary into how API expects fields var field = ]; for(var i in arr) { field.push({ "name": i, "content": arr i] });
}
@ikbelkirasan I did but the post was probably flagged and needs to be reviewed by moderators. Please find attached a doc file.
@Zane@ikbelkirasan Thank you for steering me in the right direction but I can’t seem to get my head around dictionary. I know my JS code to transform response data is correct
“The code you’re showing us above is referencing the response data - what your API returns to your integration.”
@Zane isn’t that how we approach this? We can’t do anything with the requestBody - we can only play with its response
As you can see in img above - value of key “name” can be field1, field2, field3 .. field20 where field1 will be mapped to firstName, field 2 mapped with lastName etc
my code shared in the original post takes the response and transform it into how a dictionary should look like i.e value of “name” : value of “content
UPDATE: My Javascript had few issues which I resolved BUT integration is still not working.
When I Test Action in Test your API Request section, I get the dictionary working. Here, I am inputting fields as expected by the requestBody
But when I test via a zap it doesn’t work. Like @Zane said “The data that the user mapped to a dictionary input field will be available to your code in bundle.inputData.keyofyourdict.” which in my case is bundle.inputData.fields.
I know I am almost there, and will appreciate if someone can take me over the line.
@ikbelkirasan Yes, I get this part, and I have tried transforming raw response to match the response expected by a dictionary but it didn’t work.