Zapier scripting - for loops - javascript

I cant seem to figure this out. Here is my working JSfiddle code that sends data to console perfectly. I know my zapier app is passing authentication. I'm getting a 200-success if I just return
var stuff =
{
"uri":"some URL here",
"action":"EXPORT",
"result":
{
"column_order":["Name","email","TimeStamp"],
"rows":[
["ted2","ted2#example.com","06 Feb, 2018 04:37:16"],
["jimf","jimf#example.com","06 Feb, 2018 19:03:39"]
]
}
};
var results2 = [];
for (var j = 0; j < stuff.result.rows.length; j++)
{
var result = {};
for (var i = 0; i < stuff.result.column_order.length; i++)
{
result['"' + stuff.result.column_order[i] + '"'] = stuff.result.rows[j][i];
}
results2.push(result);
}
console.log(results2);
It spits out:
{
"Name": "ted2",
"email": "ted2#example.com",
"TimeStamp": "06 Feb, 2018 04:37:16"
}{
"Name": "jimf",
"email": "jimf#example.com",
"TimeStamp": "06 Feb, 2018 19:03:39"
}
Now if I try to convert this to a Zapier Post POLL function, I keep getting errors: Javascript Exception: TypeError: Cannot read property 'rows' of undefined.
Here is my Zapier Post Poll function. What am I missing? For loops just wont work the same.
email_post_poll: function(bundle){
var response = z.JSON.parse(bundle.response.content);
var results2 = [];
for (var j = 0; j < response.result.rows.length; j++)
{
var result = {};
for (var i = 0; i < response.result.column_order.length; i++)
{
result['"' + response.result.column_order[i] + '"'] = response.rows[j][i];
}
results2.push(result);
}
return results2 || [];
}

David here, from the Zapier Platform team.
Your issue is in the for loop, you're calling = response.rows[j][i], which should be = response.result.rows[j][i]. If that doesn't clear it up, I'd suggest using console.log to make sure you know what is actually coming in the response.
As a side note, arrays are truthy in js, so results2 || [] will never return the empty array on the right.

