别离开,为了更好的访问体验,请进行验证,通过后即可继续访问网页

assignment mismatch 1 variable but e.watch returns 2 values

Golang中的变量声明

assignment mismatch 1 variable but e.watch returns 2 values

第3部分:变量

这是Golang教程系列中的第三篇教程,它涉及Golang中的变量。

您可以阅读Golang教程第2部分:Hello World,以了解有关配置Go和运行hello world程序的信息。

什么是变量? 变量是为存储位置指定的名称,用于存储特定类型的值。Go中有多种语法来声明变量。让我们一一看一下。

声明一个变量 var name type是声明单个变量的语法。

该语句var age int声明一个名为agetype 的变量int。我们尚未为该变量分配任何值。如果未为变量分配任何值,则Go会使用变量类型的零值自动对其进行初始化。在这种情况下,为age分配了值0,即零值int。如果运行此程序,则可以看到以下输出。

可以将变量分配给其类型的任何值。在上面的程序中,age可以分配任何整数值。

上面的程序将打印以下输出。

声明具有初始值的变量 声明变量时,还可以为其提供初始值。以下是声明具有初始值的变量的语法。

在上述程序中,age是类型的变量,int并且具有初始值29。上面的程序将打印以下输出。

它显示年龄已经用值29初始化。

类型推断 如果变量具有初始值,Go将自动使用该初始值来推断该变量的类型。因此,如果变量具有初始值,则可以删除变量声明中的type。

如果使用以下语法声明了变量

Go会自动从初始值推断出该变量的类型。

在下面的示例中,我们可以看到int变量的类型age已在行号中删除.由于变量具有初始值29,因此Go可以推断出它的类型int。

多变量声明 可以使用单个语句声明多个变量。

上面的程序将width is 100 height is 50作为输出打印。

正如您现在可能已经猜到的那样,如果未为宽度和高度指定初始值,则将它们初始值指定为0。

在某些情况下,我们可能希望在单个语句中声明属于不同类型的变量。这样做的语法是

下面的程序使用上面的语法声明不同类型的变量。

在这里我们声明一个变量name,类型为string,age和height,类型为int。(在下一个教程中,我们将讨论Golang中可用的各种类型)。

Go还提供了另一种简洁的声明变量的方法。这被称为简写声明,它使用:=运算符。

以下程序使用简写语法声明一个count初始化为的变量10。Go会自动推断出该count类型,int因为它已经使用整数值进行了初始化10。

以上程序将打印,

也可以使用简写语法在一行中声明多个变量。

上述程序声明两个变量name和age, 类型分别为string和int。

如果您运行上述程序,则可以看到my name is naveen age is 29打印内容。

简写声明要求赋值左侧所有变量的初始值。以下程序将打印错误assignment mismatch: 2 variables but 1 values。这是因为尚未为age分配值。

仅当新声明了:=左侧变量中的至少一个时,才可以使用简写语法。考虑以下程序,

在上面的程序中, b已经被声明,但是c是新声明的,因此它可以工作并输出

而如果我们运行以下程序,

它将打印错误,/prog.go:8:10: no new variables on left side of :=这是因为变量a和b已经被声明,并且在行号:=的左侧没有新变量。

也可以为变量分配在运行时计算的值。考虑以下程序,

在上面的程序中,math是一个包,Min是该包中的函数。现在不用担心,我们将在即将到来的教程中详细讨论软件包和功能。所有我们需要知道的是,c的值在运行时计算,它在a和b中选出最小的值。上面的程序将打印,

由于Go是强类型的,因此不能为声明为属于一种类型的变量分配另一种类型的值。以下程序将打印错误,cannot use “naveen” (type string) as type int in assignment因为age已声明为type,int并且我们正在尝试为其分配string值。

assignment mismatch 1 variable but e.watch returns 2 values

“相关推荐”对你有帮助么?

assignment mismatch 1 variable but e.watch returns 2 values

请填写红包祝福语或标题

assignment mismatch 1 variable but e.watch returns 2 values

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。 2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

assignment mismatch 1 variable but e.watch returns 2 values

assignment mismatch 1 variable but e.watch returns 2 values

golang 返回错误和接受对象个数不匹配的问题,修改错误之后不起作用

问答 / 42 / 2 / 创建于 4年前

livego,一个golang的音视频开源项目,在拉代码进行编译的时候遇到的,错误如下 assignment mismatch: 2 variables but uuid.NewV4 returns 1 values

这个错误应该就是NewV4这个方法有两个返回值,但接受对象只有一个吧,然后我就增加了一个接受值,如下图

在编译一个开源项目时遇到( assignment mismatch: 2 variables but uuid.NewV4 returns 1 values),修改错误之后不起作用

  • 我修改成下面这样,依旧报这个错误

在编译一个开源项目时遇到( assignment mismatch: 2 variables but uuid.NewV4 returns 1 values),修改错误之后不起作用

  • uuid.NewV4()函数截图

在编译一个开源项目时遇到( assignment mismatch: 2 variables but uuid.NewV4 returns 1 values),修改错误之后不起作用

忘了附上这个相关的开源项目的地址了, https://github.com/gwuhaolin/livego.git

assignment mismatch 1 variable but e.watch returns 2 values

大概率依赖包版本问题,你的修改没有问题!至于为什么没有生效,了解情况太少不太好猜测!

assignment mismatch 1 variable but e.watch returns 2 values

  • 《LearnKu 社区规范》

assignment mismatch 1 variable but e.watch returns 2 values

粤ICP备18099781号-6 | 粤公网安备 44030502004330号 | 违法和不良信息举报

由 Summer 设计和编码 ❤

我要举报该 ,理由是:

Navigation Menu

Search code, repositories, users, issues, pull requests..., provide feedback.

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly.

To see all available qualifiers, see our documentation .

  • Notifications You must be signed in to change notification settings

vip

assignment mismatch: 2 variables but uuid.NewV4 returns 1 values

在使用 github.com/satori/go.uuid 包生成 uuid 时,突然发现一个很奇怪的问题。如下图示。 编译器和启动时,报错冲突。

在这里插入图片描述

把 go.mod 中的版本声明,使用新版本即可解决。

在这里插入图片描述

  • what is erf function
  • week planner templates
  • 漳州职业技术学院录取分数线
  • 彩礼10万属于什么水平
  • 我没后悔遇见你只是觉得遗憾

assignment mismatch 1 variable but e.watch returns 2 values

7 Ways to Look at the Values of Variables While Debugging in Visual Studio

' data-src=

Aaron Hallberg

July 15th, 2016 1 1

When you are running your code and something is behaving unexpectedly, how do you find out what is going wrong? When I was in school the first way I learned how to debug a wonky application was by sticking “print()” statements all over the place, running my code, and looking back through the log of output seeing if I noticed that something looked wrong. Then if I wanted to look at the value of another variable I would have to add a new “print()” statement, recompile, and re-run the application again. This can be a tedious process, so I am pleased to tell you there is a better way than littering your code with a slew of “print()” statements you’ll have to remove later. You can use the tools of the Visual Studio debugger to inspect variables on the fly.

In this post I will review seven different ways to inspect the values of your variables while debugging through your code in the Visual Studio debugger without modifying your code. Which ways do you already use? Let us know in the comments below.

If you’re interested in giving us feedback about our future ideas, please help us improve the Visual Studio debugger by joining our community .

In order to look at the value of variables while you are debugging, you first need to be in break mode. You can be stopped at a breakpoint, stopped while stepping, or even stopped at an Exception, and then you will have access to your variable values using these techniques.

1. DataTip

Hover over a variable to see its value.

The most commonly used way to look at variables is the DataTip . When stopped in the debugger hover the mouse cursor over the variable you want to look at. The DataTip will appear showing you the value of that variable. If the variable is an object, you can expand the object by clicking on the arrow to see the elements of that object.

You can also “pin” a DataTip to your code by clicking on the pin icon next to a value. This way you can see the value change right in-line with your code as you are stepping through it. This can come in handy when debugging inside of loops where you are watching a single value continually change.

2. Autos Window

**See variables used near your instruction pointer. **

As you stop at different places in your code the Autos window will automatically populate with all the variables used in the current statement (the line where the yellow instruction pointer is) and some surrounding statements. The scope of what variables automatically populate from the surrounding statements depends on the language you are debugging. Typically, you will see variables that are referenced 3 lines behind and 1 line ahead of the current statement. Some languages like JavaScript are not supported by the Autos window.

image

Open up this window from Debug/Windows/Autos Window (Ctrl+Alt+V, A)

3. Locals Window

**See variables that exist in the local scope of your current stack frame. **

The Locals window will populate with the local variables for the current method that have. Like the Autos window, variables that appear here are automatically populated. Deciding which window you prefer to use depends on which scope of the variables you would like to see.

In all of our variable windows, when any values of the variables change the new values will appear in red text.

image

Open up this window from Debug/Windows/Locals Window (Ctrl+Alt+V, L).

4. Watch Windows

Evaluate variables and ** expressions and keep track of the results. **

There are four Watch windows available to use. These windows start out blank and let you add the names of variables that you care about watching as you debug your application. You can click in the editable line under the name column and type in the variable name whose value you want to see. Or you can right click on variables from your code editor and select “Add to Watch”.

Beyond adding just a single variable, you can type in generally any expression. So you can potentially call methods, evaluate lambdas, or just do things like “1+3”. Note that when you type in an expression that executes code there could be side effects that change the state of your application .

image

Open up these windows from Debug/Windows/Watch (Ctrl+Alt+W, 1).

5. QuickWatch dialog

**Quickly inspect the value and properties of a single variable or expression in a disposable pop-up diag. **

The QuickWatch window is a dialog that you can use to inspect a single variable or expression. This temporary dialog is convenient to use when you want more space to inspect all of the properties of an object, but don’t want to modify your window layout.

image

Open the QuickWatch window by right clicking on a variable and selecting “QuickWatch…” or by using the keyboard shortcut Shift+F9.

6. Parallel Watch Windows

See the value of a variable or expression simultaneously across multiple threads or recursive calls.

There are four Parallel Watch windows available to use. Similar to the Watch windows, you can click in the editable line and type in the variable name or expression whose value you want to see.

Each row in the window identifies a different thread and so you can see the value of the same variable across all your current threads.

It will also show you the value of a variable in a recursive stack across the same thread, where each row is an iteration of that function call.

Open up these windows from Debug/Windows/Parallel Watch (Ctrl+Shift+D, 1).

7. Immediate Window

Use this scratch pad to view and change the values of variables at a point in time.

While stopped at a line of code, you can type a variable or expression into the Immediate window and hit enter to view the result. The Immediate window evaluates expressions just like the Watch windows and can result in side effects.

You can also use the Immediate window to execute complex expressions (even evaluate lambda expressions) and view the results without having to edit and re-execute your code. This window can also be used at design time, before you have started a debugging session.

image

Open the Immediate Window from Debug/Windows/Immediate Window (Ctrl+Alt+I).

This list provides a basic overview of different ways to inspect variables using Visual Studio. What is your favorite way to see your variable values while debugging? Let us know in the comments below.

If you are interested in helping give feedback about our future ideas, sign up to help us improve the Visual Studio Debugger .

' data-src=

Aaron Hallberg Partner Director of Product, Azure DevOps

' data-src=

Discussion is closed. Login to edit/delete existing comments.

This was a very helpful article. I have recently lost my sight so I am currently in the process of learning how to do my job using JAWS text-to-speech software.

I used to use the hover tip to examine variables during debugging and I did not realise there were other ways of doing this. I have not tried all of the other methods but the ‘Locals’ window works quite well.

light-theme-icon

Subscribe to input changes

watch: (names?: string | string[] | (data, options) => void) => unknown

This method will watch specified inputs and return their values. It is useful to render input value and for determining what to render by condition.

When defaultValue is not defined, the first render of watch will return undefined because it is called before register . It's recommend to provide defaultValues at useForm to avoid this behaviour, but you can set the inline defaultValue as the second argument.

When both defaultValue and defaultValues are supplied, defaultValue will be returned.

This API will trigger re-render at the root of your app or form, consider using a callback or the useWatch api if you are experiencing performance issues.

watch result is optimised for render phase instead of useEffect 's deps, to detect value update you may want to use an external custom hook for value comparison.

The following video tutorial demonstrates watch API.

Thank you for your support

If you find React Hook Form to be useful in your project, please consider to star and support it.

go - 编写传递匿名函数作为参数的高阶函数

标签 go lambda closures anonymous-function higher-order-functions

重现此代码的方法如下: https://play.golang.org/p/ostuT1QFV4C **

我正在尝试编写一个函数,允许我传递用于获取数据并将其转换为字符串的任何方法。这是为了更好地理解如何在 Go 中使用高阶函数的尝试。

我尝试过以几种不同的方式使用此功能,但没有一种能正常工作。

例如,在我可能会使用它的一种情况下,我可以构造一个匿名函数,它围绕一个变量关闭并返回一个不接受任何参数并返回 ([]byte, error) 。从理论上讲,只要我可以返回不接受任何参数并返回 ([]byte, error) 的匿名方法,这种方法就允许我包装任何获取数据的代码。

但是,我尝试实现它却失败了。

assignment mismatch: 1 variable but func literal returns 2 values

(作为引用, ioutil.ReadFile(..) 返回 ([]byte, error) 。)

我假设(可能是错误的)我的错误意味着匿名函数正在立即执行(就像 Javascript 中的 IIFE),所以我尝试将内部部分包装在一个函数中(试图强制匿名函数返回一个函数,而不是 2 个值),像这样:

但是 IDE 强制我将“nil,”添加到匿名函数的一部分,这似乎违反了我打算做的事情(除非我误解了什么)。无论如何,它给了我这个错误:

