Question

Help creating Action with Line Items support in 'Code Mode'

  • 20 July 2022
  • 5 replies
  • 48 views

Hi!

I’m trying to create a new Action for our app. I have created simple actions and triggers with success, but can’t create this one with ‘Line Items’ support.

This is the JSON required by our API. This is a simplified example:

{
"gross": "100",
"total": "121",
"name": "Adobe",
"lines": [
{
"sku": "",
"descr": "Corsair H60 120mm GAMING LGA1200",
"quantity": "1",
"price": "100.00000"
}
]
}

In the Input Designer, I created the generic fields and the line items fields:

In the API configuration tab, I have to Switch to ‘Code Mode’ because, as said, our API requires the json to come in the ‘data’ param, so I did this:

const options = {
url: 'https://myapp.cloud/api/expenses',
method: 'POST',
headers: {
'apikey': bundle.authData.apikey
},
params: {
'data': '{"name":"'+bundle.inputData.name+
'","gross":"'+bundle.inputData.gross+
'","total":"'+bundle.inputData.total+
'","lines":"'+bundle.inputData.lines+'"}'
}
}

Now if I “create a zap with this action’, I have tried with a single item/line…

...and using comma separated items like this:

...but it is not working as expected. I think the problem is in the “Code Mode” section, that requires the lines to be sent in other way.

My API log shows this as the received request:

JSON: {"name":"Peter","gross":"100","total":"121","lines":"[object Object]"}

How can I prepare the request to send the line items to my api server, inside a ‘data’ parameter?

Thanks!

 


5 replies

Do I need to add a Step with Zapier Transform, Utilities, etc. for this?

Userlevel 7
Badge +11

@santycg 

It looks like you have your input set up correctly. Meaning input for Expense items is a line item group so Zapier will return an array of objects for that field. 

You may need to manipulate the input into the correct key/value pair before sending your request to the API. 

It might be helpful to run some z.console.logs on bundle.inputData or to temporarily just return the bundle.inputData object (prior to returning z.request) just so you can better familiarize yourself with the bundle.inputData object

Without looking at the API docs i would add a header to your request ‘Content-Type’: ‘application/json’

And i would change ‘params’ to ‘body’ so that the data is sent in the body of the request and not as url params. 

based on your sample, body should look like the below (assuming your lines input has input fields with keys: sku, descr, quantity, & price)

body: {
"gross": bundle.inputData.gross,
"total": bundle.inputData.total,
"name": bundle.inputData.name,
"lines": bundle.inputData.lines
}

 

Userlevel 2
Badge +1

Hey there, @santycg !

 

Line items can definitely be tricky. One thing to note here is that `bundle.inputData.lines` will be an array. And each element in the array will be an object that has the sub-keys you’ve defined in that line item group. 

Now, looking at this line item group documentation, That documentation is wrong (and I’ve told the team that maintains it). Zapier will not automatically parse a comma-separated value into line items. If you have a comma-separated value and need to parse it into line items, we have the “Text-to-Line-Item” transformation in the Formatter app. That will take a comma-separated piece of text and parse it into an array of line items that it will send to your action step. You can also do a Code step. See this example of one I set up for testing my own line items work: https://cdn.zappy.app/2a85eef7bf367801c897ea78ba8e5b1d.png

Now, you could write your code to expect comma-separated values there and parse them into an array yourself. However, that would break things in the case where somebody actually was sending in line items (an array). And it doesn’t cover the case where there are commas in your fields, and Price, Name, and Quantity all seem likely to contain commas at some point.

Hope that helps...let me know if you have more questions!

Sorry, but I can`t get it to work.

How can I test the Action? The Action editor lets me assign sample values for each param, but what do I to write in the Lines field?

No matter what I write there. It always returns this:

'str' object has no attribute 'items'.

I can ignore the ‘test’ and create the Action. So I create a new Zap Template, integrating for example, eBay with my app. (I also tried with Shopify, Stripe…). I just need to get line items and send them to my app.

So, I create a new Zap template: New Order in eBay → New Order in my App.

As the Second Step, I added the Formatter by Zapier → Utilities → Line Item to Text.

I also tried with Line Itemizer, etc. with same result: I always get this error:

I don’t know that this error message means.

Is there any existing zap template I can use as example? I suppose there mus be a lot of zap templates that do the same I need: get line items from A and convert/itemize to B.

Userlevel 2
Badge +1

As far as the Zap goes ...

> As the Second Step, I added the Formatter by Zapier → Utilities → Line Item to Text. I also tried with Line Itemizer, etc.

Can you try with “Text-to-Line-Item” instead? I was just able to get it to work. Make sure you enter a comma-separated value there.

Since three of your line items fields are required, you’ll need three steps there and then map those in to the action step as shown here: https://cdn.zappy.app/6a46a61a2bcf42e29acd28b32f92287d.png

Can you give that a try and let me know how that goes?

And then back to the code…

> How can I test the Action? The Action editor lets me assign sample values for each param, but what do I to write in the Lines field? … No matter what I write there. It always returns this:

I think there is a problem with the way you’ve set up your code here: https://cdn.zappy.app/daa67f0d314d8996db19198fe751329e.png

That’s going to put one giant string in the data field, where what I think you want is something more like:

params: {
data: {
nombre: bundle.inputData.nombre,
importe: bundle.inputData.importe,
total: bundle.inputData.total,
fpago: bundle.inputData.fpago,
lines: bundle.inputData.lines
}
}

And for now, to test that, it might even be best at first to just hard code some data there to make sure we can get it to work in the simplest of examples. For example, just enter:

params: {
data: {
nombre: 12345,
importe: "testimporte",
total: 6789,
fpago: "test fpago",
lines: [
{
"descr": "description",
"quantity": 1
"price": 2
},
{
"descr": "description again",
"quantity": 3
"price": 4
}
]
}
}

Thanks!

Reply