I got this working. bundle.response.content had a parent array of "response" on top of everything. So i actually had to call "response.response." for everything. Using the console.log suggestion from Dave helped me solve this but you can only see the console log inside of the scripting tool and then "Bundle logs". Just a learning curve for the platform i guess.
email_post_poll: function(bundle){
var response = z.JSON.parse(bundle.response.content);
var results2 = [];
console.log(response.response.result.rows.length);
for (var j = 0; j < response.response.result.rows.length; j++)
{
var results3 = {};
for (var i = 0; i < response.response.result.column_order.length; i++)
{
results3['"' + response.response.result.column_order[i] + '"'] = response.response.result.rows[j][i];
}
results2.push(results3);
}
return results2;

Related

Unexpected behaviour of glob-fs glob.readdirSync

I have the following nodejs code. The client first calls /api/demosounds then call /api/testsounds.
var glob = require('glob-fs')({ gitignore: true });
app.get('/api/demosounds',function(req,res){
var demosounds = []
var demosoundlist = glob.readdirSync('src/assets/demosounds/*.wav');
demosounds = demosounds.concat(demosoundlist)
for (var i = 0; i < demosounds.length; i++) {
demosounds[i] = demosounds[i].replace("src/assets/","/api/static/")
}
demosounds = demosounds.sort()
res.json(demosounds)
})
app.get('/api/testsounds',function(req,res){
var listofsounds = []
var folderlist = ['01_sinus','02_pulse_train','03_contour_le','04_contour_fel','05_variable','06_complex_le','07_complex_fel']
for (var x = 0; x < folderlist.length; x++){
var testsoundlist = glob.readdirSync('src/assets/' + folderlist[x] +'/*.wav');
listofsounds = listofsounds.concat(testsoundlist)
}
When doing glob.readdirSync('src/assets/01_sinus/*.wav') I would expect to get only path starting with src/assets/01_sinus/ and yet testsoundlist starts as the following:
[ 'src/assets/demosounds/electricity.wav',
'src/assets/demosounds/phone.wav',
'src/assets/demosounds/water.wav',
'src/assets/demosounds/wind.wav',
'src/assets/01_sinus/02_sin1_0065_0.16923076923076924.wav',
'src/assets/01_sinus/04_sin1_0065_0.7692307692307693.wav',
'src/assets/01_sinus/05_sin1_0065_1.0615384615384615.wav',
'src/assets/01_sinus/07_sin1_0165_0.07272727272727272.wav',
I have no idea why this is happening :(
UPDATE
Somewhat closer to the problem, the code below
var glob = require('glob-fs')({ gitignore: true });
var folderlist = ['01_sinus','02_pulse_train','03_contour_le','04_contour_fel','05_variable','06_complex_le','07_complex_fel']
for (var x = 0; x < folderlist.length; x++){
console.log((glob.readdirSync('src/assets/' + folderlist[x] +'/*.wav').length))
}
Outputs this, as if glob would remember the previous globs.
49
98
147
196
245
294
343
The library doesn't seem to be maintained anymore and there is a hanging issue with exactly the same problem, so it seems like this is a bug.
A solution is to simply use glob, glob.sync() in this case.

JS JSON process

I'm new in JSON handling, so I would like to get some help :)
I have this data in the data variable:
{"json":null,"id":"1111","prime1":"26","prime2":"0","ass1":"0","ass2":"0","time1":"07:00:00","time2":"14:30:00"}*{"json":null,"id":"2111","prime1":"0","prime2":"0","ass1":"0","ass2":"0","time1":"07:00:00","time2":"14:30:00"}*{"json":null,"id":"3111","prime1":"11","prime2":"0","ass1":"0","ass2":"0","time1":"07:00:00","time2":"14:30:00"}*{"json":null,"id":"4111","prime1":"4","prime2":"0","ass1":"17","ass2":"13","time1":"07:00:00","time2":"17:30:00"}*{"json":null,"id":"5111","prime1":"6","prime2":"0","ass1":"23","ass2":"0","time1":"07:00:00","time2":"14:30:00"}*{"json":null,"id":"6111","prime1":"1","prime2":"0","ass1":"15","ass2":"0","time1":"07:00:00","time2":"14:30:00"}*{"json":null,"id":"1112","prime1":"0","prime2":"0","ass1":"0","ass2":"0","time1":"14:00:00","time2":"21:30:00"}*{"json":null,"id":"2112","prime1":"0","prime2":"0","ass1":"0","ass2":"0","time1":"14:00:00","time2":"21:30:00"}*{"json":null,"id":"3112","prime1":"22","prime2":"0","ass1":"18","ass2":"0","time1":"14:00:00","time2":"21:30:00"}*{"json":null,"id":"4112","prime1":"0","prime2":"0","ass1":"0","ass2":"0","time1":"14:00:00","time2":"21:30:00"}*{"json":null,"id":"5112","prime1":"3","prime2":"0","ass1":"19","ass2":"0","time1":"14:00:00","time2":"21:30:00"}*{"json":null,"id":"6112","prime1":"9","prime2":"0","ass1":"0","ass2":"0","time1":"14:00:00","time2":"21:30:00"}*{"json":null,"id":"1121","prime1":"3","prime2":"0","ass1":"15","ass2":"0","time1":"07:00:00","time2":"14:30:00"}*{"json":null,"id":"2121","prime1":"6","prime2":"0","ass1":"23","ass2":"0","time1":"07:00:00","time2":"14:30:00"}*{"json":null,"id":"3121","prime1":"11","prime2":"0","ass1":"0","ass2":"0","time1":"07:00:00","time2":"14:30:00"}*{"json":null,"id":"4121","prime1":"8","prime2":"0","ass1":"17","ass2":"13","time1":"07:00:00","time2":"14:30:00"}*{"json":null,"id":"5121","prime1":"22","prime2":"0","ass1":"19","ass2":"0","time1":"07:00:00","time2":"14:30:00"}*{"json":null,"id":"6121","prime1":"1","prime2":"0","ass1":"12","ass2":"0","time1":"07:00:00","time2":"14:30:00"}*{"json":null,"id":"1122","prime1":"0","prime2":"0","ass1":"0","ass2":"0","time1":"14:00:00","time2":"21:30:00"}*{"json":null,"id":"2122","prime1":"0","prime2":"0","ass1":"0","ass2":"0","time1":"14:00:00","time2":"21:30:00"}*{"json":null,"id":"3122","prime1":"0","prime2":"0","ass1":"0","ass2":"0","time1":"14:00:00","time2":"21:30:00"}*{"json":null,"id":"4122","prime1":"8","prime2":"0","ass1":"13","ass2":"18","time1":"14:00:00","time2":"21:30:00"}*{"json":null,"id":"5122","prime1":"22","prime2":"0","ass1":"19","ass2":"0","time1":"14:00:00","time2":"21:30:00"}
I can't create objects from them.
This is my code:
var dataSplit = data.split("*");
for (var i = 0; i < dataSplit.length; i++) {
objects[i] = dataSplit[i];
document.getElementById("proba").innerHTML += objects[i].time2;
}
Thanks for all of you!
It's working now, it was 2 hours for me. The problem was I didn't initialize the object array and didn't use JSON.parse() (tried the JSON.parse() before, without success). So the solution is:
var objects = [];
var dataSplit = data.split("*");
for (var i = 0; i < dataSplit.length; i++) {
objects[i] = JSON.parse(dataSplit[i]);
document.getElementById("proba").innerHTML += objects[i].time2;
}

JS check if the value of object exists

So, I have following js setup:
var NAMES = [];
function INFO(id,first,middle,last){
var newMap = {};
newMap[id] = [first, middle, last];
return newMap ;
}
Then,
for (var j = 0; j < NUMBER.length; j++) { //let say it there are three values
var my_name = all_names[j]; // has "185, 185, 185"
if (NAMES[my_name] !== 185){ //Needs to check here
NAMES.push(INFO(my_name,"sean","sdfsd","sdfsfd"));
}else{
}
}
alert(JSON.stringify(NAMES , null, 4));
Here is a screenshot of the alert:
I hardcoded the number "185" for this example. I need to check if the id of 185 exists, then skip to else. I am not sure how to check it. I tried typeof, undefinedetc. but no luck.
(In other words, I should only have one "185").
Any help? Thanks!
If I understood correctly what you are trying to achieve, you have to iterate over NAMES and check every element. For example, you could do it using [].some javascript function:
if (!NAMES.some(function(v){return v[my_name]})) {
...
} else {
}
If you want to remove duplication you can just use NAMES as an object instead of array like this
var all_names = [185, 185, 181],
NAMES = {};
for (var j = 0; j < all_names.length; j++) { //let say it there are three values
var my_name = all_names[j]; // has "185, 185, 185"
NAMES[my_name] = ["sean","sdfsd","sdfsfd"];
}
alert(JSON.stringify(NAMES, null, 4));
First of all I would recommend making a JS Fiddle or CodePen out of this so people can see the code running.
I believe that the issue is that NAMES[my_name] is not doing what you think it is. NAMES is an Array so when you say NAMES[my_name] you are really asking for the ITEM in the array so you are getting the entire object that you create in the INFO function. What you really want is to see if the object has an attribute that matches the value (e.g. "185" from the my_names array).
This is not the prettiest code but it will show you how to do what you really want to do:
var NAMES = [];
function INFO(id,first,middle,last){
var newMap = {};
newMap[id] = [first, middle, last];
return newMap ;
}
all_names = ["185", "186", "185"]
for (var j = 0; j < all_names.length; j++) {
var my_name = all_names[j];
if (NAMES.length == 0) {
NAMES.push(INFO(my_name,"sean","sdfsd","sdfsfd"));
} else {
var match = false;
for (var x = 0; x < NAMES.length; x++) {
console.log(NAMES[x][my_name] + ' : ' + my_name);
if(NAMES[x][my_name]) {
match = true;
}
}
if (!match) {
NAMES.push(INFO(my_name,"sean","sdfsd","sdfsfd"));
}
}
}
alert(JSON.stringify(NAMES , null, 4));
Note the if that looks at NAMES[x][my_name] - this is asking if the item at array index 'x' has an attribute of 'my_name' (e.g. "185"). I believe this is really what you are trying to do. As its after midnight I assure you that there is more concise and pretty JS to do this but this should show you the basic issue you have to address.
Try this code using hasOwnProperty method :
for (var j = 0; j < NUMBER.length; j++) { //let say it there are three values
var my_name = all_names[j]; // has "185, 185, 185"
if (!NAMES[my_name].hasOwnProperty("185")){ //Needs to check here
NAMES.push(INFO(my_name,"sean","sdfsd","sdfsfd"));
}else{
}
}

create an array from different objects

I've sent data from server side with socket.io :
for (i = 0; i<rows.length; i++) {
socket.emit('Switch', {eqid:rows[i].EquipmentID,eqroom:rows[i].Name});
}
and in the client side :
socket.on('Switch', function (data) {
console.log(data.eqid);
}
and what I get is :console log and when I do console.log(data.eqid[0] I get undefined
so I want to get an array [120336,120337..]
I've tried also to send an array from the beginning in the server side :
for (i = 0; i<rows.length; i++) {
var test=[];
test.push(rows[i].EquipmentID);
}
console.log(test);
console.log gives me the last equipmentID only [120339
console.log gives me the last equipmentID only [120339
Because you are redefining rows array in every iteration.
Try this:
var ids = [];
var names = [];
for (var i = 0; i < rows.length; i++) {
ids.push(rows[i].EquipmentID);
names.push(rows[i].Name);
}
socket.emit('Switch', {eqid: ids, eqroom: names});

populate select element based on json

How could I populate a second select element? I've figured out how to do the first one. But how could I do the same for the second depending on which "Make" is selected? I've tried to talk myself through it while taking small steps but I'm thinking this may be too advanced for me.
var cars = '{"USED":[{"name":"Acura","value":"20001","models":[{"name":"CL","value":"20773"},{"name":"ILX","value":"47843"},{"name":"ILX Hybrid","value":"48964"},{"name":"Integra","value":"21266"},{"name":"Legend","value":"21380"},{"name":"MDX","value":"21422"},{"name":"NSX","value":"21685"},{"name":"RDX","value":"21831"},{"name":"RL","value":"21782"},{"name":"RSX","value":"21784"},{"name":"SLX","value":"21879"},{"name":"TL","value":"22237"},{"name":"TSX","value":"22248"},{"name":"Vigor","value":"22362"},{"name":"ZDX","value":"32888"}]},{"name":"Alfa Romeo","value":"20047","models":[{"name":"164","value":"20325"},{"name":"8c Competizione","value":"34963"},{"name":"Spider","value":"22172"}]}';
var carobj = eval ("(" + cars + ")");
var select = document.getElementsByTagName('select')[0];
//print array elements out
for (var i = 0; i < carobj.USED.length; i++) {
var d = carobj.USED[i];
select.options.add(new Option(d.name, i))
};
If I read your question right, you want to populate a second select with the models for the make in the first select. See below for a purely JS approach (with jsfiddle). If possible, I would recommend looking into jQuery, since I would prefer a jQuery solution.
http://jsfiddle.net/m5U8r/1/
var carobj;
window.onload = function () {
var cars = '{"USED":[{"name":"Acura","value":"20001","models":[{"name":"CL","value":"20773"},{"name":"ILX","value":"47843"},{"name":"ILX Hybrid","value":"48964"},{"name":"Integra","value":"21266"},{"name":"Legend","value":"21380"},{"name":"MDX","value":"21422"},{"name":"NSX","value":"21685"},{"name":"RDX","value":"21831"},{"name":"RL","value":"21782"},{"name":"RSX","value":"21784"},{"name":"SLX","value":"21879"},{"name":"TL","value":"22237"},{"name":"TSX","value":"22248"},{"name":"Vigor","value":"22362"},{"name":"ZDX","value":"32888"}]},{"name":"Alfa Romeo","value":"20047","models":[{"name":"164","value":"20325"},{"name":"8c Competizione","value":"34963"}, {"name":"Spider","value":"22172"}]}]}';
carobj = eval ("(" + cars + ")");
var makes = document.getElementById('make');
for (var i = 0; i < carobj.USED.length; i++) {
var d = carobj.USED[i];
makes.options.add(new Option(d.name, i));
}
makes.onchange = getModels;
getModels();
}
// add models based on make
function getModels () {
var makes = document.getElementById('make');
var make = makes.options[makes.selectedIndex].text;
for (var i = 0; i < carobj.USED.length; i++) {
if (carobj.USED[i].name == make) {
var models = document.getElementById('model');
models.options.length = 0;
for (var j= 0; j < carobj.USED[i].models.length; j++) {
var model = carobj.USED[i].models[j];
models.options.add(new Option(model.name, j));
}
break;
}
}
}
I would also recommend looking into safer JSON parsing. There is a security risk in using eval if it runs on any user input. You could look into JSON.org and their json2.js. Or if you want to use jQuery: parseJSON. Below is the jQuery version:
jQuery.parseJSON(jsonString);
JSON parsing tips from: Safely turning a JSON string into an object.

Categories