./main.go:247:20: assignment mismatch: 1 variable but func literal returns 2 values ./main.go:248:15: cannot use func literal (type func() ([]byte, error)) as type error in return argument: func() ([]byte, error) does not implement error (missing Error method)

我可以用 Go 做我想做的事吗?

为了完整起见, nfsConfigs.json 的内容如下所示:

不创建匿名函数。它 调用 匿名函数,因为训练 () 。

关于go - 编写传递匿名函数作为参数的高阶函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57797589/

上一篇: go - 在 Go 包函数中模拟函数

下一篇: json - 如何实现自定义 json 验证器.

go - 如何在Goroutine中处理错误

Golang 加密随机播放

multithreading - 从 Go 应用程序中的线程低级 C/C++ 代码层调用 Go 回调

c++ - 传递本地创建的 lambda 用于回调,然后超出范围

c# - 创建所有 ExpressionTree/Func 参数的数组

go - go中的包解耦

python - Pandas lambda 函数无法识别 NaN

javascript - 试图了解这个 JS 函数的作用及其参数是什么,有人可以解释一下吗?

java - Java中的匿名类和闭包有什么区别?

html5-canvas - Chrome 的非法调用错误和关闭

©2024 IT工具网   联系我们

Find Study Materials for

  • Explanations
  • Business Studies
  • Combined Science
  • Computer Science
  • Engineering
  • English Literature
  • Environmental Science
  • Human Geography
  • Macroeconomics
  • Microeconomics
  • Social Studies
  • Browse all subjects
  • Read our Magazine

Create Study Materials

  • Flashcards Create and find the best flashcards.
  • Notes Create notes faster than ever before.
  • Study Sets Everything you need for your studies in one place.
  • Study Plans Stop procrastinating with our smart planner features.
  • Watch Variable

Explore the powerful tool known as the Watch Variable in this comprehensive guide to Computer Science programming. You'll delve into the meaning and function of the Watch Variable and its essential role in problem-solving techniques. Harnessing the abilities of this potent component can elevate programming efficiency and accuracy to new heights. Uncover valuable insights on how to utilise Watch Variables in Visual Studio, where you can directly observe variable changes and implement them practically. This journey doesn't stop there. It also presents a plethora of significant benefits reaped from the appropriate application of Watch Variables in computer science. Learn how to evaluate watch variable values and integrate expressions into your captivating code. Embark on this enlightening expedition to navigate computer science's intricate terrain with the expert navigation of the Watch Variable.

Watch Variable

Create learning materials about Watch Variable with our free learning app!

  • Instand access to millions of learning materials
  • Flashcards, notes, mock-exams and more
  • Everything you need to ace your exams
  • Algorithms in Computer Science
  • Computer Network
  • Computer Organisation and Architecture
  • Computer Programming
  • Computer Systems
  • Data Representation in Computer Science
  • Data Structures
  • Functional Programming
  • Issues in Computer Science
  • Problem Solving Techniques
  • Abstraction Computer Science
  • Agile Methodology
  • Agile Scrum
  • Breakpoints
  • Computational Thinking
  • Decomposition Computer Science
  • Integration Testing
  • Kanban Boards
  • Pattern Recognition
  • Software Development Life Cycle
  • Step Into Debugging
  • Step Over Debugging
  • System Testing
  • Unit Testing
  • Waterfall Model
  • Theory of Computation

Understanding the Watch Variable in Computer Science

Watch variable meaning and function.

A watch variable is simply a feature provided by various debugging tools that lets you monitor the changes in the value of a variable during the execution of a program. As such, this makes it easier to detect anomalies and debug the code.

  • Select a variable which you want to monitor
  • Add that variable to your list of watch expressions
  • Run your program

For example, suppose there is a specific variable, say 'count', in your code. When you add 'count' to the watch window, the debugger will monitor its value and allow you to see how it changes throughout the program execution.

Essential Role of Watch Variable in Problem Solving Techniques

Observing changes in variable values can contribute significantly to debugging efforts; it can expose unexpected behaviours, highlight instances where variables are assigned incorrect values, or reveal instances where variables are not changing when they should.

It's important to remember that the goal of using watch variables is not to change the values during runtime. Instead, this feature is meant to facilitate a greater understanding of how the program operates and reveal where potential bugs lie.

Utilising Watch Variables in Visual Studio

Approach to visual studio watch variable change.

  • Run your program in debug mode
  • Navigate to the "Debug" menu
  • Select the "Windows" option, then click on "Watch"
  • In the watch window, type the name of the variable you want to watch

The value of the watch variable, as well as the location of its latest defined or modified position in the code, will be displayed in the watch window.

It's crucial to note, values of variables that go out of scope are automatically grayed out. This highlights that the variable may no longer be relevant, providing a hint about the correctness of the flow of your program.

In a complex program where you need to keep an eye on two variable values and their interaction, this proves beneficial. For example, if a loop counter 'i' and some array element 'array[i]' interact, adding the expression 'array[i]' in the watch window will allow you to monitor how 'array[i]' changes as 'i' increments.

Practical Examples of Watch Variables in Visual Studio

  • Run this program in debug mode
  • Go to the "Debug" menu, select "Windows" then "Watch"
  • Type 'values[i]' in the watch window and press Enter

These tools empower the debugging process, making it more interactive and less daunting. The use of watch variables can save you a lot of time and frustrations while familiarising you with the inner workings of your code, thereby improving your overall coding skills.

Making the Most of Watch Variables

Significant benefits of watch variables in computer science.

  • Immediate Feedback: Watch variables offer programmers immediate feedback. Rather than waiting for a code block's execution to finish, you receive real-time updates about variable states.
  • Error Detection: It is easier to identify unintentional variable changes. Spotting such changes can be vital in troubleshooting and ultimately fixing errors before the code goes into production.
  • In-depth Understanding: Through visualizing variables' values change, you gain better knowledge of the inner workings of your code, leading to an enhanced mastery of programming concepts.

For instance, in a game development scenario, you might have a variable controlling the game play speed. By using watch variables, you can monitor the variation of this variable during gameplay, thus being able to assure the desired behaviour is met.

How to Evaluate Watch Variable Values

  • Select and highlight the variable you want to watch.
  • Right-click the selected variable. An option to add the variable to a watch list usually appears.
  • Once added, the watch window should list the variable with its current value and update it in real-time as your program runs.

Incorporating Watch Variable Expressions into Your Code

  • Run your program in Debug mode.
  • Navigate to the Debug menu.
  • Select Windows and then Watch.
  • Type 'debit + credit' in the field and press enter.

Just remember, while this function provides real-time status updates for the watched expressions, it doesn't directly influence the execution of your code. It's a window into the engine of your program, not the control stick. Watch variables and expressions provide vital insight into your application, but they won't fix coding errors for you. It's your responsibility to interpret the data they provide and apply it to refining your coding strategy.

Watch Variable - Key takeaways

Watch Variable: A feature provided by various debugging tools that monitor the changes in the value of a variable during the execution of a program. This helps in catching anomalies and debugging the code.

Usage of Watch Variable: Allows direct observation of a variable's changes through the program execution which can reveal unexpected behaviors leading to bugs.

Evaluating Watch Variable Values: This process can illuminate how certain variables change state during the runtime of a program. It provides essential insights into the runtime behavior of the code.

Watch Variable Expressions: More than single variables, expressions involving multiple variables or function calls can also be watched. This can provide more complex and insightful information necessary for debugging intricate code behavior.

Benefits of Watch Variables: Enhances understanding of changes in program behavior, offers immediate feedback, facilitates error detection, and promotes in-depth understanding of the inner workings of your code.

Flashcards inWatch Variable 15

What is the main function of a watch variable in computer programming?

A watch variable is a feature provided by various debugging tools that allows you to monitor changes in a variable's value during the execution of a program, aiding in code debugging.

What steps are typically involved in using a watch variable?

First, you select a variable to monitor. Next, add that to your watch expressions list, then run your program that is being debugged.

How are watch variables beneficial for problem-solving techniques in computer programming?

By monitoring variable value changes, watch variables can help pinpoint where things go wrong, highlight unexpected behaviors, or reveal variables not changing when they should, simplifying debugging.

What is one crucial thing to remember about the use of watch variables?

The goal of using watch variables is not to change the values during runtime, but to better understand how the program operates and identify potential bugs.

How is a watch variable's status typically displayed?

Often the debugger will include a watch window, which displays in real-time, the variable in question and its current value.

What is the function of watch variables in Visual Studio's integrated development environment?

Watch variables allow developers to monitor variable values in real-time during debugging, facilitating the observation of any unexpected behaviours leading to bugs.

Watch Variable

Learn with 15 Watch Variable flashcards in the free StudySmarter app

We have 14,000 flashcards about Dynamic Landscapes.

Already have an account? Log in

Frequently Asked Questions about Watch Variable

Test your knowledge with multiple choice flashcards.

Watch Variable

Join the StudySmarter App and learn efficiently with millions of flashcards and more!

Keep learning, you are doing great.

1

About StudySmarter

StudySmarter is a globally recognized educational technology company, offering a holistic learning platform designed for students of all ages and educational levels. Our platform provides learning support for a wide range of subjects, including STEM, Social Sciences, and Languages and also helps students to successfully master various tests and exams worldwide, such as GCSE, A Level, SAT, ACT, Abitur, and more. We offer an extensive library of learning materials, including interactive flashcards, comprehensive textbook solutions, and detailed explanations. The cutting-edge technology and tools we provide help students create their own learning materials. StudySmarter’s content is not only expert-verified but also regularly updated to ensure accuracy and relevance.

Watch Variable

StudySmarter Editorial Team

Team Watch Variable Teachers

  • 11 minutes reading time
  • Checked by StudySmarter Editorial Team

Study anywhere. Anytime.Across all devices.

Create a free account to save this explanation..

Save explanations to your personalised space and access them anytime, anywhere!

By signing up, you agree to the Terms and Conditions and the Privacy Policy of StudySmarter.

Sign up to highlight and take notes. It’s 100% free.

Join over 22 million students in learning with our StudySmarter App

The first learning app that truly has everything you need to ace your exams in one place

  • Flashcards & Quizzes
  • AI Study Assistant
  • Study Planner
  • Smart Note-Taking

Join over 22 million students in learning with our StudySmarter App

This browser is no longer supported.

Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.

Watch variables with Watch windows and QuickWatch

  • 15 contributors

While you're debugging, you can use Watch windows and QuickWatch to watch variables and expressions. The windows are only available during a debugging session.

Watch windows can display several variables at a time while debugging. The QuickWatch dialog displays a single variable at a time, and must be closed before debugging can continue. For more information on using QuickWatch, see Observe a single variable or expression with QuickWatch .

If this is the first time that you've tried to debug code, you may want to read Debugging for absolute beginners and Debugging techniques and tools before going through this article.

Observe variables with a Watch window

You can open more than one Watch window, and observe more than one variable in a Watch window.

For example, to set a watch on the values of a , b , and c in the following code:

Set a breakpoint on the c = a + b; line by clicking in the left margin, selecting Debug > Toggle Breakpoint , or pressing F9 .

Start debugging by selecting the green Start arrow or Debug > Start Debugging , or press F5 . Execution pauses at the breakpoint.

Open a Watch window by selecting Debug > Windows > Watch > Watch 1 , or pressing Ctrl + Alt + W > 1 .

You can open additional Watch windows by selecting windows 2 , 3 , or 4 .

In the Watch window, select an empty row, and type variable a . Do the same for b and c .

Screenshot of Watch variables.

Continue debugging by selecting Debug > Step Into or pressing F11 as needed to advance. The variable values in the Watch window change as you iterate through the for loop.

For C++ only,

You may need to qualify the context of a variable name, or an expression that uses a variable name. The context is the function, source file, or module where a variable is located. If you have to qualify the context, use the context operator (C++) syntax in the Name in the Watch window.

You can add register names and variable names using $<register name> or @<register name> to the Name in the Watch window. For more information, see Pseudovariables .

Use expressions in a Watch window

You can observe any valid expression recognized by the debugger in a Watch window.

For example, for the code in the preceding section, you can get the average of the three values by entering (a + b + c) / 3 in the Watch window:

Screenshot of Watch expression.

The rules for evaluating expressions in the Watch window are generally the same as the rules for evaluating expressions in the code language. If an expression has a syntax error, expect the same compiler error as in the code editor. For example, a typo in the preceding expression produces this error in the Watch window:

Screenshot of Watch expression error.

A circle with two wavy lines icon may appear in the Watch window. This icon means the debugger doesn't evaluate the expression because of a potential cross-thread dependency. Evaluating the code requires other threads in your app to run temporarily, but since you are in break mode, all threads in your app are usually stopped. Allowing other threads to run temporarily can have unexpected effects on the state of your app, and the debugger may ignore events such as breakpoints and exceptions on those threads.

Search in the Watch window

You can search for keywords in the Name, Value, and Type columns of the Watch window using the search bar above each window. Hit ENTER or select one of the arrows to execute a search. To cancel an ongoing search, select the "x" icon in the search bar.

Use the left and right arrows (Shift+F3 and F3, respectively) to navigate between found matches.

Screenshot of Search in Watch Window.

To make your search more or less thorough, use the Search Deeper dropdown at the top of the Watch window to select how many levels deep you want to search into nested objects.

Pin properties in the Watch window

This feature is supported in .NET Core 3.0 or higher.

You can quickly inspect objects by their properties in the Watch window with the Pinnable Properties tool. To use this tool, hover over a property and select the pin icon that appears or right-click and select the Pin Member as Favorite option in the resulting context menu. This bubbles up that property to the top of the object’s property list, and the property name and value is displayed in the Value column. To unpin a property, select the pin icon again or select the Unpin Member as Favorite option in the context menu.

You can also toggle property names and filter out non-pinned properties when viewing the object’s property list in the Watch window. You can access both options by selecting the buttons in the toolbar above the watch window.

Refresh watch values

