Best answer

Invalid API Response: - Results must be an array

  • 3 December 2020
  • 9 replies
  • 1007 views

Userlevel 1

Hi 
I am building an app where I use VM2 to create another version of the javascript editor that has my custom functions inside.

I am using a search step to do this, but I am getting the error 

Invalid API Response: - Results must be an array, got: undefined, (undefined)

 

Here is my code:
 

const vm2 = require("vm2");
const moment = require("moment");
const fetch = require("node-fetch");

const runCode = async (code, inputData) => {
console.log(code);
console.log(inputData);
const vm = new vm2.NodeVM({
sandbox: {
moment,
fetch,
inputData,
},
});

const wrapper = `module.exports = (async function run() {
let output;
${code}
return output;
})()`;

const result = await vm.run(wrapper);

return result;
};

const perform = async (z, bundle) => {
console.log(z);
console.log(bundle);
const inputData = bundle.inputData;
const code = bundle.inputData.code;
const result = await runCode(code, inputData);
return result;
};

module.exports = {
key: "runJsCode",
noun: "Code",
display: {
label: "Run JavaScript Code",
description: "Runs JavaScript code",
},
operation: {
inputFields: [
{
key: "inputData",
label: "Input Data",
dict: true,
helpText:
"What input data should we provide to your code (as strings) via an object set to a variable named `inputData`?",
},
async (z, bundle) => {
return [
{
key: "code",
label: "Code",
type: "code",
language: "javascript",
default:
'// this is wrapped in an `async` function\n// you can use await throughout the function\n\noutput = [{id: 123, hello: "world"}];',
required: true,
},
];
},
],
perform,
sample: {
id: 1,
},
},
};

and here is my package.json file:
 

{
"name": "js-editor",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "jest --testTimeout 10000"
},
"dependencies": {
"moment": "^2.29.1",
"node-fetch": "^2.6.1",
"vm2": "^3.9.2",
"zapier-platform-core": "10.1.2"
},
"devDependencies": {
"jest": "^25.5.3"
},
"private": true
}

 

icon

Best answer by ikbelkirasan 5 December 2020, 23:16

View original

This post has been closed for comments. Please create a new post if you need help or have a question about this topic.

9 replies

Userlevel 7
Badge +10

Hi @Powerleech 

I’ve moved this to “Developer Discussion” for better visibility. 

Maybe @ikbelkirasan can help here?

Userlevel 7
Badge +12

@Powerleech - Does the script you’re providing to this step return an array of objects? 

Userlevel 1

@ikbelkirasan  - It does, as its default should be set to 
 

default:
'// this is wrapped in an `async` function\n// you can use await throughout the function\n\noutput = [{id: 123, hello: "world"}];',

But I found my error. I used a boilierplate code from a custom zapier app called ‘Advanced Utilitied’, which is supposed to be a “super charged” version of the code step, where I can use npm’s, my own functions, ect.

In this boiler plate OP is somehow setting the the inputData field `code` to be of the type: ‘code’.
This is something I haven’t been able to find in the official documentation.

OP was using v. 9.0.0 of the cli. I tried the integration, and it works fine, but I can’t seem to replicate the code.

source: 
https://github.com/ikbelkirasan/advanced-zapier-utilities-integration

I haven’t been able to fix this though :(

Userlevel 7
Badge +12

@Powerleech - Yeah, I know that app. Actually, I’m its author :)

Well, the `code` field type isn’t documented and it’s only used by the official code step app. I used it to enable syntax highlighting for JavaScript code.

However, that’s not the problem. The error is trying to tell you that the response of this step is undefined instead of an array. So, maybe you forgot to set the output value? Also, I suggest using return [...] instead of output = [...].

Hope this helps!

 

Userlevel 1

Ha ha, I see, how unattentative of me :) 
Thank you for creating that repository, if I can make it work for my idea, it will really help me out!

So as I am not using typescript, I have removed those actions I don’t need, transformed it to js, and changed it to a structure that I understand.

Maybe I just broke it, but now when I am running Jest, I see that everything works as it is supposed to.
And I didn’t add any stuff, only changed the test file to something very simple, and removed packages that I didn’t need in order to have a basic js template.

 PASS  test/searches/test.js
runJsCode
√ test (48ms)

console.log
[
{
othervariable: 'This is from code',
MyInputDataVariable: 'This is my input'
}
]

at test/searches/test.js:11:29

Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 3.144s

But when I push it to Zapier it gives me this error

 


I first thought it was because of my translation to js/simplication, but it also gave the error when I tried to push your repo (maybe I am doing something wrong there).

I suspect it has something to do the inputField code, but it seem to work when running jest:

 inputFields: [
{
key: "inputData",
label: "Input Data",
dict: true,
helpText:
"What input data should we provide to your code (as strings) via an object set to a variable named `inputData`?",
},
async (z, bundle) => {
return [
{
key: "code",
label: "Code",
type: "code",
language: "javascript",
default:
'// this is wrapped in an `async` function\n// you can use await throughout the function\n\noutput = [{id: 123, hello: "world"}];',
required: true,
},
];
},
],


Here is a link to my fork:
https://github.com/Powerleech/advanced-zapier-utilities-integration

And thank you for your comment, that led me to fix the other error from the API response.

Userlevel 1

Update:

I changed the code to a static string field, and now I can insert code.

const vm2 = require("vm2");
const moment = require("moment");

const runCode = async (code, inputData) => {
const vm = new vm2.NodeVM({
sandbox: {
moment,
inputData,
},
});

const wrapper = `module.exports = (async function run() {
let output;
${code}
return output;
})()`;

const result = await vm.run(wrapper);

return result;
};

const perform = async (z, bundle) => {
const code = bundle.inputData.code;
const inputData = bundle.inputData.inputData;
//console.log(code);
//console.log(inputData);
const result = await runCode(code, inputData);
console.log(result);
return result;
};

module.exports = {
key: "runJsCode",
noun: "runJsCode",
display: {
label: "Run JavaScript Code",
description: "Runs JavaScript code",
},
operation: {
inputFields: [
{
key: "inputData",
label: "Input Data",
dict: true,
helpText:
"What input data should we provide to your code (as strings) via an object set to a variable named `inputData`?",
},
{
key: "code",
label: "Code",
type: "string",
default:
'// this is wrapped in an `async` function\n// you can use await throughout the function\n\noutput = [{id: 123, hello: "world"}];',
required: true,
},
],
perform : perform,
sample: {
id: 1,
},
},
};


But I get another error when running the app in zapier:


 

Userlevel 7
Badge +12

@Powerleech - You’re welcome! I’m glad that you found it helpful :)

The problem here is that zapier CLI is trying to reduce the package size by removing unused dependencies. In order to include all the files of vm2 module, you should mention them in .zapierapprc file.

Check this out: https://github.com/ikbelkirasan/advanced-zapier-utilities-integration/blob/master/.zapierapprc#L5 

Once done, you should be able to upload the app. Good luck!

Userlevel 1

Thank you so much!

I did include that to the .zapierapprc file, but it still removes files from the vm2 module :(
But I found a sub-optimal solution where I use `zapier push --disable-dependency-detection`
so I doesn’t remove any files.

Now everything works for me, except if I console stuff in the code inputfiels, it is not returning it as logs.

Userlevel 7
Badge +12

@Powerleech - Nice! By the way, console logs are not supported.