A refresh icon (circular arrow) might appear in the Watch window when an expression is evaluated. The refresh icon indicates an error or a value that is out of date.

To refresh the value, select the refresh icon, or press the spacebar. The debugger tries to reevaluate the expression. However, you may not want or be able to reevaluate the expression, depending on why the value wasn't evaluated.

Hover over the refresh icon or see the Value column for the reason the expression wasn't evaluated. Reasons include:

An error occurred as the expression was being evaluated, as in the previous example. A timeout might occur, or a variable might be out of scope.

The expression has a function call that could trigger a side effect in the app. See Expression side effects .

Automatic evaluation of properties and implicit function calls is disabled.

If the refresh icon appears because automatic evaluation of properties and implicit function calls is disabled, you can enable it by selecting Enable property evaluation and other implicit function calls in Tools > Options > Debugging > General .

To demonstrate using the refresh icon:

In Tools > Options > Debugging > General , clear the Enable property evaluation and other implicit function calls check box.

Enter the following code, and in the Watch window, set a watch on the list.Count property.

Start debugging. The Watch window shows something like the following message:

Screenshot of Refresh Watch.

To refresh the value, select the refresh icon, or press the spacebar. The debugger reevaluates the expression.

Expression side effects

Evaluating some expressions can change the value of a variable, or otherwise affect the state of your app. For example, evaluating the following expression changes the value of var1 :

This code can cause a side effect . Side effects can make debugging more difficult by changing the way your app operates.

An expression with side effects is evaluated only once, when you first enter it. After that, the expression appears grayed out in the Watch window, and further evaluations are disabled. The tooltip or Value column explains that the expression causes a side effect. You can force reevaluation by selecting the refresh icon that appears next to the value.

One way to prevent the side effects designation is to turn off automatic function evaluation. In Tools > Options > Debugging > General , deselect Enable property evaluation and other implicit function calls .

For C# only, when evaluation of properties or implicit function calls is turned off, you can force evaluation by adding the ac format modifier to a variable Name in the Watch window. See Format specifiers in C# .

Use Object IDs in the Watch window (C# and Visual Basic)

Sometimes you want to observe the behavior of a specific object. For example, you might want to track an object referred to by a local variable after that variable has gone out of scope. In C# and Visual Basic, you can create Object IDs for specific instances of reference types, and use them in the Watch window and in breakpoint conditions. The Object ID is generated by the common language runtime (CLR) debugging services and associated with the object.

Object IDs create weak references that don't prevent the object from being garbage collected. They are valid only for the current debugging session.

In the following code, the MakePerson() method creates a Person using a local variable:

To find out the name of the Person in the DoSomething() method, you can add a reference to the Person Object ID in the Watch window.

Set a breakpoint in the code after the Person object has been created.

Start debugging.

When execution pauses at the breakpoint, open the Locals window by choosing Debug > Windows > Locals .

In the Locals window, right-click the Person variable and select Make Object ID .

You should see a dollar sign ( $ ) plus a number in the Locals window, which is the Object ID.

Add the object ID to the Watch window by right-clicking the Object ID and selecting Add Watch .

Set another breakpoint in the DoSomething() method.

Continue debugging. When execution pauses in the DoSomething() method, the Watch window displays the Person object.

If you want to see the object's properties, such as Person.Name , you must enable property evaluation by selecting Tools > Options > Debugging > General > Enable property evaluation and other implicit function calls .

Dynamic View and the Watch window

Some scripting languages (for example, JavaScript or Python) use dynamic or duck typing, and .NET version 4.0 and later supports objects that are difficult to observe in the normal debugging windows.

The Watch window displays these objects as dynamic objects, which are created from types that implement the IDynamicMetaObjectProvider interface. Dynamic object nodes show the dynamic members of the dynamic objects, but don't allow editing of the member values.

To refresh Dynamic View values, select the refresh icon next to the dynamic object node.

To display only the Dynamic View for an object, add a dynamic format specifier after the dynamic object name in the Watch window:

  • For C#: ObjectName, dynamic
  • For Visual Basic: $dynamic, ObjectName
  • The C# debugger doesn't automatically reevaluate the values in the Dynamic View when you step to the next line of code.
  • The Visual Basic debugger automatically refreshes expressions added through the Dynamic View .
  • Evaluating the members of a Dynamic View can have side effects .

To insert a new watch variable that casts an object to a dynamic object:

  • Right-click any child of a Dynamic View .
  • Choose Add Watch . The object.name becomes ((dynamic) object).name and appears in a new Watch window.

The debugger also adds a Dynamic View child node of the object to the Autos window. To open the Autos window, during debugging, select Debug > Windows > Autos .

Dynamic View also enhances debugging for COM objects. When the debugger gets to a COM object wrapped in System.__ComObject , it adds a Dynamic View node for the object.

Observe a single variable or expression with QuickWatch

You can use QuickWatch to observe a single variable.

For example, for the following code:

To observe the a variable,

Set a breakpoint on the a = a + b; line.

Start debugging. Execution pauses at the breakpoint.

Select the variable a in the code.

Select Debug > QuickWatch , press Shift + F9 , or right-click and select QuickWatch .

The QuickWatch dialog appears. The a variable is in the Expression box with a Value of 1 .

Screenshot of QuickWatch variable.

To evaluate an expression using the variable, type an expression such as a + b in the Expression box, and select Reevaluate .

Screenshot of QuickWatch expression.

To add the variable or expression from QuickWatch to the Watch window, select Add Watch .

Select Close to close the QuickWatch window. ( QuickWatch is a modal dialog, so you can't continue debugging as long as it is open.)

Continue debugging. You can observe the variable in the Watch window.

Related content

  • What is debugging?
  • Debugging techniques and tools
  • First look at debugging
  • Debugger windows

Was this page helpful?

Coming soon: Throughout 2024 we will be phasing out GitHub Issues as the feedback mechanism for content and replacing it with a new feedback system. For more information see: https://aka.ms/ContentUserFeedback .

Submit and view feedback for

Additional resources

assignment mismatch 1 variable but e.watch returns 2 values

Beego开发中出现的报错:assignment mismatch: 1 variable but web.AppConfig.String returns 2 values

assignment mismatch 1 variable but e.watch returns 2 values

logo

  • 记录自己日常工作的实践、心得
  • 发表对生活和职场的感悟
  • 针对感兴趣的事件发表随笔或者杂谈
  • 从0到1详细介绍你掌握的一门语言、一个技术,或者一个兴趣、爱好
  • 或者,就直接把你的个人博客、公众号直接搬到这里

初识 Golang 之函数及方法的多返回值

用户头像

我们试图读取用户的键盘输入,但出现了一个错误。编译器报告了在此代码中的一个问题:

问题是 ReadString 方法试图返回两个值,而我们只提供了一个变量来赋值。

在大多数编程语言中,函数和方法只能由一个返回值。但在 Go 中,它们可以返回任意数量的值。Go 中多个返回值最常见的用法是返回一个额外的错误值,可以通过查询该错误值来确定函数或方法运行时是否发生了错误。举几个例子。

Go 要求声明的每个变量都必须在程序的某个地方使用。如果我们添加了一个 err 变量,而不检查它,我们的代码将无法编译。未使用的变量通常表示一个 bug,所以这是一个 Go 帮助检测和修复 bug 的例子。

Go 不允许我们声明一个变量,除非我们使用它。

现实的理想主义者 2019.10.08 加入

【坐标】:魔都 【品种】:程序媛 【标签】:技术宅、大吃货 【追求】:改变世界、改变自己 【信条】:每次前进一小步

logo

促进软件开发及相关领域知识与创新的传播

  • 2020腾讯云·云开发技术峰会
  • Google Cloud
  • 华为云 DevRun 专区
  • 鲲鹏应用创新大赛2020
  • 腾讯Techo开发者大会
  • DevRun鲲鹏开发者沙龙2020
  • Intel 精彩芯体验
  • InfoQ 关于我们 我要投稿 合作伙伴 加入我们 关注我们
  • 联系我们 内容投稿:[email protected] 业务合作:[email protected] 反馈投诉:[email protected] 加入我们:[email protected] 联系电话:010-64738142 地址:北京市朝阳区叶青大厦北园

会议图片

  • Build integration
  • Partner Program

Zapier Platform CLI docs

Zapier is a platform for creating integrations and workflows. This CLI is your gateway to creating custom applications on the Zapier platform.

You may find some documents on the Zapier site duplicate or outdated. The most up-to-date contents are always available on GitHub:

  • Latest CLI Docs
  • Latest CLI Reference
  • Latest Schema Docs

Our code is updated frequently. To see a full list of changes, look no further than the CHANGELOG .

This doc describes the latest CLI version ( 15.7.1 ), as of this writing. If you’re using an older version of the CLI, you may want to check out these historical releases:

  • CLI Docs: 14.x , 13.x
  • CLI Reference: 14.x , 13.x
  • Schema Docs: 14.x , 13.x

Table of Contents

What is an app, how does zapier platform cli work, zapier platform cli vs ui, requirements, quick setup guide, local project structure, local app definition, registering an app, private app version (default), sharing an app version, promoting an app version, converting an existing app, oauth2 with pkce, connection label, resource definition, returning line items (array of objects), fallback sample, custom/dynamic fields, dynamic dropdowns, search-powered fields, computed fields, nested & children (line item) fields, z.request([url], options), z.dehydrate(func, inputdata), z.dehydratefile(func, inputdata), z.stashfile(bufferstringstream, [knownlength], [filename], [contenttype]), z.generatecallbackurl(), bundle.authdata, bundle.inputdata, bundle.inputdataraw, bundle.meta, bundle.rawrequest, bundle.cleanedrequest, bundle.outputdata, bundle.targeturl, bundle.subscribedata, defining environment variables, accessing environment variables, adding throttle configuration, shorthand http requests, post and put requests, error response handling, http request options, http response object, merging hydrated data, file dehydration, stashing files, console logging, viewing console logs, viewing bundle logs, http logging, viewing http logs, general errors, halting execution, stale authentication credentials, handling throttled requests, writing unit tests, using the z object in tests, mocking requests, running unit tests, testing & environment variables, testing in your ci, debugging tests, using npm modules, building native packages with docker, using transpilers, why doesn’t zapier support newer versions of node.js, how do i manually set the node.js version to run my app with, when to use placeholders or curlies, does zapier support xml (soap) apis, is it possible to iterate over pages in a polling trigger, how do search-powered fields relate to dynamic dropdowns and why are they both required together, what’s the deal with pagination when is it used and how does it work, how does deduplication work, why are my triggers complaining if i don’t provide an explicit id field, node x no longer supported, what analytics are collected, what’s the difference between an “app” and an “integration”, command line tab completion, updating these packages, developing on the cli, getting started.

If you’re new to Zapier Platform CLI, we strongly recommend you to walk through the Tutorial for a more thorough introduction.
Note: this document uses “app” while modern Zapier nomenclature refers instead to “integrations”. In both cases, the phrase refers to your code that connects your API with Zapier.

A CLI App is an implementation of your app’s API. You build a Node.js application that exports a single object ( JSON Schema ) and upload it to Zapier. Zapier introspects that definition to find out what your app is capable of and what options to present end users in the Zap Editor.

For those not familiar with Zapier terminology, here is how concepts in the CLI map to the end user experience:

  • Authentication , (usually) which lets us know what credentials to ask users for. This is used during the “Connect Accounts” section of the Zap Editor.
  • Triggers , which read data from your API. These have their own section in the Zap Editor.
  • Creates , which send data to your API to create new records. These are listed under “Actions” in the Zap Editor.
  • Searches , which find specific records in your system. These are also listed under “Actions” in the Zap Editor.
  • Resources , which define an object type in your API (say a contact) and the operations available to perform on it. These are automatically extracted into Triggers, Searches, and Creates.

Zapier takes the App you upload and sends it over to Amazon Web Service’s Lambda. We then make calls to execute the operations your App defines as we execute Zaps. Your App takes the input data we provide (if any), makes the necessary HTTP calls, and returns the relevant data, which gets fed back into Zapier.

The Zapier Platform includes two ways to build integrations: a CLI (to build integrations in your local development environment and deploy them from the command line), and a Visual Builder (to create integrations with a visual builder from your browser). Both use the same underlying platform, so pick the one that fits your team’s needs best. The main difference is how you make changes to your code.

Zapier Platform CLI is designed to be used by development teams who collaborate with version control and CI, and can be used to build more advanced integrations with custom coding for every part of your API calls and response parsing.

Zapier Platform UI is designed to quickly spin up new integrations, and collaborate on them with teams that include non-developers. It’s the quickest way to start using the Zapier platform—and you can manage your CLI apps’ core details from its online UI as well. You can also export Zapier Platform UI integrations to CLI to start development in your browser, then finish out the core features in your local development environment.

Learn more in our Zapier Platform UI vs CLI post.

All Zapier CLI apps are run using Node.js v18 .

You can develop using any version of Node you’d like, but your eventual code must be compatible with v18 . If you’re using features not yet available in v18 , you can transpile your code to a compatible format with Babel (or similar).

To ensure stability for our users, we strongly encourage you run tests on v18 sometime before your code reaches users. This can be done multiple ways.

Firstly, by using a CI tool (like Travis CI or Circle CI , which are free for open source projects). We provide a sample .travis.yml file in our template apps to get you started.

Alternatively, you can change your local node version with tools such as nvm . Then you can either swap to that version with nvm use v18 , or do nvm exec v18 zapier test so you can run tests without having to switch versions while developing.

First up is installing the CLI and setting up your auth to create a working “Zapier Example” application. It will be private to you and visible in your live Zap Editor .

Note: If you log into Zapier via the single sign-on (Google, Facebook, or Microsoft), you may not have a Zapier password. If that’s the case, you’ll need to generate a deploy key, go to your Zapier developer account here and create/copy a key, then run zapier login command with the –sso flag.

Your Zapier CLI should be installed and ready to go at this point. Next up, we’ll create our first app!

Depending on the authentication method for your app, you’ll also likely need to set your CLIENT_ID and CLIENT_SECRET as environment variables. These are the consumer key and secret in OAuth1 terminology.

You should now have a working local app. You can run several local commands to try it out.

Next, you’ll probably want to upload app to Zapier itself so you can start testing live.

Go check out our full CLI reference documentation to see all the other commands!

For a full tutorial, head over to our Tutorial for a comprehensive walkthrough for creating your first app. If this isn’t your first rodeo, read on!

Creating a Local App

Tip: Check the Quick Setup if this is your first time using the platform!

Creating an App can be done entirely locally and they are fairly simple Node.js apps using the standard Node environment and should be completely testable. However, a local app stays local until you zapier register .

If you’d like to manage your local App , use these commands:

  • zapier init myapp - initialize/start a local app project
  • zapier convert 1234 . - initialize/start from an existing app
  • zapier scaffold resource Contact - auto-injects a new resource, trigger, etc.
  • zapier test - run the same tests as npm test
  • zapier validate - ensure your app is valid
  • zapier describe - print some helpful information about your app

In your app’s folder, you should see this general recommended structure. The index.js is Zapier’s entry point to your app. Zapier expects you to export an App definition there.

The core definition of your App will look something like this, and is what your index.js should provide as the only export:

Tip: You can use higher order functions to create any part of your App definition!

Registering your App with Zapier is a necessary first step which only enables basic administrative functions. It should happen before zapier push which is to used to actually expose an App Version in the Zapier interface and editor.

Note: This doesn’t put your app in the editor - see the docs on pushing an App Version to do that!

If you’d like to manage your App , use these commands:

  • zapier integrations - list the apps in Zapier you can administer
  • zapier register "App Title" - creates a new app in Zapier
  • zapier link - lists and links a selected app in Zapier to your current folder
  • zapier history - print the history of your app
  • zapier team:add [email protected] admin - add an admin to help maintain/develop your app
  • zapier users:add [email protected] 1.0.0 - invite a user try your app version 1.0.0

Deploying an App Version

An App Version is related to a specific App but is an “immutable” implementation of your app. This makes it easy to run multiple versions for multiple users concurrently. The App Version is pulled from the version within the package.json . To create a new App Version, update the version number in that file. By default, every App Version is private but you can zapier promote it to production for use by over 1 million Zapier users.

If you’d like to manage your Version , use these commands:

  • zapier versions - list the versions for the current directory’s app
  • zapier push - push the current version of current directory’s app & version (read from package.json )
  • zapier promote 1.0.0 - mark a version as the “production” version
  • zapier migrate 1.0.0 1.0.1 [100%] - move users between versions, regardless of deployment status
  • zapier deprecate 1.0.0 2020-06-01 - mark a version as deprecated, but let users continue to use it (we’ll email them)
  • zapier env:set 1.0.0 KEY=VALUE - set an environment variable to some value
  • zapier delete:version 1.0.0 - delete a version entirely. This is mostly for clearing out old test apps you used personally. It will fail if there are any users. You probably want deprecate instead.
Note: To see the changes that were just pushed reflected in the browser, you have to manually refresh the browser each time you push.

A simple zapier push will only create the App Version in your editor. No one else using Zapier can see it or use it.

This is how you would share your app with friends, co-workers or clients. This is perfect for quality assurance, testing with active users or just sharing any app you like.

You can also invite anyone on the internet to your app by using the links from zapier users:links . The link should look something like https://zapier.com/platform/public-invite/1/222dcd03aed943a8676dc80e2427a40d/ . You can put this in your help docs, post it to Twitter, add it to your email campaign, etc. You can choose an invite link specific to an app version or for the entire app (i.e. all app versions).

Promotion is how you would share your app with every one of the 1 million+ Zapier users. If this is your first time promoting - you may have to wait for the Zapier team to review and approve your app.

If this isn’t the first time you’ve promoted your app - you might have users on older versions. You can zapier migrate to either move users over (which can be dangerous if you have breaking changes). Or, you can zapier deprecate to give users some time to move over themselves.

If you have an existing Zapier legacy Web Builder app , you can use it as a template to kickstart your local application.

Your CLI app will be created and you can continue working on it.

Note: There is no way to convert a CLI app to a Web Builder app and we do not plan on implementing this.

Introduced in v8.2.0, you are able to convert new integrations built in Zapier Platform UI to CLI.

Authentication

Most applications require some sort of authentication. The Zapier platform provides core behaviors for several common authentication methods that might be used with your application, as well as the ability to customize authentication further.

When a user authenticates to your application through Zapier, a “connection” is created representing their authentication details. Data tied to a specific authentication connection is included in the bundle object under bundle.authData .

Useful if your app requires two pieces of information to authenticate: username and password , which only the end user can provide. By default, Zapier will do the standard Basic authentication base64 header encoding for you (via an automatically registered middleware).

To create a new integration with basic authentication, run zapier init [your app name] --template basic-auth . You can also review an example of that code here .

If your app uses Basic auth with an encoded API key rather than a username and password, like Authorization: Basic APIKEYHERE:x , consider the Custom authentication method instead.

Added in v7.4.0.

The setup and user experience of Digest Auth is identical to Basic Auth. Users provide Zapier their username and password, and Zapier handles all the nonce and quality of protection details automatically.

To create a new integration with digest authentication, run zapier init [your app name] --template digest-auth . You can also review an example of that code here .
Limitation: Currently, MD5-sess and SHA are not implemented. Only the MD5 algorithm is supported. In addition, server nonces are not reused. That means for every z.request call, Zapier will send an additional request beforehand to get the server nonce.

Custom auth is most commonly used for apps that authenticate with API keys, although it also provides flexibility for any unusual authentication setup. You’ll likely provide some custom beforeRequest middleware or a requestTemplate (see Making HTTP Requests ) to pass in data returned from the authentication process, most commonly by adding/computing needed headers.

To create a new integration with custom authentication, run zapier init [your app name] --template custom-auth . You can also review an example of that code here .

Session auth gives you the ability to exchange some user-provided data for some authentication data; for example, username and password for a session key. It can be used to implement almost any authentication method that uses that pattern - for example, alternative OAuth flows.

To create a new integration with session authentication, run zapier init [your app name] --template session-auth . You can also review an example of that code here .

For Session auth, the function that fetches the additional authentication data needed to make API calls ( authentication.sessionConfig.perform ) has the user-provided fields in bundle.inputData . Afterwards, bundle.authData contains the data returned by that function (usually the session key or token).

Added in v7.5.0 .

Zapier’s OAuth1 implementation matches Twitter and Trello implementations of the 3-legged OAuth flow.

To create a new integration with OAuth1, run zapier init [your app name] --template oauth1-trello . You can also check out oauth1-trello , oauth1-tumblr , and oauth1-twitter for working example apps with OAuth1.

The flow works like this:

  • Zapier makes a call to your API requesting a “request token” (also known as “temporary credentials”).
  • Zapier sends the user to the authorization URL, defined by your app, along with the request token.

assignment mismatch 1 variable but e.watch returns 2 values

  • Zapier makes a backend call to your API to exchange the request token for an “access token” (also known as “long-lived credentials”).
  • Zapier stores the access_token and uses it to make calls on behalf of the user.

You are required to define:

  • getRequestToken : The API call to fetch the request token
  • authorizeUrl : The authorization URL
  • getAccessToken : The API call to fetch the access token

You’ll also likely need to set your CLIENT_ID and CLIENT_SECRET as environment variables. These are the consumer key and secret in OAuth1 terminology.

Your auth definition would look something like this:

For OAuth1, authentication.oauth1Config.getRequestToken , authentication.oauth1Config.authorizeUrl , and authentication.oauth1Config.getAccessToken have fields like redirect_uri and the temporary credentials in bundle.inputData . After getAccessToken runs, the resulting token value(s) will be stored in bundle.authData for the connection.

Also, authentication.oauth1Config.getAccessToken has access to the additional return values in rawRequest and cleanedRequest should you need to extract other values (for example, from the query string).

Zapier’s OAuth2 implementation is based on the authorization_code flow, similar to GitHub and Facebook .

To create a new integration with OAuth2, run zapier init [your app name] --template oauth2 . You can also check out our working example app .

If your app’s OAuth2 flow uses a different grant type, such as client_credentials , try using Session auth instead.

The OAuth2 flow looks like this:

  • Zapier sends the user to the authorization URL defined by your app.

assignment mismatch 1 variable but e.watch returns 2 values

  • Zapier makes a backend call to your API to exchange the code for an access_token .
  • (Optionally) Zapier can refresh the token if it expires.

If the access token has a limited life and you want to refresh the token when it expires, you’ll also need to define the API call to perform that refresh ( refreshAccessToken ). You can choose to set autoRefresh: true , as in the example app, if you want Zapier to automatically make a call to refresh the token after receiving a 401. See Stale Authentication Credentials for more details on handling auth refresh.

You’ll also likely want to set your CLIENT_ID and CLIENT_SECRET as environment variables:

For OAuth2, authentication.oauth2Config.authorizeUrl , authentication.oauth2Config.getAccessToken , and authentication.oauth2Config.refreshAccessToken have fields like redirect_uri and state in bundle.inputData . After the code is exchanged for an access token and/or refresh token, those tokens are stored in bundle.authData for the connection.

Also, authentication.oauth2Config.getAccessToken has access to the additional return values in rawRequest and cleanedRequest should you need to extract other values (for example, from the query string).

If you define fields to collect additional details from the user, please note that client_id and client_secret are reserved keys and cannot be used as keys for input form fields.

Note: The OAuth2 state param is a  standard security feature  that helps ensure that authorization requests are only coming from your servers. Most OAuth clients have support for this and will send back the state query param that the user brings to your app. The Zapier Platform performs this check and this required field cannot be disabled. The state parameter is automatically generated by Zapier in the background, and can be accessed at bundle.inputData.state . Since Zapier uses the  state  to verify that GET requests to your redirect URL truly come from your app, it needs to be generated by Zapier so that it can be validated later (once the user confirms that they’d like to grant Zapier permission to access their account in your app).

Added in v14.0.0.

Zapier’s OAuth2 implementation also supports PKCE . This implementation is an extension of the OAuth2 authorization_code flow described above.

To use PKCE in your OAuth2 flow, you’ll need to set the following variables:

  • enablePkce: true
  • getAccessToken.body to include code_verifier: "{{bundle.inputData.code_verifier}}"

The OAuth2 PKCE flow uses the same flow as OAuth2 but adds a few extra parameters:

  • Zapier computes a code_verifier and code_challenge internally and stores the code_verifier in the Zapier bundle.
  • Zapier sends the user to the authorization URL defined by your app. We automatically include the computed code_challenge and code_challenge_method in the authorization request.
  • Once authorized, your website sends the user to the redirect_uri Zapier provided.
  • Zapier makes a call to your API to exchange the code but you must include the computed code_verifier in the request for an access_token .

The computed code_verifier uses this standard: RFC 7636 Code Verifier

The computed code_challenge uses this standard: RFC 7636 Code Challenge

When a user connects to your app via Zapier and a connection is created to hold the related data in bundle.authData , the connection is automatically labeled with the app name. You also have the option of setting a connection label ( connectionLabel ), which can be extremely helpful to identify information like which user is connected or what instance of your app they are connected to. That way, users don’t get confused if they have multiple connections to your app.

When setting a connection label, you can use either a string with variable references (as shown in Basic Auth ) or a function (as shown in Digest Auth ).

When using a string, you have access to the information in bundle.authData and the information returned from the test request in bundle.inputData , all at the top level. So in Basic auth, if connectionLabel is {{username}} , that refers to the username used for authentication.

When using a function, this “hoisting” of data to the top level is skipped, and you must refer to data items by their fully qualified name, as shown in the line return bundle.inputData.username; in the Digest Auth snippet. return username; would not work in this context.

NOTE: Do not use sensitive authentication data such as passwords or API keys in the connection label. It’s visible in plain text on Zapier. The purpose of the label is to identify the connection for the user, so stick with data such as username or instance identifier that is meaningful but not sensitive.

A resource is a representation (as a JavaScript object) of one of the REST resources of your API. Say you have a /recipes endpoint for working with recipes; you can define a recipe resource in your app that will tell Zapier how to do create, read, and search operations on that resource.

The quickest way to create a resource is with the zapier scaffold command:

This will generate the resource file and add the necessary statements to the index.js file to import it.

A resource has a few basic properties. The first is the key , which allows Zapier to identify the resource on our backend. The second is the noun , the user-friendly name of the resource that is presented to users throughout the Zapier UI.

Check out this working example app to see resources in action.

After those, there is a set of optional properties that tell Zapier what methods can be performed on the resource. The complete list of available methods can be found in the Resource Schema Docs . For now, let’s focus on two:

  • list - Tells Zapier how to fetch a set of this resource. This becomes a Trigger in the Zapier Editor.
  • create - Tells Zapier how to create a new instance of the resource. This becomes an Action in the Zapier Editor.

Here is a complete example of what the list method might look like

The method is made up of two properties, a display and an operation . The display property ( schema ) holds the info needed to present the method as an available Trigger in the Zapier Editor. The operation ( schema ) provides the implementation to make the API call.

Adding a create method looks very similar.

Every method you define on a resource Zapier converts to the appropriate Trigger, Create, or Search. Our examples above would result in an app with a New Recipe Trigger and an Add Recipe Create.

Note the keys for the Trigger, Create, Search, and Search or Create are automatically generated (in case you want to use them in a dynamic dropdown), like: {resourceName}List , {resourceName}Create , {resourceName}Search , and {resourceName}SearchOrCreate ; in the examples above, {resourceName} would be recipe .

Triggers/Searches/Creates

Triggers, Searches, and Creates are the way an app defines what it is able to do. Triggers read data into Zapier (i.e. watch for new recipes). Searches locate individual records (find recipe by title). Creates create new records in your system (add a recipe to the catalog).

The definition for each of these follows the same structure. Here is an example of a trigger:

You can find more details on the definition for each by looking at the Trigger Schema , Search Schema , and Create Schema .

To create a new integration with a premade trigger, search, or create, run zapier init [your app name] and select from the list that appears. You can also check out our working example apps here .
To add a trigger, search, or create to an existing integration, run zapier scaffold [trigger|search|create] [noun] to create the necessary files to your project. For example, zapier scaffold trigger post will create a new trigger called “New Post”. Return Types

Each of the 3 types of function should return a certain data type for use by the platform. There are automated checks to let you know when you’re trying to pass the wrong type back. For reference, each expects:

When a trigger function returns an empty array, the Zap will not trigger. For REST Hook triggers, this can be used to filter data if the available subscription options are not specific enough for the Zap’s needs.

In some cases, you may want to include multiple items in the data you return for Searches or Creates. To do that, return the set of items as an array of objects under a descriptive key. This may be as part of another object (like items in an invoice) or as multiple top-level items.

For example, a Create Order action returning an order with multiple items might look like this:

While a Find Users search could return multiple items under an object key within an array, like this:

A standard search would return just the inner array of users, and only the first user would be provided as a final result. Returning line items instead means that the “first result” return is the object containing all the user details within it.

Using the standard approach is recommended, because not all Zapier integrations support line items directly, so users may need to take additional actions to reformat this data for use in their Zaps. More detail on that at Use line items in Zaps . However, there are use cases where returning multiple results is helpful enough to outweigh that additional effort.

In cases where Zapier needs to show an example record to the user, but we are unable to get a live example from the API, Zapier will fallback to this hard-coded sample. This should reflect the data structure of the Trigger’s perform method, and have dummy values that we can show to any user.

Input Fields

On each trigger, search, or create in the operation directive, you can provide fields as an array of objects under inputFields . Input Fields are what your users see in Zapier when setting up your app’s triggers and actions. For example, you might have a “Create Contact” action with fields like “First name”, “Last name”, “Email”, etc. These fields will be able to accept input from the user, or from previous steps in a Zap. For example:

You can find more details about setting action fields from a user perspective in our help documentation .

Those fields have various options you can provide. Here is a brief example:

Notably, fields come in different types, which may look and act differently in the Zap editor. The default field display is a single-line input field.

You can find more details on the different field schema options at our Field Schema .

In some cases, you may need to provide dynamically-generated fields - especially for custom ones. This is common functionality for CRMs, form software, databases, and other highly-customizable platforms. Instead of an explicit field definition, you can provide a function we’ll evaluate to return a list of fields - merging the dynamic with the static fields.

You should see bundle.inputData partially filled in as users provide data - even in field retrieval. This allows you to build hierarchical relationships into fields (e.g. only show issues from the previously selected project).
A function that returns a list of dynamic fields cannot include additional functions in that list to call for dynamic fields.

Additionally, if there is a field that affects the generation of dynamic fields, you can set the property altersDynamicFields: true . This informs the Zapier UI whenever the value of that field changes, the input fields need to be recomputed. For example, imagine the selection on a static dropdown called “Dessert Type” determining whether the function generating dynamic fields includes the field “With Sprinkles?” or not. If the value in one input field affects others, this is an important property to set.

Only dropdowns support altersDynamicFields .

When using dynamic fields, the fields will be retrieved in three different contexts:

  • Whenever the value of a field with altersDynamicFields is changed, as described above.
  • Whenever the Zap Editor opens the “Set up” section for the trigger or action.
  • Whenever the “Refresh fields” button at the bottom of the Editor’s “Set up” section is clicked.

Be sure to set up your code accordingly - for example, don’t rely on any input fields already having a value, since they won’t have one the first time the “Set up” section loads.

Sometimes, API endpoints require clients to specify a parent object in order to create or access the child resources. For instance, specifying a spreadsheet id in order to retrieve its worksheets. Since people don’t speak in auto-incremented ID’s, it is necessary that Zapier offer a simple way to select that parent using human readable handles.

Our solution is to present users a dropdown that is populated by making a live API call to fetch a list of parent objects. We call these special dropdowns “dynamic dropdowns.”

To define one you include the dynamic property on the inputFields object. The value for the property is a dot-separated string concatenation.

The dot-separated string concatenation follows this pattern:

  • The key of the trigger you want to use to power the dropdown. required
  • The value to be made available in bundle.inputData. required
  • The human friendly value to be shown on the left of the dropdown in bold. optional

In the above code example the dynamic property makes reference to a trigger with a key of project. Assuming the project trigger returns an array of objects and each object contains an id and name key, i.e.

screenshot of dynamic dropdown in Zap Editor

In the first code example the dynamic dropdown is powered by a trigger. You can also use a resource to power a dynamic dropdown. To do this combine the resource key and the resource method using camel case.

In some cases you will need to power a dynamic dropdown but do not want to make the Trigger available to the end user. Here it is best practice to create the trigger and set hidden: true on it’s display object.

You can have multiple dynamic dropdowns in a single Trigger or Action. And a dynamic dropdown can depend on the value chosen in another dynamic dropdown when making it’s API call. Such as a Spreadsheet and Worksheet dynamic dropdown in a trigger or action. This means you must make sure that the key of the first dynamic dropdown is the same as referenced in the trigger powering the second.

Let’s say you have a Worksheet trigger with a perform method similar to this.

And your New Records trigger has a Spreadsheet and a Worksheet dynamic dropdown. The Spreadsheet dynamic dropdown must have a key of spreadsheet_id . When the user selects a spreadsheet via the dynamic dropdown the value chosen is made available in bundle.inputData . It will then be passed to the Worksheet trigger when the user clicks on the Worksheet dynamic dropdown.

The Google Sheets integration is an example of this pattern.

If you want your trigger to perform specific scripting for a dynamic dropdown you will need to make use of bundle.meta.isFillingDynamicDropdown . This can be useful if need to make use of pagination in the dynamic dropdown to load more options.

For fields that take id of another object to create a relationship between the two (EG: a project id for a ticket), you can specify the search property on the field to indicate that Zapier needs to prompt the user to setup a Search step to populate the value for this field. Similar to dynamic dropdowns, the value for this property is a dot-separated concatenation of a search’s key and the field to use for the value.

NOTE: This has to be combined with the dynamic property to give the user a guided experience when setting up a Zap.

If you don’t define a trigger for the dynamic property, the search connector won’t show.

In OAuth and Session Auth, Zapier automatically stores every value from an integration’s auth API response i.e. that’s getAccessToken and refreshAccessToken for OAuth and getSessionKey for session auth.

You can return additional fields in these responses, on top of the expected access_token or refresh_token for OAuth and sessionKey for Session auth. They will be saved in bundle.authData . You can reference these fields in any subsequent API call as needed.

Note: Only OAuth and Session Auth support computed fields.

If you want Zapier to validate that these additional fields exist, you need to use Computed Fields. If you define computed fields in your integration, Zapier will check to make sure those fields exist when it runs the authentication test API call.

Computed fields work like any other field, though with computed: true property, and required: false as user can not enter computed fields themselves. Reference computed fields in API calls as {{bundle.authData.field}} , replacing field with that field’s name from your test API call response.

You can see examples of computed fields in the OAuth2 or Session Auth example sections.

When your action needs to accept an array of items, you can include an input field with the children attribute. The children attribute accepts a list of fields that can be input for each item in this array.

Output Fields

On each trigger, search, or create in the operation directive - you can provide an array of objects as fields under the outputFields . Output Fields are what users see when they select a field provided by your trigger, search or create to map it to another.

Output Fields are optional, but can be used to:

  • Define friendly labels for the returned fields. By default, we will humanize for example my_key as My Key .
  • Make sure that custom fields that may not be found in every live sample and - since they’re custom to the connected account - cannot be defined in the static sample, can still be mapped.
  • (Added in v15.6.0) Define what field(s) can be used to uniquely identify and deduplicate items returned by a polling trigger call.

The schema for outputFields is shared with inputFields but only these properties are relevant:

  • key - includes the field when not present in the live sample. When no label property is provided, key will be humanized and displayed as the field name.
  • label - defines the field name displayed to users.
  • type - defines the type for static sample data. A validation warning will be displayed if the static sample does not match the specified type.
  • required - defines whether the field is required in static sample data. A validation warning will be displayed if the value is true and the static sample does not contain the field.
  • primary - defines whether the field is part of the primary key for polling trigger deduplication .

Custom/Dynamic Output Fields are defined in the same way as Custom/Dynamic Input Fields .

To define an Output Field for a nested field use {{parent}}__{{key}} . For children (line item) fields use {{parent}}[]{{key}} .

We provide several methods off of the z object, which is provided as the first argument to all function calls in your app.

The z object is passed into your functions as the first argument - IE: perform: (z) => {} .

z.request([url], options) is a promise based HTTP client with some Zapier-specific goodies. See Making HTTP Requests . z.request() will percent-encode non-ascii characters and these reserved characters: :$/?#[]@$&+,;=^@`\ . Use skipEncodingChars to modify this behaviour.

z.console.log(message) is a logging console, similar to Node.js console but logs remotely, as well as to stdout in tests. See Log Statements

z.dehydrate(func, inputData) is used to lazily evaluate a function, perfect to avoid API calls during polling or for reuse. See Dehydration .

z.dehydrateFile is used to lazily download a file, perfect to avoid API calls during polling or for reuse. See File Dehydration .

z.stashFile(bufferStringStream, [knownLength], [filename], [contentType]) is a promise based file stasher that returns a URL file pointer. See Stashing Files .

z.JSON is similar to the JSON built-in like z.JSON.parse('...') , but catches errors and produces nicer tracebacks.

z.hash() is a crypto tool for doing things like z.hash('sha256', 'my password')

z.errors is a collection error classes that you can throw in your code, like throw new z.errors.HaltedError('...') .

The available errors are:

  • Error ( added in v9.3.0 ) - Stops the current operation, allowing for (auto) replay. Read more on General Errors
  • HaltedError - Stops current operation, but will never turn off Zap. Read more on Halting Execution
  • ExpiredAuthError - Stops the current operation and emails user to manually reconnect. Read more on Stale Authentication Credentials
  • RefreshAuthError - (OAuth2 or Session Auth) Tells Zapier to refresh credentials and retry operation. Read more on Stale Authentication Credentials
  • ThrottledError ( new in v11.2.0 ) - Tells Zapier to retry the current operation after a delay specified in seconds. Read more on Handling Throttled Requests

For more details on error handling in general, see here .

The z.cursor object exposes two methods:

  • z.cursor.get(): Promise<string|null>
  • z.cursor.set(string): Promise<null>

Any data you set will be available to that Zap for about an hour (or until it’s overwritten). For more information, see: paging .

The z.generateCallbackUrl() will return a callback URL your app can POST to later for handling long running tasks (like transcription or encoding jobs). In the meantime, the Zap and Task will wait for your response and the user will see the Task marked as waiting.

For example, in your perform you might do:

And in your own /api/slow-job view (or more likely, an async job) you’d make this request to Zapier when the long-running job completes to populate bundle.cleanedRequest :

We recommend using bundle.meta.isLoadingSample to determine if the execution is happening in the foreground (IE: during Zap setup) as using z.generateCallbackUrl() can be inappropriate given the disconnect. Instead, wait for the long running request without generating a callback, or if you must, return stubbed data.

And finally, in a performResume to handle the final step which will receive three bundle properties:

  • bundle.outputData is {"hello": "world"} , the data returned from the initial perform
  • bundle.cleanedRequest is {"foo": "bar"} , the payload from the callback URL
  • bundle.rawRequest is the full request object corresponding to bundle.cleanedRequest
The app will have a maximum of 30 days to POST to the callback URL. If a user deletes or modifies the Zap or Task in the meantime, we will not resume the task.
performResume will only run when the Zap runs live, and cannot be tested in the Zap Editor when configuring the Zap. It is possible to use bundle.meta.isLoadingSample to load a fixed sample to allow users to test a step that includes performResume .

Bundle Object

This object holds the user’s auth details and the data for the API requests.

The bundle object is passed into your functions as the second argument - IE: perform: (z, bundle) => {} .

bundle.authData is user-provided authentication data, like api_key or access_token . Read more on authentication.

bundle.inputData is user-provided data for this particular run of the trigger/search/create, as defined by the inputFields . For example:

bundle.inputDataRaw is like bundle.inputData , but before processing such as interpreting friendly datetimes and rendering {{curlies}} :

“curlies” represent data mapped in from previous steps. They take the form {{NODE_ID__key_name}} .

You’ll usually want to use bundle.inputData instead.

bundle.meta contains extra information useful for doing advanced behaviors depending on what the user is doing. It has the following options:

Before v8.0.0, the information in bundle.meta was different. See the old docs for the previous values and the wiki for a mapping of old values to new.

Here’s an example of a polling trigger that is also used to power a dynamic dropdown:

bundle.rawRequest is only available in the perform for webhooks, getAccessToken for OAuth authentication methods, and performResume in a callback action.

bundle.rawRequest holds raw information about the HTTP request that triggered the perform method or that represents the user’s browser request that triggered the getAccessToken call:

In bundle.rawRequest , headers other than Content-Length and Content-Type will be prefixed with Http- , and all headers will be named in Camel-Case. For example, the header X-Time-GMT would become Http-X-Time-Gmt .

bundle.cleanedRequest is only available in the perform for webhooks, getAccessToken for OAuth authentication methods, and performResume in a callback action.

bundle.cleanedRequest will return a formatted and parsed version of the request. Some or all of the following will be available:

bundle.outputData is only available in the performResume in a callback action.

bundle.outputData will return a whatever data you originally returned in the perform , allowing you to mix that with bundle.rawRequest or bundle.cleanedRequest .

bundle.targetUrl is only available in the performSubscribe and performUnsubscribe methods for webhooks.

This the URL to which you should send hook data. It’ll look something like https://hooks.zapier.com/1234/abcd . We provide it so you can make a POST request to your server. Your server should store this URL and use is as a destination when there’s new data to report.

For example:

Read more in the REST hook example .

bundle.subscribeData is available in the perform and performUnsubscribe method for webhooks.

This is an object that contains the data you returned from the performSubscribe function. It should contain whatever information you need send a DELETE request to your server to stop sending webhooks to Zapier.

Environment

Apps can define environment variables that are available when the app’s code executes. They work just like environment variables defined on the command line. They are useful when you have data like an OAuth client ID and secret that you don’t want to commit to source control. Environment variables can also be used as a quick way to toggle between a staging and production environment during app development.

It is important to note that variables are defined on a per-version basis! When you push a new version, the existing variables from the previous version are copied, so you don’t have to manually add them. However, edits made to one version’s environment will not affect the other versions.

To define an environment variable, use the env command:

You will likely also want to set the value locally for testing.

Alternatively, we provide some extra tooling to work with an .env (or .environment , see below note) that looks like this:

.env is the new recommended name for the environment file since v5.1.0. The old name .environment is deprecated but will continue to work for backward compatibility.

And then in your test/basic.js file:

This is a popular way to provide process.env.ACCESS_TOKEN || bundle.authData.access_token for convenient testing.
NOTE Variables defined via zapier env:set will always be uppercased. For example, you would access the variable defined by zapier env:set 1.0.0 foo_bar=1234 with process.env.FOO_BAR .

To view existing environment variables, use the env command.

Within your app, you can access the environment via the standard process.env - any values set via local export or zapier env:set will be there.

For example, you can access the process.env in your perform functions and in templates:

Note! Be sure to lazily access your environment variables - see When to use placeholders or curlies? .

Added in v15.4.0.

When a throttle configuration is set for an action, Zapier uses it to apply throttling when the limit for the timeframe window is exceeded. It can be set at the root level and/or on an action. When set at the root level, it is the default throttle configuration used on each action of the integration. And when set in an action’s operation object, the root-level default is overwritten for that action only. Note that the throttle limit is not shared across actions unless for those with the same key, window, limit, and scope when “action” is not in the scope.

To throttle an action, you need to set a throttle object with the following variables:

  • window [integer] : The timeframe, in seconds, within which the system tracks the number of invocations for an action. The number of invocations begins at zero at the start of each window.
  • limit [integer] : The maximum number of invocations for an action, allowed within the timeframe window.
  • key [string] ( added in v15.6.0 ): The key to throttle with in combination with the scope. User data provided for the input fields can be used in the key with the use of the curly braces referencing. For example, to access the user data provided for the input field “test_field”, use {{bundle.inputData.test_field}} . Note that a required input field should be referenced to get user data always.
  • ‘user’ - Throttles based on user ids.
  • ‘auth’ - Throttles based on auth ids.
  • ‘account’ - Throttles based on account ids for all users under a single account.
  • ‘action’ - Throttles the action it is set on separately from other actions.
  • window [integer] : Same description as above.
  • limit [integer] : Same description as above.
  • filter [string] : Account-based attribute to override the throttle by. You can set to one of the following: “free”, “trial”, “paid”. Therefore, the throttle scope would be automatically set to “account” and ONLY the accounts based on the specified filter will have their requests throttled based on the throttle overrides while the rest are throttled based on the original configuration.
  • retry [boolean] ( added in v15.6.1 ): The effect of throttling on the tasks of the action. true means throttled tasks are automatically retried after some delay, while false means tasks are held without retry. It defaults to true .

Both window and limit are required and others are optional. By default, throttling is scoped to the action and account.

Here is a typical usage of the throttle configuration:

Making HTTP Requests

There are two ways to make HTTP requests:

  • Shorthand HTTP Requests - Easy to use, but limits what you can control. Best for simple requests.
  • Manual HTTP Requests - Gives you full control over the request and response.

Use these helper constructs to reduce boilerplate:

  • requestTemplate - an object literal of HTTP request options that will be merged with every request.
  • beforeRequest - middleware that mutates every request before it is sent.
  • afterResponse - middleware that mutates every response before it is completed.
Note: you can install any HTTP client you like - but this is greatly discouraged as you lose automatic HTTP logging and middleware.

For simple HTTP requests that do not require special pre- or post-processing, you can specify the HTTP request options as an object literal in your app definition.

This features:

  • Lazy {{curly}} replacement.
  • JSON and form body de-serialization.
  • Automatic non-2xx error raising.

In the URL above, {{bundle.authData.subdomain}} is automatically replaced with the live value from the bundle. If the call returns a non 2xx return code, an error is automatically raised. The response body is automatically parsed as JSON or form-encoded and returned.

An error will be raised if the response cannot be parsed as JSON or form-encoded. To use shorthand requests with other response types, add middleware that sets response.data to the parsed response.

Manual HTTP Requests

Use this when you need full control over the request/response. For example:

  • To do processing (usually involving bundle.inputData ) before a request is made
  • To do processing of an API’s response before you return data to Zapier
  • To process an unusual response type, such as XML

To make a manual request, pass your request options to z.request() then use the resulting response object to return the data you want:

Manual requests perform lazy {{curly}} replacement. In the URL above, {{bundle.authData.subdomain}} is automatically replaced with the live value from the bundle.

To POST or PUT data to your API you can do this:

Note: you need to call z.JSON.stringify() before setting the body .

Using HTTP middleware

To process all HTTP requests in a certain way, use the beforeRequest and afterResponse middleware functions.

Middleware functions go in your app definition:

A beforeRequest middleware function takes a request options object, and returns a (possibly mutated) request object. An afterResponse middleware function takes a response object, and returns a (possibly mutated) response object. Middleware functions are executed in the order specified in the app definition, and each subsequent middleware receives the request or response object returned by the previous middleware.

Middleware functions can be asynchronous - just return a promise from the middleware function.

The second argument for middleware is the z object, but it does not include z.request() as using that would easily create infinite loops.

Here is the full request lifecycle when you call z.request({...}) :

  • set defaults on the request object
  • run your beforeRequest middleware functions in order
  • add applicable auth headers (e.g. adding Basic ... for basic auth), if applicable
  • add request.params to request.url
  • execute the request , store the result in response
  • try to auto-parse response body for non-raw requests, store result in response.data
  • log the request to Zapier’s logging server
  • if the status code is 401 , you’re using a refresh-able auth (such as oauth2 or session ) and autoRefresh is true in your auth configuration, throw a RefreshAuthError . The server will attempt to refresh the authentication again and retry the whole step
  • run your afterResponse middleware functions in order
  • call response.throwForStatus() unless response.skipThrowForStatus is true

The resulting response object is returned from z.request() .

Example App: check out https://github.com/zapier/zapier-platform/tree/main/example-apps/middleware for a working example app using HTTP middleware.

Since v10.0.0 , z.request() calls response.throwForStatus() before it returns a response. You can disable automatic error throwing by setting skipThrowForStatus on the request object:

You can also do it in afterResponse if the API uses a status code >= 400 that should not be treated as an error.

For developers using v9.x and below, it’s your responsibility to throw an exception for an error response. That means you should call response.throwForStatus() or throw an error yourself, likely following the z.request call.

This behavior has changed periodically across major versions, which changes how/when you have to worry about handling errors. Here’s a diagram to illustrate that:

assignment mismatch 1 variable but e.watch returns 2 values

Ensure you’re handling errors correctly for your platform version. The latest released version is 15.7.1 .

Shorthand requests and manual requests support the following HTTP options :

  • url : HTTP url, you can provide it as a separate argument ( z.request(url, options) ) or as part of the options object ( z.request({url: url, ...}) ).
  • method : HTTP method, default is GET .
  • headers : request headers object, format {'header-key': 'header-value'} .
  • params : URL query params object, format {'query-key': 'query-value'} .
  • body : request body, can be a string, buffer, readable stream or plain object. When it is an object/array and the Content-Type header is application/x-www-form-urlencoded the body will be transformed to query string parameters, otherwise we’ll set the header to application/json; charset=utf-8 and JSON encode the body. Default is null .
  • allowGetBody : include body in GET requests. Set to true to enable. Default is false . Set only if required by the receiving API. See section 4.3.1 in RFC 7231 .
  • json : shortcut object/array/etc. you want to JSON encode into body. Default is null .
  • form : shortcut object. you want to form encode into body. Default is null .
  • raw : set this to stream the response instead of consuming it immediately. Default is false .
  • redirect : set to manual to extract redirect headers, error to reject redirect, default is follow .
  • follow : maximum redirect count, set to 0 to not follow redirects. default is 20 .
  • compress : support gzip/deflate content encoding. Set to false to disable. Default is true .
  • agent : Node.js http.Agent instance, allows custom proxy, certificate etc. Default is null .
  • timeout : request / response timeout in ms. Set to 0 to disable (OS limit still applies), timeout reset on redirect . Default is 0 (disabled).
  • size : maximum response body size in bytes. Set to 0 to disable. Default is 0 (disabled).
  • skipThrowForStatus ( added in v10.0.0 ): don’t call response.throwForStatus() before resolving the request with response . See HTTP Response Object .

The response object returned by z.request([url], options) supports the following fields and methods:

  • status : The response status code, i.e. 200 , 404 , etc.
  • content : The response content as a String. For Buffer, try options.raw = true .
  • data ( added in v10.0.0 ): The response content as an object if the content is JSON or application/x-www-form-urlencoded ( undefined otherwise).
  • headers : Response headers object. The header keys are all lower case.
  • getHeader(key) : Retrieve response header, case insensitive: response.getHeader('My-Header')
  • skipThrowForStatus ( added in v10.0.0 ): don’t call throwForStatus() before resolving the request with this response.
  • throwForStatus() : Throws an error if 400 <= statusCode < 600 .
  • request : The original request options object (see above).

Additionally, if request.raw is true , the raw response has the following properties:

  • json() : Get the response content as an object, if options.raw = true and content is JSON (returns a promise). undefined in non-raw requests.
  • body : A stream available only if you provide options.raw = true .

Dehydration

Dehydration, and its counterpart Hydration, is a tool that can lazily load data that might be otherwise expensive to retrieve aggressively.

  • Dehydration - think of this as “make a pointer”, you control the creation of pointers with z.dehydrate(func, inputData) (or z.dehydrateFile(func, inputData) for files). This usually happens in a trigger step.
  • Hydration - think of this as an automatic step that “consumes a pointer” and “returns some data”, Zapier does this automatically behind the scenes. This usually happens in an action step.
This is very common when Stashing Files - but that isn’t their only use!

The method z.dehydrate(func, inputData) has two required arguments:

  • func - the function to call to fetch the extra data. Can be any raw function , defined in the file doing the dehydration or imported from another part of your app. You must also register the function in the app’s hydrators property. Note that since v10.1.0, the maximum payload size to pass to z.dehydrate / z.dehydrateFile is 6KB.
  • inputData - this is an object that contains things like a path or id - whatever you need to load data on the other side
  • A known limitation of hydration is a 5 minute cache if the hydration call is made with identical inputData within that timeframe. To workaround this cache for records triggering hydration in close succession, include a unique value in the inputData , for example a timestamp in addition to the record id .
Why do I need to register my functions? Because of how JavaScript works with its module system, we need an explicit handle on the function that can be accessed from the App definition without trying to “automagically” (and sometimes incorrectly) infer code locations.

Here is an example that pulls in extra data for a movie:

And in future steps of the Zap - if Zapier encounters a pointer as returned by z.dehydrate(func, inputData) - Zapier will tie it back to your app and pull in the data lazily.

Why can’t I just load the data immediately? Isn’t it easier? In some cases it can be - but imagine an API that returns 100 records when polling - doing 100x GET /id.json aggressive inline HTTP calls when 99% of the time Zapier doesn’t need the data yet is wasteful.

As you’ve seen, the usual call to dehydrate will assign the result to an object property:

In this example, all of the movie details will be located in the details property (e.g. details.releaseDate ) after hydration occurs. But what if you want these results available at the top-level (e.g. releaseDate )? Zapier supports a specific keyword for this scenario:

Using $HOIST$ as the key will signal to Zapier that the results should be merged into the object containing the $HOIST$ key. You can also use this to merge your hydrated data into a property containing “partial” data that exists before dehydration occurs:

Added in v7.3.0.

The method z.dehydrateFile(func, inputData) allows you to download a file lazily. It takes the same arguments as z.dehydrate(func, inputData) does, but is recommended when the data is a file.

An example can be found in the Stashing Files section.

What makes z.dehydrateFile different from z.dehydrate has to do with efficiency and when Zapier chooses to hydrate data. Knowing which pointers give us back files helps us delay downloading files until it’s absolutely necessary. Not only will it help avoid unnecessary file downloads, it can also prevent errors if the file has a limited availability. (Stashing files, described below, can also help with that situation.)

A good example is when users are creating Zaps in the Zap Editor. If a pointer is made by z.dehydrate , the Zap Editor will hydrate the data immediately after pulling in samples. This allows users to map fields from the hydrated data into the subsequent steps of the Zap. If, however, the pointer is made by z.dehydrateFile , the Zap Editor will wait to hydrate the file, and will display a placeholder instead. There’s nothing inside binary file data for users to map in the subsequent steps.

z.dehydrateFile(func, inputData) was added in v7.3.0. We used to recommend using z.dehydrate(func, inputData) for files, but we now recommend changing it to z.dehydrateFile(func, inputData) for a better user experience.

It can be expensive to download and stream files or they can require complex handshakes to authorize downloads - so we provide a helpful stash routine that will take any String , Buffer or Stream and return a URL file pointer suitable for returning from triggers, searches, creates, etc.

The interface z.stashFile(bufferStringStream, [knownLength], [filename], [contentType]) takes a single required argument - the extra three arguments will be automatically populated in most cases. Here’s a full example:

Most likely you’d want to stream from another URL - note the usage of z.request({raw: true}) :

Note: you should only be using z.stashFile() in a hydration method or a hook trigger’s perform if you’re sending over a short-lived URL to a file. Otherwise, it can be very expensive to stash dozens of files in a polling call - for example!

See a full example with dehydration/hydration wired in correctly:

To create a new integration for handling files, run zapier init [your app name] --template files . You can also check out our working example app here .

To view the logs for your application, use the zapier logs command.

There are three types of logs for a Zapier app:

  • http : logged automatically by Zapier on HTTP requests
  • bundle : logged automatically on every method execution
  • console : manual logs via z.console.log() statements ( see below for details )

Note that by default, this command will only fetch logs associated to your user.

For advanced logging options, including the option to fetch logs for other users or specific app versions, look at the help for the logs command:

To manually print a log statement in your code, use z.console.log :

The z.console object has all the same methods and works just like the Node.js Console class - the only difference is we’ll log to our distributed datastore and you can view the logs via zapier logs (more below).

To see your z.console.log logs, do:

To see the bundle logs, do:

If you are using shorthand HTTP requests or the z.request() method that we provide, HTTP logging is handled automatically for you. For example:

HTTP logging will often work with other methods of making requests as well, but if you’re using another method and having trouble seeing logs, try using z.request() .

To see the HTTP logs, do:

To see detailed HTTP logs, including data such as headers and request and response bodies, do:

Error Handling

APIs are not always available. Users do not always input data correctly to formulate valid requests. Thus, it is a good idea to write apps defensively and plan for 4xx and 5xx responses from APIs. Without proper handling, errors often have incomprehensible messages for end users, or possibly go uncaught.

Zapier provides a couple of tools to help with error handling. First is the afterResponse middleware ( docs ), which provides a hook for processing all responses from HTTP calls. Second is response.throwForStatus() ( docs ), which throws an error if the response status indicates an error (status >= 400). Since v10.0.0, we automatically call this method before returning the response, unless you set skipThrowForStatus on the request or response object. The last tool is the collection of errors in z.errors ( docs ), which control the behavior of Zaps when various kinds of errors occur.

Errors due to a misconfiguration in a user’s Zap should be handled in your app by throwing z.errors.Error with a user-friendly message and optional error and status code. Typically, this will be prettifying 4xx responses or APIs that return errors as 200s with a payload that describes the error.

Example: throw new z.errors.Error('Contact name is too long.', 'InvalidData', 400);

z.errors.Error was added in v9.3.0. If you’re on an older version of zapier-platform-core , throw a standard JavaScript Error instead, such as throw new Error('A user-friendly message') .

A couple best practices to keep in mind:

  • Elaborate on terse messages. “not_authenticated” -> “Your API Key is invalid. Please reconnect your account.”
  • If the error calls out a specific field, surface that information to the user. “Provided data is invalid” -> “Contact name is invalid”
  • If the error provides details about why a field is invalid, add that in too! “Contact name is invalid” -> “Contact name is too long”
  • The second, optional argument should be a code that a computer could use to identify the type of error.
  • The last, optional argument should be the HTTP status code, if any.

The code and status can be used by us to provide relevant troubleshooting to the user when we communicate the error.

Note that if a Zap raises too many error messages it will be automatically turned off, so only use these if the scenario is truly an error that needs to be fixed.

Any operation can be interrupted or “halted” (not success, not error, but stopped for some specific reason) with a HaltedError . You might find yourself using this error in cases where a required pre-condition is not met. For instance, in a create to add an email address to a list where duplicates are not allowed, you would want to throw a HaltedError if the Zap attempted to add a duplicate. This would indicate failure, but it would be treated as a soft failure.

Unlike throwing z.errors.Error , a Zap will never by turned off when this error is thrown (even if it is raised more often than not).

Example: throw new z.errors.HaltedError('Your reason.');

For apps that require manual refresh of authorization on a regular basis, Zapier provides a mechanism to notify users of expired credentials. With the ExpiredAuthError , the current operation is interrupted and a predefined email is sent out asking the user to refresh the credentials. While the auth is disconnected, Zap runs will not be executed, to prevent more calls with expired credentials. (The runs will be Held , and the user will be able to replay them after reconnecting.)

Example: throw new z.errors.ExpiredAuthError('You must manually reconnect this auth.');

For apps that use OAuth2 with autoRefresh: true or Session Auth, core injects a built-in afterResponse middleware that throws an error when the response status is 401. The error will signal Zapier to refresh the credentials and then retry the failed operation. You can also throw this error manually if your server doesn’t use the 401 status or you want to trigger an auth refresh even if the credentials aren’t stale.

Example: throw new z.errors.RefreshAuthError();

Since v11.2.0, there are two types of errors that can cause Zapier to throttle an operation and retry at a later time. This is useful if the API you’re interfacing with reports it is receiving too many requests, often indicated by receiving a response status code of 429.

If a response receives a status code of 429 and is not caught, Zapier will re-attempt the operation after a delay. The delay can be customized by the server response containing a specific Retry-After header in your error response or with a specified time delay in seconds using a ThrottledError :

Instead of a user’s Zap erroring and halting, the request will be repeatedly retried at the specified time.

For throttled requests that occur during processing of a webhook trigger’s perform, before results are produced; there is a max retry delay of 300 seconds and a default delay of 60 seconds if none is specified. For webhook processing only, if a request during the retry attempt is also throttled, it will not be re-attempted again.

You can write unit tests for your Zapier integration that run locally, outside of the Zapier editor. You can run these tests in a CI tool like Travis .

From v10 of zapier-platform-cli , we recommend using the Jest testing framework. After running zapier init you should find an example test to start from in the test directory.

Note: On v9, the recommendation was Mocha . You can still use Mocha if you prefer.

Introduced in [email protected] , appTester can now run arbitrary functions:

It’s useful to test your code without actually hitting any external services. Nock is a Node.js utility that intercepts requests before they ever leave your computer. You can specify a response code, body, headers, and more. It works out of the box with z.request by setting up your nock before calling appTester .

Here’s more info about nock and its usage in the README .

To run all your tests do:

You can also go direct with npm test or node_modules/.bin/jest .

The best way to store sensitive values (like API keys, OAuth secrets, or passwords) is in an .env (or .environment , see below note) file ( learn more ). Then, you can include the following before your tests run:

Remember: NEVER add your secrets file to version control!

Additionally, you can provide them dynamically at runtime:

Or, export them explicitly and place them into the environment:

Whether you use Travis, Circle, Jenkins, or another service, we aim to make it painless to test in an automated environment.

Behind the scenes zapier test does a standard npm test , which could be Jest or Mocha , based on your project setup.

This makes it straightforward to integrate into your testing interface. For example, if you want to test with Travis CI , the .travis.yml would look something like this:

You can substitute zapier test with npm test , or a direct call to node_modules/.bin/jest . We recommend putting environment variables directly into the configuration screens Jenkins, Travis, or other services provide.

Alternatively to reading the deploy key from root (the default location), you may set the ZAPIER_DEPLOY_KEY environment variable to run privileged commands without the human input needed for zapier login . We suggest encrypting your deploy key in the manner your CI provides (such as these instructions , for Travis).

Sometimes tests aren’t enough, and you may want to step through your code and set breakpoints. The testing suite is a regular Node.js process, so debugging it doesn’t take anything special. Because we recommend jest for testing, these instructions will outline steps for debugging w/ jest, but other test runners will work similarly. You can also refer to Jest’s own docs on the subject .

To start, add the following line to the scripts section of your package.json :

This will tell node to inspect the jest processes, which is exactly what we need.

Next, add a debugger; statement somewhere in your code, probably in a perform method:

This creates a breakpoint while inspect ing, or a starting point for our manual inspection.

Next, you’ll need an inspection client. The most available one is probably the Google Chrome browser, but there are lots of options . We’ll use Chrome for this example. In your terminal (and in your integration’s root directory), run yarn test:debug (or npm run test:debug ). You should see the following:

Now in Chrome, go to chrome://inspect. Make sure Discover Network Targets is checked and you should see a path to your jest file on your local machine:

assignment mismatch 1 variable but e.watch returns 2 values

Click inspect . A new window will open. Next, click the little blue arrow in the top right to actually run the code:

assignment mismatch 1 variable but e.watch returns 2 values

After a few seconds, you’ll see your code, the debugger statement, and info about the current environment on the right panel. You should see familiar data in the Locals section, such as the response variable, and the z object.

assignment mismatch 1 variable but e.watch returns 2 values

Debugging combined with thorough unit tests will hopefully equip you in keeping your Zapier integration in smooth working order.

Use npm modules just like you would use them in any other node app, for example:

And then package.json will be updated, and you can use them like anything else:

During the zapier build or zapier push step - we’ll copy all your code to a temporary folder and do a fresh re-install of modules.

Note: If your package isn’t being pushed correctly (IE: you get “Error: Cannot find module ‘whatever’” in production), try adding the --disable-dependency-detection flag to zapier push .
Note 2: You can also try adding a includeInBuild array property (with paths to include, which will be evaluated to RegExp, with a case insensitive flag) to your .zapierapprc file, to make it look like:
Warning: Do not use compiled libraries unless you run your build on the AWS AMI ami-4fffc834 , or follow the Docker instructions below.

Unfortunately if you are developing on a macOS or Windows box you won’t be able to build native libraries locally. If you try and push locally build native modules, you’ll get runtime errors during usage. However, you can use Docker and Docker Compose to do this in a pinch. Make sure you have all the necessary Docker programs installed and follow along.

First, create your Dockerfile :

And finally, create your docker-compose.yml file:

Note: Watch out for your package-lock.json file, if it exists for local install it might incorrectly pin a native version.

Now you should be able to run docker-compose run pusher and see the build and push successfully complete!

If you would like to use a transpiler like babel , you can add a script named _zapier-build to your package.json , which will be run during zapier build , zapier push , and zapier upload . See the following example:

Then, you can have your fancy ES7 code in src/* and a root index.js like this:

And work with commands like this:

There are a lot of details left out - check out the full example app here .

We recommend using zapier init . to create an app - you’ll be presented with a list of currently available example templates to start with.

We run your code on AWS Lambda, which only supports a few versions of Node. Sometimes that doesn’t include the latest version. Additionally, with thousands of apps running on the Zapier platform, we have to be sure upgrading to the latest Node version will not have a negative impact.

Update your zapier-platform-core dependency in package.json . Each major version ties to a specific version of Node.js. You can find the mapping here . We only support the version(s) supported by AWS Lambda .

IMPORTANT CAVEAT : AWS periodically deprecates Node versions as they reach EOL. They announce this on their blog . Similar info and dates are available on github . Well before this date, we’ll have a version of core that targets the newer Node version.

If you don’t upgrade before the cutoff date, there’s a chance that AWS will throw an error when attempting to run your app’s code. If that’s the case, we’ll instead run it under the oldest Node version still supported. All that is to say, we may run your code on a newer version of Node.js than you intend if you don’t update your app’s dependencies periodically.

You will see both template literal placeholders ${var} and (double) “curlies” {{var}} used in examples.

In general, use ${var} within functions and use {{var}} anywhere else.

Placeholders get evaluated as soon as the line of code is evaluated. This means that if you use ${process.env.VAR} in a trigger configuration, zapier push will substitute it with your local environment’s value for VAR when it builds your app and the value set via zapier env:set will not be used.

If you’re not familiar with template literals , know that const val = "a" + b + "c" is essentially the same as const val = `a${b}c` .

Not natively, but it can! Users have reported that the following npm modules are compatible with the CLI Platform:

  • fast-xml-parser

Since core v10, it’s possible for shorthand requests to parse XML. Use an afterResponse middleware that sets response.data to the parsed XML:

Yes, though there are caveats. Your entire function only gets 30 seconds to run. HTTP requests are costly, so paging through a list may time out (which you should avoid at all costs).

If you need to do more requests conditionally based on the results of an HTTP call (such as the “next URL” param or similar value), using async/await (as shown in the example below) is a good way to go. If you go this route, only page as far as you need to. Keep an eye on the polling guidelines , namely the part about only iterating until you hit items that have probably been seen in a previous poll.

To understand search-powered fields, we have to have a good understanding of dynamic dropdowns.

When users are selecting specific resources (for instance, a Google Sheet), it’s important they’re able to select the exact sheet they want. Instead of referencing the sheet by name (which may change), we match via id instead. Rather than directing the user copy and paste an id for every item they might encounter, there is the notion of a dynamic dropdown . A dropdown is a trigger that returns a list of resources. It can pull double duty and use its results to power another trigger, search, or action in the same app. It provides a list of ids with labels that show the item’s name:

assignment mismatch 1 variable but e.watch returns 2 values

The field’s value reaches your app as an id. You define this connection with the dynamic property, which is a string: trigger_key.id_key.label_key . This approach works great if the user setting up the Zap always wants the Zap to use the same spreadsheet. They specify the id during setup and the Zap runs happily.

Search fields take this connection a step further. Rather than set the spreadsheet id at setup, the user could precede the action with a search field to make the id dynamic. For instance, let’s say you have a different spreadsheet for every day of the week. You could build the following zap:

  • Some Trigger
  • Calculate what day of the week it is today (Code)
  • Find the spreadsheet that matches the day from Step 2
  • Update the spreadsheet (with the id from step 3) with some data

If the connection between steps 3 and 4 is a common one, you can indicate that in your field by specifying search as a search_key.id_key . When paired with a dynamic dropdown , this will add a button to the editor that will add the search step to the user’s Zap and map the id field correctly.

assignment mismatch 1 variable but e.watch returns 2 values

This is paired most often with “update” actions, where a required parameter will be a resource id.

Paging is only used when a trigger is part of a dynamic dropdown . Depending on how many items exist and how many are returned in the first poll, it’s possible that the resource the user is looking for isn’t in the initial poll. If they hit the “see more” button, we’ll increment the value of bundle.meta.page and poll again.

Paging is a lot like a regular trigger except the range of items returned is dynamic. The most common example of this is when you can pass a offset parameter:

If your API uses cursor-based paging instead of an offset, you can use z.cursor.get and z.cursor.set :

Cursors are stored per-zap and last about an hour. Per the above, make sure to only include the cursor if bundle.meta.page > 0 , so you don’t accidentally reuse a cursor from a previous poll.

Lastly, you need to set canPaginate to true in your polling definition (per the schema ) for the z.cursor methods to work as expected.

Each time a polling Zap runs, Zapier extracts a unique “primary key” for each item in the response. Zapier needs to decide which of the items should trigger the Zap. To do this, we compare the primary keys to all those we’ve seen before, trigger on new objects, and update the list of seen primary keys. When a Zap is turned on, we initialize the list of seen primary keys with a single poll. When it’s turned off, we clear that list. For this reason, it’s important that calls to a polling endpoint always return the newest items.

For example, the initial poll returns objects 4, 5, and 6 (where a higher primary key is newer). If a later poll increases the limit and returns objects 1-6, then 1, 2, and 3 will be (incorrectly) treated like new objects.

By default, the primary key is the item’s id field. Since v15.6.0, you can customize the primary key by setting primary to true in outputFields .

There’s a more in-depth explanation here .

For deduplication to work, we need to be able to identify and use a unique field. In older, legacy Zapier Web Builder apps, we guessed if id wasn’t present. In order to ensure we don’t guess wrong, we now require that the developers send us an id field. If your objects have a differently-named unique field, feel free to adapt this snippet and ensure this test passes:

Since v15.6.0, instead of using the default id field, you can also define one or more outputFields as primary . For example:

will tell Zapier to use (userId, slug) as the unique primary key to deduplicate items when running a polling trigger.

If you’re seeing errors like the following:

… then you need to update your zapier-platform-core dependency to a non-deprecated version that uses a newer version of Node.js. Complete the following instructions as soon as possible:

  • Edit package.json to depend on a later major version of zapier-platform-core . There’s a list of all breaking changes (marked with a :exclamation:) in the changelog .
  • Increment the version property in package.json
  • Ensure you’re using version v18 (or greater) of node locally ( node -v ). Use nvm to use a different one if need be.
  • Run rm -rf node_modules && npm i to get a fresh copy of everything
  • Run zapier test to ensure your tests still pass
  • Run zapier push
  • Run zapier promote YOUR_NEW_VERSION (from step 2)
  • Migrate your users from the previous version ( zapier migrate OLD_VERSION YOUR_NEW_VERSION )

Starting with v8.4.0, Zapier collects information about each invocation of the CLI tool.

This data is collected purely to improve the CLI experience and will never be used for advertising or any non-product purpose. There are 3 collection modes that are set on a per-computer basis.

When you run a command with analytics in anonymous mode, the following data is sent to Zapier:

  • which command you ran
  • if that command is a known command
  • how many arguments you supplied (but not the contents of the arguments)
  • which flags you used (but not their contents)
  • the version of CLI that you’re using

Enabled (the default)

When analytics are fully enabled , the above is sent, plus:

  • your operating system (the result of calling process.platform )
  • your Zapier user id

Lastly, analytics can be disabled entirely, either by running zapier analytics --mode disabled or setting the DISABLE_ZAPIER_ANALYTICS environment variable to 1 .

We take great care not to collect any information about your filesystem or anything otherwise secret. You can see exactly what’s being collecting at runtime by prefixing any command with DEBUG=zapier:analytics .

We’re in the process of doing some renaming across our Zapier marketing terms. Eventually we’ll use “integration” everywhere. Until then, know that these terms are interchangeable and describe the code that you write that connects your API to Zapier.

Introduced in v9.1.0, the zapier autocomplete command shows instructions for generating command line autocomplete.

Follow those instructions to enable completion for zapier commands and flags!

The Zapier Platform Packages

The Zapier Platform consists of 3 npm packages that are released simultaneously.

  • zapier-platform-cli is the code that powers the zapier command. You use it most commonly with the test , scaffold , and push commands. It’s installed with npm install -g zapier-platform-cli and does not correspond to a particular app.
  • zapier-platform-core is what allows your app to interact with Zapier. It holds the z object and app tester code. Your app depends on a specific version of zapier-platform-core in the package.json file. It’s installed via npm install along with the rest of your app’s dependencies.
  • zapier-platform-schema enforces app structure behind the scenes. It’s a dependency of core , so it will be installed automatically.

To learn more about the structure of the code (especially if you’re interested in contributing), check out the ARCHITECTURE.md file(s).

The Zapier platform and its tools are under active development. While you don’t need to install every release, we release new versions because they are better than the last. We do our best to adhere to Semantic Versioning wherein we won’t break your code unless there’s a major release. Otherwise, we’re just fixing bugs ( patch ) and adding features ( minor ).

Broadly speaking, all releases will continue to work indefinitely. While you never have to upgrade your app’s zapier-platform-core dependency, we recommend keeping an eye on the changelog to see what new features and bug fixes are available.

For more info about which Node versions are supported, see the faq .

The most recently released version of cli and core is 15.7.1 . You can see the versions you’re working with by running zapier -v .

To update cli , run npm install -g zapier-platform-cli .

To update the version of core your app depends on, set the zapier-platform-core dependency in your package.json to a version listed here and reinstall your dependencies (either yarn or npm install ).

For maximum compatibility, keep the versions of cli and core in sync.

You can get help by either emailing [email protected] or by joining our developer community here .

See CONTRIBUTING.md .

Need help? Tell us about your problem and we’ll connect you with the right resource or contact support.

IMAGES

  1. Error: (random.go) assignment mismatch: 2 variables but 1 values

    assignment mismatch 1 variable but e.watch returns 2 values

  2. Python: Return Multiple Values from a Function • datagy

    assignment mismatch 1 variable but e.watch returns 2 values

  3. assignment mismatch: 2 variables but uuid.NewV4 returns 1 values-CSDN博客

    assignment mismatch 1 variable but e.watch returns 2 values

  4. Define a function overlapping () that takes two lists and returns true

    assignment mismatch 1 variable but e.watch returns 2 values

  5. VBA Type Mismatch

    assignment mismatch 1 variable but e.watch returns 2 values

  6. assignment mismatch: 2 variables but uuid.NewV4 returns 1 values-CSDN博客

    assignment mismatch 1 variable but e.watch returns 2 values

VIDEO

  1. Solving Primavera P6 Schedule % Mismatch: Aligning Excel-based S Curve and Schedule Percent Complete

  2. gstr1 march return 2024

  3. Advancing Treatment Options for Mismatch Repair-Deficient Metastatic Colorectal Cancers

  4. STAT200

  5. scholarship category mismatch verify|scholarship cast mismatch verify|10th scholarship cast verify

  6. 0X01. C

COMMENTS

  1. go

    This function is returning 2 values, thus we have to use 2 variables. So you have to use. config := mollie.NewConfig (true, mollie.OrgTokenEnv) mollieClient, err := mollie.NewClient (client, config) assignment mismatch: 1 variable but mollie.NewClient returns 2 values will be resolved with this change. func (ps *PaymentsService) Create (ctx ...

  2. Undefined variable leads to `assignment mismatch: 2 variables but 1

    The result is: $ go run main.go # dns-cli/cmd cmd/subdomainDelete.go:38:6: undefined: recordID cmd/subdomainDelete.go:41:9: assignment mismatch: 2 variables but 1 values cmd/subdomainDelete.go:41:40: undefined: recordID. I've only been using golang for about six months and this is my first ever project using cobra.

  3. go 我这里的代码一个不理解的报错,麻烦会的看下谢谢

    go 我这里的代码一个不理解的报错,麻烦会的看下谢谢. 凉瓜. 70 1 11 20. 发布于. 2019-04-09. 报错信息是:serviceservice.go:38:11: assignment mismatch: 2 variables but 1 values. 代码如下. package service. import (.

  4. assignment mismatch: 2 variables but uuid.NewV4 returns 1 values

    编译器和启动时,报错冲突。. 启动时,报错。. 报错提示uuid.NewV4 ()函数,只有一个返回值。. 点进函数内部去发现确实是两个参数。. 只接受一个参数发现只接受一个参数,可以启动,但是编译器又报错。. 最终解决。. 在该项目的github->issues_assignment mismatch: 2 ...

  5. Golang中的变量声明_assignment mismatch: 2 variables but 1 value-CSDN博客

    上述程序声明两个变量name和age, 类型分别为string和int。. 如果您运行上述程序,则可以看到my name is naveen age is 29打印内容。. 简写声明要求赋值左侧所有变量的初始值。. 以下程序将打印错误assignment mismatch: 2 variables but 1 values。. 这是因为尚未为age分配值。. package ...

  6. GitHub

    Key: Exactly the same features / API objects in both client-go and the Kubernetes version. + client-go has features or API objects that may not be present in the Kubernetes cluster, either due to that client-go has additional new API, or that the server has removed old API. However, everything they have in common (i.e., most APIs) will work. Please note that alpha APIs may vanish or change ...

  7. golang 返回错误和接受对象个数不匹配的问题,修改错误之后不起作用

    assignment mismatch: 2 variables but uuid.NewV4 returns 1 values. 分析. 这个错误应该就是NewV4这个方法有两个返回值,但接受对象只有一个吧,然后我就增加了一个接受值,如下图. 相关截图. 源代码截图; 我修改成下面这样,依旧报这个错误; uuid.NewV4()函数截图; 请问这是怎么 ...

  8. client-go/tools/record/event.go at master

    Normally, those methods // uses the global default logger to record errors and debug messages. // If that is not desired, use WithLogger to provide a logger instance. type EventRecorderLogger interface { EventRecorder // WithLogger replaces the context used for logging. This is a cheap call // and meant to be used for contextual logging ...

  9. [Go] assignment count mismatch 1 = 2

    [Go] assignment count mismatch 1 = 2 . Golang 中这个错误的的意思是赋值变量的数目不匹配。 举例:

  10. assignment mismatch: 2 variables but uuid.NewV4 returns 1 values

    assignment mismatch: 2 variables but uuid.NewV4 returns 1 values. ... assignment mismatch: 2 variables but uuid.NewV4 returns 1 values 启动时,报错。 点进函数内部去 只接受一个参数 最终解决。 把go.mod中的版本声明,使用新版本即可解决。 相关推荐 ...

  11. 7 Ways to Look at the Values of Variables While Debugging in Visual

    1. DataTip. Hover over a variable to see its value. The most commonly used way to look at variables is the DataTip. When stopped in the debugger hover the mouse cursor over the variable you want to look at. The DataTip will appear showing you the value of that variable. If the variable is an object, you can expand the object by clicking on the ...

  12. useForm

    Rules. When defaultValue is not defined, the first render of watch will return undefined because it is called before register.It's recommend to provide defaultValues at useForm to avoid this behaviour, but you can set the inline defaultValue as the second argument.. When both defaultValue and defaultValues are supplied, defaultValue will be returned.. This API will trigger re-render at the ...

  13. go

    我假设(可能是错误的)我的错误意味着匿名函数正在立即执行(就像 Javascript 中的 IIFE),所以我尝试将内部部分包装在一个函数中(试图强制匿名函数返回一个函数,而不是 2 个值),像这样:

  14. Watch Variable: Values & Benefits

    A watch variable is a feature provided by various debugging tools that allows you to monitor changes in a variable's value during the execution of a program, aiding in code debugging. C. A watch variable is an execution control variable that stops and starts a program's execution based on changes in value. D.

  15. Set a watch on variables and expressions

    Execution pauses at the breakpoint. Open a Watch window by selecting Debug > Windows > Watch > Watch 1, or pressing Ctrl + Alt + W > 1. You can open additional Watch windows by selecting windows 2, 3, or 4. In the Watch window, select an empty row, and type variable a. Do the same for b and c.

  16. Beego开发中出现的报错:assignment mismatch: 1 variable but web.AppConfig.String

    assignment mismatch: 1 variable but web.AppConfig.String returns 2 values 主要是beego升级2.0后出现的问题 我现在还在找解决方案 Beego开发中出现的报错:assignment mismatch: 1 variable but web.AppConfig.String returns 2 values - 不忘前行 - 博客园

  17. 初识Golang之函数及方法的多返回值

    在大多数编程语言中,函数和方法只能由一个返回值。. 但在 Go 中,它们可以返回任意数量的值。. Go 中多个返回值最常见的用法是返回一个额外的错误值,可以通过查询该错误值来确定函数或方法运行时是否发生了错误。. 举几个例子。. bool, err := strconv.ParseBool ...

  18. Creating a Time class in Java

    Time (int h, int m) - If h is between 1 and 23 inclusive, set the hour to h. Otherwise, set the hour to 0. If m is between 0 and 59 inclusive, set the minutes to m. Otherwise, set the minutes to 0. Time should include the following methods: String toString () - Returns the time as a String of length 4 in the format: 0819.

  19. Zapier Platform CLI docs

    Go check out our full CLI reference documentation to see all the other commands!. Tutorial. For a full tutorial, head over to our Tutorial for a comprehensive walkthrough for creating your first app. If this isn't your first rodeo, read on! Creating a Local App. Tip: Check the Quick Setup if this is your first time using the platform!. Creating an App can be done entirely locally and they ...