27
September
,
2022
Product

Debugging your apps in Appsmith with the Appsmith Debugger, part 2

Debugging your apps in Appsmith with the Appsmith Debugger, part 2
Ayush Pahwa
0
 minutes ↗
Meet the sidekicks, Logs and Inspect Entity

The first part of this teardown helped you see how the Error pane can save you hours in debugging and build better internal apps. In this one, let’s meet two seemingly innocuous features that can give you debugging super-powers when used right.

Logs

The Logs pane shows you everything logged by Appsmith and, like Errors, in lockstep with the sequence of code execution in your build. Borrowing from the experience of showing logs in general—in the browser console, from a shell, or on your favorite IDE—the Logs pane has four views for specific debugging use cases.

Post_5.jpg (1920×1080)

All Logs

This view shows you all logs timestamped by when we saw them in your Appsmith session. Updated a widget’s property? Wrote a new action to your GraphQL datasource? Ran a JS Object to concat two queries? It all gets logged, including the errors you see in the Errors pane, in a separate view called Error Logs. You will see how that can be useful in a GIF, pun intended.

The All Logs view can be a little overwhelming, though, and a bit of work when you have been at your build for a while. For easier tracking of relevant logs, use one of the three options below.

Post_6.gif (1440×810)

Errors Logs

Everything you learned about the Errors pane applies to this view, too, but there’s more to this view. Here's a likely scenario to show that.

State #1

You have a button to reload a table, presumably to refresh the data from your datasource.

Condition #1

You use the Button property, onClick, which runs the query to fetch the latest data into the table.

Scenario #1

Your query fails.

- On just the Error pane

  • You see just the error for the failing query. Although helpful, it doesn’t offer context for the before and after of the error.

- On the Error Logs pane under Logs

  1. You see logs for the Button click and the executed onClick event .
  2. Because the onClick property is binded to queries and JS Objects, you see the ones that are successfully executed and those that fail.
Error_Logs__Appsmith.gif (1440×810)

The triaging in our example above is especially useful when you have nested queries, several dependent bindings, and a more complex workflow overall.

Console Logs

console.log_in_the_Editor__Appsmith.jpg (1920×1080)

Just introduced in the Debugger, console methods in Appsmith help you see statements for just JS Objects and JavaScript bindings so much better than in the browser sub-window.

Set points in your code that you want to log statements at, view tabular data, or see groups for repeated errors.

System Logs

Post_7.jpg (1920×1080)

Automatically tracking all your interactions with Appsmith during build, System Logs show a helpful trail of activity by descending order of timestamp, especially useful when you want to go back in time or pivot from a point of failure to everything that led to it.

They show up for different situations and interactions for the type of entity you are working with.

With widgets, you see a log when you

  • Drag-and-drop a new widget on the canvas.
  • Update the widget’s properties
    Updating a property also updates all its dependent properties which then show up in System Logs.
Dependent_properties_updates_in_system_logs__Appsmith.gif (1280×720)
For example, when you update the tableData property, you also see its dependent properties like selectedRowIndex, filters, triggeredRowIndex, and so on.
  • Trigger events with an end-user action.
Trigger_events_with_an_end-user_action__Appsmith.gif (1280×720)
For example, when you are using an end-user action to store a value with storeValue or when you want a click-action to trigger an operation like an update or delete and are using onClick, you see them show up in System Logs.
  • Delete a widget from the canvas

With actions, you see them when you

  • Create a new datasource or a query
  • Update query properties like queryName, queryBody, queryConfiguration, and queryProperties.
  • Execute a query
Execute_a_query.gif (1440×810)
This can be either from query pane, running a plain REST API query, a JS Object, or via a widget’s bindings.
  • Delete a query

With JS Objects, you’ll see system logs when you

  • Create and update code inside JS Objects
  • Execute JS Objects
Execute_JS_Objects.gif (1440×810)

Just like errors, system logs are native to entities and have four parts to them.

Parts_of_a_system_log_line__Appsmith.jpg (1920×1080)

The timestamp

Logged as your entities are created, updated and deleted, these little breadcrumbs help you track back from when the error occurred to when it was last A-Okay.

Timestamped_logs_in_System_Logs.gif (1440×810)

The message

Useful during build, the message of the log answers two questions— what were you doing with an entity—creating it, updating it, deleting it—and what happened with your action—success or failure.

  • With widgets, outside of CRUD information, you also see event-specific info like onClick and showAlert linked to those widgets.
  • Queries and JS Objects are straightforward with start and end points that indicate if they were updated, ran, and failed.

The source

Like errors, a system log has two parts to its source—the entity’s name.the type of entity, e.g., SELECT1.TABLE1.WIDGET.

Redirect_from_an_Inspect_Entity_sub-window.gif (1440×810)
👌🏽 Appsmith Experience plug

Clicking the source from the logs takes you to the associated entity anywhere in Appsmith, be it a widget, a query, or a JS Object. Noice!

The response

This doesn’t always show, but when it does, it can be useful confirmation of a binding working, a query running successfully, or a JS Object executing completely.

  • For widgets, you see which properties are updated when you are configuring them and how.
    Say you’re updating the text widget’s background property and you don’t see it change on the canvas. Track the log to the response for a quick confirmation of that and troubleshoot the canvas next.
  • For queries, you’ll see two different logs—the start of a query run and the status of its execution.
    The first type of log will show you configuration details of the query—helpful to verify if the config matches the request.        

{
    "timeoutInMillisecond":10000
    "paginationType":"NONE"
    "encodeParamsToggle":true
    "body":"SELECT * FROM public."users" LIMIT 10;"
    "pluginSpecifiedTemplates":[
        0:{
            "value":true
        }
    ]
}

  • The second type will throw an error if the run fails. When the query runs successfully, it shows all the parameters that the query ran with and the time taken for the response.

{
	"response" : [...],
	"request" : {
		"actionId" "6321c1193668£71e£7caala2"
		"requestedAt" : 1663912830.640344
		"requestParams": {...}
}

  • With JS Objects, you see the response from the function as a JSON after an object is successfully run. This shows you how Appsmith handles the function while evaluating and running it and can be useful for spotting conflicts, undefined references, or troublesome variables.

Inspect Entity

Borrowing from a modern browser’s Inspect Element feature, Inspect Entity lets you see incoming and outgoing entities for any widget. These entities can be queries, JS Objects, or even other widgets.

Group_8480.png (1920×1080)
  • Incoming entities are those that fetch data from the datasource into the widget.
    For example, if the data on a table is populated by a Postgres query, you’ll see the query name under the Incoming entities column.
  • Outgoing entities are those that can specify the data that’s to be sent to the datasource in a typical CUD operation and then send it to your datasource.
    Say, a text widget is binded to a table's selectedRow property, you will see the text widget’s name under the Outgoing entities column.

The Inspect Entity pane lets you see dependencies for all your widgets on the canvas, especially useful if you have a medium-complex app with several widgets working off of each other. For example, when you have a parent widget or query that controls bindings on other dependent widgets---call them children widgets---, Inspect Entity can show you all those children when you click the parent and quickly take you to any one of them directly.

In combination with Errors, Logs and Inspect Entity round out the Debugger for several scenarios during build and save you hours in building an app end-users love. Try out the Debugger and let us know how you like it, what it's missing, and what we can improve. Our Discord is the best place for that feedback.

Debugging your apps in Appsmith with the Appsmith Debugger, part 2
27
September
2022
Product

Debugging your apps in Appsmith with the Appsmith Debugger, part 2

Debugging your apps in Appsmith with the Appsmith Debugger, part 2
Ayush Pahwa
0
 minutes ↗
#
product
#
errors
#
troubleshooting
#
debugger
Product
Meet the sidekicks, Logs and Inspect Entity

The first part of this teardown helped you see how the Error pane can save you hours in debugging and build better internal apps. In this one, let’s meet two seemingly innocuous features that can give you debugging super-powers when used right.

Logs

The Logs pane shows you everything logged by Appsmith and, like Errors, in lockstep with the sequence of code execution in your build. Borrowing from the experience of showing logs in general—in the browser console, from a shell, or on your favorite IDE—the Logs pane has four views for specific debugging use cases.

Post_5.jpg (1920×1080)

All Logs

This view shows you all logs timestamped by when we saw them in your Appsmith session. Updated a widget’s property? Wrote a new action to your GraphQL datasource? Ran a JS Object to concat two queries? It all gets logged, including the errors you see in the Errors pane, in a separate view called Error Logs. You will see how that can be useful in a GIF, pun intended.

The All Logs view can be a little overwhelming, though, and a bit of work when you have been at your build for a while. For easier tracking of relevant logs, use one of the three options below.

Post_6.gif (1440×810)

Errors Logs

Everything you learned about the Errors pane applies to this view, too, but there’s more to this view. Here's a likely scenario to show that.

State #1

You have a button to reload a table, presumably to refresh the data from your datasource.

Condition #1

You use the Button property, onClick, which runs the query to fetch the latest data into the table.

Scenario #1

Your query fails.

- On just the Error pane

  • You see just the error for the failing query. Although helpful, it doesn’t offer context for the before and after of the error.

- On the Error Logs pane under Logs

  1. You see logs for the Button click and the executed onClick event .
  2. Because the onClick property is binded to queries and JS Objects, you see the ones that are successfully executed and those that fail.
Error_Logs__Appsmith.gif (1440×810)

The triaging in our example above is especially useful when you have nested queries, several dependent bindings, and a more complex workflow overall.

Console Logs

console.log_in_the_Editor__Appsmith.jpg (1920×1080)

Just introduced in the Debugger, console methods in Appsmith help you see statements for just JS Objects and JavaScript bindings so much better than in the browser sub-window.

Set points in your code that you want to log statements at, view tabular data, or see groups for repeated errors.

System Logs

Post_7.jpg (1920×1080)

Automatically tracking all your interactions with Appsmith during build, System Logs show a helpful trail of activity by descending order of timestamp, especially useful when you want to go back in time or pivot from a point of failure to everything that led to it.

They show up for different situations and interactions for the type of entity you are working with.

With widgets, you see a log when you

  • Drag-and-drop a new widget on the canvas.
  • Update the widget’s properties
    Updating a property also updates all its dependent properties which then show up in System Logs.
Dependent_properties_updates_in_system_logs__Appsmith.gif (1280×720)
For example, when you update the tableData property, you also see its dependent properties like selectedRowIndex, filters, triggeredRowIndex, and so on.
  • Trigger events with an end-user action.
Trigger_events_with_an_end-user_action__Appsmith.gif (1280×720)
For example, when you are using an end-user action to store a value with storeValue or when you want a click-action to trigger an operation like an update or delete and are using onClick, you see them show up in System Logs.
  • Delete a widget from the canvas

With actions, you see them when you

  • Create a new datasource or a query
  • Update query properties like queryName, queryBody, queryConfiguration, and queryProperties.
  • Execute a query
Execute_a_query.gif (1440×810)
This can be either from query pane, running a plain REST API query, a JS Object, or via a widget’s bindings.
  • Delete a query

With JS Objects, you’ll see system logs when you

  • Create and update code inside JS Objects
  • Execute JS Objects
Execute_JS_Objects.gif (1440×810)

Just like errors, system logs are native to entities and have four parts to them.

Parts_of_a_system_log_line__Appsmith.jpg (1920×1080)

The timestamp

Logged as your entities are created, updated and deleted, these little breadcrumbs help you track back from when the error occurred to when it was last A-Okay.

Timestamped_logs_in_System_Logs.gif (1440×810)

The message

Useful during build, the message of the log answers two questions— what were you doing with an entity—creating it, updating it, deleting it—and what happened with your action—success or failure.

  • With widgets, outside of CRUD information, you also see event-specific info like onClick and showAlert linked to those widgets.
  • Queries and JS Objects are straightforward with start and end points that indicate if they were updated, ran, and failed.

The source

Like errors, a system log has two parts to its source—the entity’s name.the type of entity, e.g., SELECT1.TABLE1.WIDGET.

Redirect_from_an_Inspect_Entity_sub-window.gif (1440×810)
👌🏽 Appsmith Experience plug

Clicking the source from the logs takes you to the associated entity anywhere in Appsmith, be it a widget, a query, or a JS Object. Noice!

The response

This doesn’t always show, but when it does, it can be useful confirmation of a binding working, a query running successfully, or a JS Object executing completely.

  • For widgets, you see which properties are updated when you are configuring them and how.
    Say you’re updating the text widget’s background property and you don’t see it change on the canvas. Track the log to the response for a quick confirmation of that and troubleshoot the canvas next.
  • For queries, you’ll see two different logs—the start of a query run and the status of its execution.
    The first type of log will show you configuration details of the query—helpful to verify if the config matches the request.        

{
    "timeoutInMillisecond":10000
    "paginationType":"NONE"
    "encodeParamsToggle":true
    "body":"SELECT * FROM public."users" LIMIT 10;"
    "pluginSpecifiedTemplates":[
        0:{
            "value":true
        }
    ]
}

  • The second type will throw an error if the run fails. When the query runs successfully, it shows all the parameters that the query ran with and the time taken for the response.

{
	"response" : [...],
	"request" : {
		"actionId" "6321c1193668£71e£7caala2"
		"requestedAt" : 1663912830.640344
		"requestParams": {...}
}

  • With JS Objects, you see the response from the function as a JSON after an object is successfully run. This shows you how Appsmith handles the function while evaluating and running it and can be useful for spotting conflicts, undefined references, or troublesome variables.

Inspect Entity

Borrowing from a modern browser’s Inspect Element feature, Inspect Entity lets you see incoming and outgoing entities for any widget. These entities can be queries, JS Objects, or even other widgets.

Group_8480.png (1920×1080)
  • Incoming entities are those that fetch data from the datasource into the widget.
    For example, if the data on a table is populated by a Postgres query, you’ll see the query name under the Incoming entities column.
  • Outgoing entities are those that can specify the data that’s to be sent to the datasource in a typical CUD operation and then send it to your datasource.
    Say, a text widget is binded to a table's selectedRow property, you will see the text widget’s name under the Outgoing entities column.

The Inspect Entity pane lets you see dependencies for all your widgets on the canvas, especially useful if you have a medium-complex app with several widgets working off of each other. For example, when you have a parent widget or query that controls bindings on other dependent widgets---call them children widgets---, Inspect Entity can show you all those children when you click the parent and quickly take you to any one of them directly.

In combination with Errors, Logs and Inspect Entity round out the Debugger for several scenarios during build and save you hours in building an app end-users love. Try out the Debugger and let us know how you like it, what it's missing, and what we can improve. Our Discord is the best place for that feedback.

The Appsmith Debugger now supports Console methods
23
September
2022
Announcement

The Appsmith Debugger now supports Console methods

The Appsmith Debugger now supports Console methods
Rishabh Rathod
0
 minutes ↗
#
debugger
#
troubleshooting
#
console-methods
Announcement

For a while now, you have used and loved the Appsmith Debugger, nearly complete with a Error pane, system and error logs, and an entity inspector. We say nearly complete because it was missing one of the most popular debugging tools in a dev’s toolkit—console methods.

We are happy to announce the availability of console methods for both cloud users and self-hosters on v1.8.0.

“But, what is the Appsmith Debugger?”

Image_1.png (1920×1080)

Think of the Appsmith Debugger as a set of Chrome DevTools—like for Appsmith. It lives on the familiar 🐞 everywhere in Appsmith and

  • shows helpful error messages for bindings, queries, and variables
  • lets you inspect entity relationships
  • filters system and user logs

All of this is helpful when debugging unexpected API responses or app viewer experiences. Should you care to learn more, this post breaks down the debugger by each one of its features.

“Okay, and console methods are…”

Just one of the most popular ways of print debugging in modern browsers, console methods, exposed by the console API, are a set of functions that help you log the values of variables at set points in your code, messages, or even tabular data so you can investigate them in your browser’s debugging console.

Before today, you could use all supported browser console methods, but only in the browser’s dev tools sub-window. To any developer with their hands dirty with front-end code, the browser debugging subwindow is a necessary evil—a thousand lines of errors, messages, values, and steps that you would have to sift through. We are not going to say, “Looking for the literal needle in the haystack”, but you know you are thinking it.

“And the Appsmith Debugger has a console now?”

Yes! 🥳

So, instead of something like,

you now see,

Image_3.png (1920×1080)

Sweet? This gets sweeter.

Supported methods

  • log

Almost synonymous with console, the .log() method is one of the most popular ways to log a message or the values of variables defined in your Javascript.

It can also be used to show helpful messages or comments, say, the entry and exit points of functions.

Example


getUUID: () => {
		console.log("entry - getUUID function");
		let prefix;
		
		let d = new Date().getTime();
		console.log("new date created -", d);
		d += (parseInt(Math.random() * 100)).toString();
		console.log(d, "random number generated by getUUID")
		if (undefined === prefix) {
			prefix = 'uid-';
		}
		d = prefix + d;
		console.log("UUID created -", d);
		console.log("exit - getUUID function")
		return d;
	}

Result

Image_4.png (1920×1080)
  • error

the .error() method logs an error message to the Appsmith console, be it a a string like, “This is an error message” or the value of a function.

Say you've written a function and you suspect it’s returning an error., but you don’t know what kind. For unknown unknowns like this, `error` comes handy.

Example


checkTextWidget: () => {
		const element = Text1.text;
		if (element == "") {
			console.error("There is an error. The Text property is empty ");
		}
		return element;
	}

Result

Image_5.png (1920×1080)
  • warn

Jus as .error() aids error investigations, .warn() shows, well, warnings for known knowns. Some situations this can come in handy are,- When the evaluated value of binded data on a widget is not using the same datatype as the expected value- When widgets continue to use deprecated queries or functions- When the timezone used in a datetime functions doesn't match the browser’s

Example


selectDefaultValue: () => {
	 const defaultValue = Select1.selectedOptionValue;
		if (defaultValue == ""){
			console.warn("No values selected on Select1 widget ")
		}
		return defaultValue;
}

Result

Image_6.png (1920×1080)
  • table

table (.) just does what it says—logs a Table widget’s data in key-value pairs for rows as objects. While we support this in Appsmith, we are still working on a browser console-like table, especially as we make the Table feature-richer.

Example


table1DataFunc: () =>{
		const data = Table1.tableData;
		console.table(data)
}

Result

Image_7.png (1920×1080)

That’s it! You now have the power of the console right within in Appsmith. There are other useful views available under Logs and we'll talk about them in a follow-up to the Debugger teardown soon. Bookmark this page. Thank us later.

Debugging your app in Appsmith with the Appsmith Debugger, Part 1
20
September
2022
Product

Debugging your app in Appsmith with the Appsmith Debugger, Part 1

Debugging your app in Appsmith with the Appsmith Debugger, Part 1
Ayush Pahwa
0
 minutes ↗
#
product
#
errors
#
troubleshooting
#
debugger
Product

That title is a tongue twister, innit? Almost.

Here’s a meme that isn’t. It’s just the painful truth.

Debugging_is_like_being_lost_in_a_deser.jpg (749×500)

There is no perfect code, so you know debugging is inevitable, but it’s still a chore and is as crushing often times as the meme claims it is.

But, while debugging is inevitable, making it painful is optional, especially when you have the Appsmith Debugger. We have claimed we champion developer experience as many times as we could before without being brazen about it. We think. So, we thought some more and said, “Let’s prove the claim, too.”

“Wait, wait. What is the Appsmith Debugger?”

In 2021, we shipped the Appsmith Debugger, a set of Chrome DevelTools-like features that have helped you investigate and resolve errors in Appsmith.

We recorded a video for it in a series about the Debugger, talked about it in our docs, and referenced it enough times to make you groan about our obsession with errors. If this is the first you are hearing of it, get on our Discord so we can tell you some more about it.

Why we did this

Browser dev tools are as helpful as a magnet when looking for iron fillings in a pristine haystack. To the untrained eye, they can be downright criminal, too.

Browser_debugger.jpeg (960×506)
Source: Reddit

Sure, sure, they nest groups of errors and there are separate tabs for the console and the debugger, but meh! There’s a sea of error messages, system logs, console logs, and then there’s you swimming in it.

Before we shipped the debugger, you saw,

  • errors inside a widget's Property pane that floated on your canvas which probably already had several widgets
  • the Editor’s Response pane, which clubbed legit responses with errors

The Debugger solved several of those problems.

Post_8.jpg (1920×1080)

What’s the Debugger have

Available on app.appsmith.com and our self-hosted release images, it can be called by toggling the debug icon—the one that looks like a bug—on the bottom-right corner of your Appsmith screen or with CTRL/CMD +D.

Inside the Debugger, live three panes, Errors, Logs, and Inspect Entity, each with their own uses. In the first part of this two part post, we will break the Error pane down for you and see how it can save you hours over browser dev tools in debugging.

If you would much rather just learn about Logs and Inspect Entity, bookmark this post. We will link to Part 2 in five days. :-)

Errors

Borrowing from a browser’s dev tools sub-window but improving on it radically, the Error pane lists all errors that we see when you are building inside Appsmith. Familiar examples include syntax errors from JavaScript bindings, reference errors from queries, and datatype mismatch errors.

Errors in the pane are specific to an Appsmith entity. Translated from Appsmithlish, it means you see helpful error messages about a faulting widget, a rogue query, or a stubborn JS Object.

Untitled.gif (1440×810)
Example of a faulting widget and the error beaconing it
Untitled.gif (1440×810)
A JS Object error

  • These errors get logged to the pane in lockstep with the sequence of code execution in Appsmith.
  • The Error pane is the default view when working with widgets—most noticeable if you have the Debugger sub-window resized as in the pictures in purple—so you know what’s going wrong and where in real-time.
  • The Editor's Error Pane is smarter. It doesn’t automatically switch to the Error pane—Response is the default on this screen—when an error occurs. Instead, the Debug icon lights up in red with a numeric notification that’s like a running ticker for the number of errors the Debugger sees with your queries or JS Objects. Click it to open the Error pane.
  • Every error you see in the pane follows a template with a few helpful pieces of info to help you debug.
image_high.jpeg (1920×1080)
Numbers on this image correspond to bullets below. Images in sub-bullets below show what the sub-bullet talks about.

The timestamp

Logged as your code executes or a value evaluates with your widgets, these little breadcrumbs help you track back from when the error occurred to when last it was A-Okay.

The issue

Depending on the error type, you will see a couple different kinds of issues.

  1. With widgets, you’ll see the faulting widget property’s name. An example of this is the commonplace The value at tableData is invalid, occurring when the property tableData expects an Array<Object> datatype but you have an Array<List> instead.
  2. With queries, you see more specific errors, often specific to the datasource you are running your queries to, often indicated by status codes returned by your failing requests.
  3. With JS Objects, we straight-up level with you about the parseability of your functions. Parseability probably isn’t a word, but you know what we mean.

The source

This has two parts to it—the entity’s name.the type of entity the troublesome one is, e.g., SELECT1.WIDGET. As is obvious and has been to you, SELECT1 is the entity’s name and WIDGET is the entity type.

👌🏾 Appsmith Experience plug: Clicking the source takes you to the faulting entity anywhere in Appsmith, be it a widget, a query, or a JS Object. Noice!

The message

This is the most helpful part of the message, beginning with Error and ending with a helpful bit of text or a number.

  1. Because widgets bind to queries or JS Objects using JavaScript, quite a few errors you see are the same as familiar JavaScript errors like SyntaxError or TypeError. Some other errors show is not defined. This is when a variable, a query, or a JS Object isn’t defined, but you have specified it in the Property pane.
  2. In the Editor, these messages go a step further and call out the line number in the editor that has the faulting code. For example, Line 2: Unrecognized token '$'. This type of message has three parts to it.
Post_9.jpg (1920×1080)

1. The type: Error

2. The string: relation “public.user” does not exit

3. The line number: Position 15

😻 Appsmith Experience plug: Clicking the message will open our in-app docs finder and run a helpful search to show you top docs matching the error.

Response from queries or bindings

This doesn’t always show, but when it does, it can show you helpful responses with query params or evaluated values of data bindings.

Post_10.jpg (1920×1080)
  1. With widgets, you’ll see the evaluated value from the bindings.
  2. With queries, you’ll see the payload from the API you are querying.

“How does all of this help?”

Consider two situations we have painfully drawn for you.

State #1

You have several queries and widgets on your way to a complete build.

Condition #1

You have nested queries inside JS Objects. Meaning, these queries are binded to multiple widgets via JavaScript transformations and have dependent parameters with each other.

Scenario #1

A query fails and returns an error.

Without the Appsmith Debugger

You decide to sift through the browser dev tools sub-window, trying to locate the faulty query in something that looks like ↓.

The_browser_console.png (1920×1080)

When you find the first problem query, you’re hoping against hope this is your patient zero.

  1. If so, congratulations aren’t quite in order yet. You’re still going to have to surgery the query to see what went wrong where.
  2. With browser tools, may you be lucky and find a fix in the first hour.

Most times, though, Murphy’s Law applies.

  1. Meaning, you will need to find the last problem query.
  2. Repeat steps #1 and #2 with all the sub-steps in between

If you have a friend who’s on Appsmith, you hear them say, “Good morning. Do you have a ready app? No? Try the Debugger. 🙄”

With the Appsmith Debugger

You see all the errors from all the failed queries In the Error pane and nothing else to crowd your investigation.

  1. You quickly scan by the type of errors.
  2. Errors are listed in the sequence of query execution.
Post_11.jpg (1920×1080)
So you can simply scroll to the first failed query, and investigate further.

  1. The error message tells you what failed with the params in which line, neatly indented neatly for you.

Don’t remember the query’s name? Pfft! We got it. Click the error message, and go right to the error source.

Trouble troubleshooting? Click the error message and find super-relevant docs in Appsmith’s doc finder.

At the end of it, you save a whole night’s hair-pulls, wake up bright and fresh, sip your coffee, and wonder why some people still use browser dev tools. 🤔 Maybe you should refer them to us.

State #2

You have the data from a REST API and the table for your dashboard, but you have left the chart for the very end. You are sensible like that. Charts are tricky things in general.

Condition #2

You have to bind the chart widget from Fusion Charts or one of our defaults with a query that should output the format Array<{ x: string, y: number Required }> as input to the widget. This will need JavaScript transformations.

Scenario #2

You get a datatype mismatch error.

Without the Appsmith Debugger

You toggle around the floating EXPECTED STRUCTURE, EXPECTED STRUCTURE - EXAMPLE, and EVALUATED VALUE panes to understand the chart widget’s configuration.

You have a JS Object for the transformation, so you now switch back and forth between the canvas and the JS Editor for each possible fix in the JS code.

  1. By now, you have console.loged your way to the browser tools sub-window. Magnet, meet Iron Fillings In A Haystack.
  2. Forgot the change you made to the JS Object five tries ago? Yeah, well, no System Logs, so what can you do, right? Maybe note each change on Sublime or VS Code from this point on.

With the Appsmith Debugger

Post_12.jpg (1920×1080)

Right after you run the transformation, you see the floating-pane-that-we-don’t have-a-name-for-yet show you some red and the Error pane light up with all your errors, timestamped and sequenced by the order of code execution.

  1. You see the type of error and the evaluated value for the faulting entity. Stick to this without worrying about the unnamed floating pane.
  2. Your query has trouble getting a response from your datasource, so you see that error, but hey, you also see the binding failure of that same query with the widget.
  3. No hunting for the query or the widget you want to troubleshoot. One click from the Debugger and you are transported to the associated entity.
Debugger_with_click-actions__JS_Editor.jpg (1920×1080)

You see all the errors from the transformation in one pane with click-actions for each one of them.

Docs_finder_from_Response__Appsmith.gif (1440×810)

Error messages not enough? Click the error and choose, Browse code snippets, and voila! You now now search for the chart + the query right there and see some of our helpful docs.

Made it to here? Your life inside Appsmith is going to change.

Also, this is just part one of this two-part breakdown. What’s next?

https://media.giphy.com/media/3kIGmlW0lvpnmF3bGy/giphy.gif

Better than post-credits. A whole other movie featuring Logs and Inspect Entity. Meanwhile, here’s a few things you can do.

Until the next Debugger post, Appsmiths.

P.S.: We love you.

GraphQL is now available in Appsmith
21
September
2022
Announcement

GraphQL is now available in Appsmith

GraphQL is now available in Appsmith
Vihar Kurama
0
 minutes ↗
#
graphql
#
integrations
Announcement

We have teased the availability of GraphQL CRUD operations inside Appsmith for more than a couple weeks now. And we are excited to announce it’s finally here!

What_you_really_want_is_GraphQL.jpg (700×498)

Appsmith now natively supports both authenticated and unauthenticated GraphQL API endpoints with native GraphQL methods for querying your connected endpoints.

Before we dive in

GraphQL is many things to many devs. For this feature, we will talk about GraphQL as it is understood most popularly—a query language and a runtime for your existing data.

While there was a way to use GraphQL inside Appsmith, it was not the easiest.

  • Because Appsmith only supported REST APIs, you would have to transform GraphQL fetch queries with JSON.stringify. Less painful than mutations
  • For each write or update query, in addition to transforming the query, you would have to specify an object and then define the object’s variables in the query body. Each variable would have to be brought in from the widgets you used on the canvas. More painful
  • We didn’t have auto-complete for variables inside queries until recently, so you would need to switch between the editor and the canvas. Super-painful

Given how popular GraphQL is with devs in general and those using Appsmith in particular, it was a no-brainer to ship native support as soon as we could, but we had to ensure we weren’t leading you onto tricky ground for connecting a datasource, writing queries, or getting variable names from widgets. Several careful considerations later, we are ready for the expose.

Let’s dive in

GraphQL inside Appsmith supports both unauthenticated—for single-use queries—and authenticated—for reusable datasource configs like the URL and params—API endpoints. To both endpoint types, you can,

  • Run dynamic query operations with variables from your Appsmith widgets
  • Write, update, or delete data with mutations
  • Paginate your data by Limit And Offset or Keysets, also called cursor-based pagination
☝🏾 We will assume you have created a new app—recommended in your Appsmith account—and have a ready GraphQL endpoint, e.g., https://api.github.com/graphql in the rest of this post.

Connecting an API

  • For single-use queries, you can use an unauthenticated API endpoint. Specify URL, headers, and query params and start writing your query just as you would with a REST API datasource.
  • For reusable configs like URL and params, choose Authenticated GraphQL API. In addition to specifying a URL, headers, and params, you would need to configure your authentication method, again, just as with a REST API.

Query and Mutation

GraphQL uses query to fetch data and mutation to write data from and to the endpoint.

  • You will notice we have a two-pane layout for the query object and variables from your Appsmith widgets.
  • A good way to test query out is to write the body without params and run the query to see its response.
Query_variables_and_response_with_GraphQL__Appsmith.gif (1024×576)
  • Or maybe you are feeling bold already and would like to specify a param—an object in GraphQL parlance—to your query.
☝🏾 GraphQL queries in Appsmith auto-indent, just like REST API ones.
  • Variables follow the usual GraphQL enforcements and need to be in their own object. Hence, the second pane. You pass the variable to the query operation as a key-value-pair argument, but you already know that, so we will stop being preachy now.
Variables_evaluated_values_and_query_params_with_GraphQL__Appsmith.gif (1440×810)
  • While most GraphQL implementations show the variable object right below the query object in the body of the request, we think a two-pane layout simplifies the experience when you have longer query objects with several nested sub-fields.
  • You can specify variables from your Appsmith widgets for dynamic bindings, of course.
Evaluated_values_with_GraphQL__Appsmith.gif (1440×810)
  • And, auto-complete works inside {{ }} just like you would expect it to. Sweet, right?
☝🏾 Last preach. Promise. GraphQL relies heavily on the database schema exposed by the endpoint and query operations need to adhere to the schema to return expected responses.
  • You can use fragment with your queries inside Appsmith to do away with repeating sets of fields that you would otherwise need to specify over and over again.

query issueDetailsFragment{
  repository(owner:"appsmithorg", name:"appsmith"){
    issues(orderBy:{field:CREATED_AT, direction:DESC},first:5){
      nodes{
        ...issueDetails
      }
      pageInfo{
        endCursor
        hasNextPage
        hasPreviousPage
        startCursor
      }
    }
  }
}

fragment issueDetails on Issue{
	id
  number
  title
  url
}

  • mutations always need an argu…

  Sorry, we started being preachy again.

  • Much like with query, you can use variables from your Appsmith widgets in mutations operations.
Mutations_with_GraphQL__Appsmith.gif (1280×720)

Pagination

You will see a Pagination tab under every GraphQL query, much like with a REST API, where you can choose from one of two supported pagination methods in Appsmith.

  • Limit and offset: Straightforward and basic, this method expects a limit and an offset value.
Link_and_offset_pagination_with_GraphQL__Appsmith.gif (1440×810)

Example


query GetAllUsers($limitz1:Int, $offsetz:Int){
  users(limit:$limitz1, offset:$offsetz){
    id
    country
    dob
    email
    gender
    image
    latitude
    longitude
    name
    phone
  }
}

  • Cursor-based pagination: One of GraphQL’s powerful features, this method expects a last location  and where you need to go next as limits to traverse through the graph of your data. We make room for that with four variable fields that make it easy to paginate your apps.
Cursor-based_paginaton_with_GraphQL__Appsmith.gif (1440×810)

Example


query getIssues(
  $orgName: String!
  $repoName: String!
  $beforeValue: String
  $afterValue: String
  $lastValue: Int
) {
  repository(owner: {{Input2.text}}, name: {{Input3.text}} ) {
    issues(
      orderBy: { field: CREATED_AT, direction: DESC }
      first: 5
      last: $lastValue
      before: $beforeValue
      after: $afterValue
    ) {
      nodes {
        id
        title
      }
      pageInfo {
        endCursor
        hasNextPage
        hasPreviousPage
        startCursor
      }
    }
  }
}

Your choice of method will depend on the GraphQL implementation of your endpoint. In our example, we have used the GitHub GraphQL endpoint which supports cursor-based pagination.

🥳

We are pretty excited for GraphQL in Appsmith and can’t wait to see how you use the feature for your apps. You can’t wait either to get your hands on it?

What’s next

We look forward to learning from your experience, closely listening to your feedback, and informing our roadmap. Here’s what’s coming down the pike.

A GraphQL schema explorer like GraphiQL

  • This will save you hours in switching between Appsmith and another GraphQL explorer like GraphiQL, so pretty exciting as the next-big-what but we will be deliberate in baking this into the native Appsmith experience.

Auto-complete for GraphQL schema attributes and fields

  • To improve dev productivity, we will extend auto-complete’s power to your GraphQL attributes and fields, so you can do away with going to your GraphQL schema each time you write a query.

Multiple GraphQL queries in the same request body

  • Despite GraphQL running each query separately, there’s significant value to being able to write as many queries as you want to in the same request.
Disappearing watermarks, powerful auto-complete, and more
5
September
2022
Monthly Round-up

Disappearing watermarks, powerful auto-complete, and more

Disappearing watermarks, powerful auto-complete, and more
Vihar Kurama
0
 minutes ↗
#
widgets
#
community
Monthly Round-up

In August, we let you turn off the Appsmith watermark, moved to Kubernetes-based deployments for reliability, turned widgets 40% faster, and made a bunch of usability updates. We also leaked a few preview screens for GraphQL as a datasource and we will announce availability of v1 anytime now. All in all, a feature- and performance-packed month.

Let’s recap.

#BigThings

Charts’ turn to say hello to Theming

You have used Themes with the new table, the Button, and the container widgets. In August, we brought theming to charts, too. Line, bar, and pie, our default charts, now follow the theme you set for your apps.

#didyouknow we also support Fusion Charts natively in Appsmith. Learn how to use them in your apps here.

Powerful upgrades to auto-complete

Auto-complete now knows your variables within widgets and across JS Objects.

  • It now remembers local variables and also shows where you used them.
  • It doesn’t trip up on the Select, Button Group, and CheckBox widgets like it did before.
  • It also behaves more consistently on forms when you use mustaches.

Peek-a-boo watermarks

For those of you who have put your money where your app is and still see the Appsmith logo, head over to your Admin page, check "Hide", and watch the watermark disappear. While you are at it, consider turning telemetry on so we can build and ship better. Win-win.

Updates from Project Reskinning

  • Radio, Toggle, and Checkbox, useful and popular widgets, are now themed.
  • Your labels on the Rich Text Editor widget have moved out of the Property Pane and are now available on the widget itself.
  • Widget properties on the Property Pane are now grouped by content, style, and events.

#UpdateThings

Controlled sync functions

There was a time when a function first written aync and then turned sync used to run on page load. That doesn’t happen anymore.

Securing your embeds

With great usability, comes great responsibility. So, while we now let you embed your apps in all domains by default, we recommend you don’t use this option and carefully allow domains and sub-domains to embed your apps.

Sun setting real-time commenting

While v1.7.13 is now sunsetted, we are excited about the future of collaboration inside Appsmith and will come back with a collaboration suite that addresses a range of your collab use cases.

#UpcomingThings

Native GraphQL support

Your days without native GraphQL support inside Appsmith are numbered. Very soon, GraphQLphiles can use the query language as a supported datasource and write their queries like you would a REST API query.

We will follow up with more soon.

Improve Customer Experience, Enable Sales Inquiries with Twilio and Appsmith
17
August
2022
Tutorial

Improve Customer Experience, Enable Sales Inquiries with Twilio and Appsmith

Improve Customer Experience, Enable Sales Inquiries with Twilio and Appsmith
Vidushi Gupta
0
 minutes ↗
#
sales
#
customer communication
#
whatsapp
#
sms
#
messaging
Tutorial

Twilio provides programmable communication tools for making and receiving phone calls, sending and receiving text messages, and performing other communication functions using its web service APIs. In this tutorial, we will show you how to build a customer messaging platform using Twilio and Appsmith. 

This tool can help organizations communicate with users about a new feature launch, sales inquiries, support queries, and welcome messages. 

You can also access this tool as a forkable template. Use this link to follow along or make your changes.

With this app, you can:

  • Select a set of customers from the table of customers.
  • Select a message from a list of messages that can be sent to a customer. 
  • Customize the message that is to be sent to a customer. 
  • Send an SMS or a WhatsApp message to the selected customers via the Twilio integration.
  • Manage customer contacts

Getting Started

Setting up Appsmith 

  • Head onto appsmith.com to sign up for a new account or log in to an existing account.
  • Create a new application in your preferred organization, and you’ll now see an editor where you can drag and drop UI widgets to build UI.

Set up UI for your app

  • Select a theme you enjoy!

Now, add the following widgets for the UI:

  • A container for the app's header that includes an icon button and a text widget.
  • A container with a table of customers and a text widget for the headline.
  • A container for the message form that has two button widgets, a rich text editor, a text widget, and a select field.

That concludes the UI. In only four easy steps, you build up the UI for your app🎉 Here's how it looks:

Connecting with data sources and customizing the UI

For building this app, we use the following tables: 

  • Customer table: This table contains the details of the customer. The attributes of this table are customer ID,  full name, SMS contact number, and WhatsApp number. 
  • Sample Messages table: This table contains sample messages for the organization to choose, customize, and send to the customer. The attributes of this table are Message type and Message text.

To customize the UI:

  • Title the container on the left with ‘Customers’
  • Bind the data of the customer table on the table widget. 

Write a selectQuery in a new query to see the customer's table. 

select * from customers

To bind the data from the selectQuery, write {{selectQuery.data}} in the Table Data field on the property pane of the Table widget.

  • Enable multi-row selection for the table from the property pane.
  • Bind the sample messages on the select widget as labels and value and display the messages in the rich text editor widget. 
  • The query {{Table1.selectedRows}} gives us a JSON with all selected customer fields. To only get the names of the selected customers, write a new JSObject.
getCustomernames: () => {
  const namesArray = Table1.selectedRows.map((row) => row.name);
  const names = namesArray.toString();
  return names;
};
  • For the container on the right, title the container with Contact {{JSObject1.getCustomernames()}}. This would show the names of the selected customers in the title. 
  • Control the visibility of the container in right by entering {{!Table1.selectedRowIndices.length==0}} in the visibility field on the property pane.
  • Label the select widget as a Message template and change the placeholder to ‘select a template.’
  • Label the two buttons as WhatsApp and SMS, respectively.

Using the Twilio integration for contacting the customer

With Appsmith’s native Twilio integration, you can easily connect Twilio to your app and send messages within minutes. To do so: 

  • Add a new Twilio Datasource from the Datasources section.
  • Rename the datasource based on your choice, and configure it withBasic Auth for the Authentication type. Enter your Account SID and Auth Token in the input fields and hit Save. 

> Note: You can find your Account SID on your account's dashboard. Check out Twilio’s Authentication docs for more information.

  • Create a new query on the Twilio datasource you just created. Name it sendSMS. Set the Commands to Create Message, and enter your Account SID and Twilio From your phone number. For the body, bind the text in the rich text editor widget on the canvas. 

To send messages to multiple users at once, you would have to iterate over the array of contact numbers of the selected customers. 

To do this, follow the below steps:

  • Write a JSObject that iterates over the array and runs the function to send the SMS repeatedly.
sendSMSFunc: async () => {
		const selectedNums = Table1?.selectedRows?.map((row) => row?.sms_number);
		selectedNums.forEach((num) => {
		sendSMS.run({num});		});
},

This method passes params to run. Check out more about it in Appsmith’s docs.

Similarly, write a similar JSObject and query for WhatsApp messaging. The only change would be to add WhatsApp: before the number.

sendWhatsAppFunc: async () => {
		const selectedNums = Table1?.selectedRows?.map((row) => row?.whatsapp_number);
		selectedNums.forEach((num1) => {
		sendWhatsApp.run({num1});		});
}
  • Bind these `JSObjects` on `onClick` function of the buttons: `{{JSObject1.sendWhatsAppFunc()}}` and `{{JSObject1.sendSMSFunc()}}`

Voila! Run your consumer messaging tool through its paces!

URL for the screen capture: https://www.loom.com/share/8f4ab7a445a24ce4a2264f3dbd73a514

We have a template that will help you get started in no time; check it out here.

Please use this form to contact us if you have any template requests for internal tools that you need, and we will get to work! 

If you have any questions, contact us on Discord. You can also keep up with us on Twitter and YouTube.

Peeking into HTTPS Traffic with a Proxy
9
August
2022
Engineering

Peeking into HTTPS Traffic with a Proxy

Peeking into HTTPS Traffic with a Proxy
Shrikant
0
 minutes ↗
#
engineering
#
security
Engineering

This article is about configuring a web application, Appsmith in this case, to run correctly behind a firewall that does SSL decryption, as a Docker container. Instead of a firewall, we’ll use a proxy, which, for the purpose of the problem statement, should be the same.

Table of Contents

Since the proxy needs to support HTTPS decryption, we’ll use mitmproxy, but Charles or any other proxy that supports this would also work just fine.

Setting up mitmproxy

Install with:

brew install mitmproxy


Now launch it using:


mitmweb --listen 9020 --web 9021

Let it run in a separate Terminal window in the background. This will also open the proxy’s web UI at http://localhost:9021. To get a console UI instead, use mitmproxy instead of mitmweb in the above command.

Let’s try running some requests through this proxy to see it’s working well. Start with:


curl http://httpbun.com/get

This should print a valid JSON as the response, with some details about the request itself. Let’s repeat this with the proxy.


curl --proxy localhost:9020 http://httpbun.com/get

You should again see the same response here, but this time, a new entry should appear in the mitmweb UI. Here, you can inspect the request and be able to see the path, headers and response of the request.

So we’ve confirmed that our proxy works. Let’s add HTTPS to the mix.

Again, same thing, but with HTTPS, without a proxy. You should see the same response as before, but without an entry in the proxy. That’s to be expected since we didn’t put a --proxy here. Let’s try that now.


curl --proxy localhost:9020 https://httpbun.com/get

This one, should also succeed, unless you’ve installed mitmproxy via a different method. Let’s see why.

The way an SSL proxy works is by establishing two SSL connections, one with the client (a browser, or curl), initiated by the client, and another with the server (the httpbun.com server in this case). Everything sent by the client is encrypted using the certificate of mitmproxy, and everything by and to the server is encrypted with the server’s certificate.

When installing mitmproxy via brew, the root certificate was automatically installed on your system, and so curl won’t complain about the certificate being unverified.

To illustrate this, we can run the same thing in a container, and we should see the error right away:


docker run --rm alpine/curl --proxy host.docker.internal:9020 https://httpbun.com/get


At this, you should see a certificate validation error. This is because the root certificate of mitmproxy isn’t installed inside the container’s environment, and so the curl invocation inside, won’t be able to verify mitmproxy‘s certificate.

To confirm that this is indeed because of mitmproxy, run the same docker run command without the --proxy host.docker.internal and you won’t see this error, despite running with https.

Now we’ve reproduced the situation where a process (a web server in our case), inside a Docker container, is trying to run behind an SSL-decrypting firewall (or, an SSL-decrypting proxy in our case here). Let’s see what we can do to get this to work.

Setting up

For our adventure here, we’ll use the Docker image of Appsmith, located at https://hub.docker.com/repository/docker/appsmith/appsmith-ce.

Let’s start a temporary Appsmith container with:


docker run --rm -d --name ace -p 80:9022 appsmith/appsmith-ce


Once this is ready, you should be able to access your Appsmith instance at http://localhost:9022.

Let’s try to run some curl requests inside this container, and get them to go through our mitmweb proxy.


docker exec ace curl --proxy host.docker.internal:9020 http://httpbun.com/get


This should work fine, and the request should show up in the proxy UI with full details as well. Now let’s do the same thing with https.


docker exec ace curl --proxy host.docker.internal:9020 https://httpbun.com/get


Let’s copy the root certificate into the container. For mitmproxy, the root cert is generated at first start, and is located at ~/.mitmproxy/mitmproxy-ca-cert.pem, going by the docs at https://docs.mitmproxy.org/stable/concepts-certificates/#the-mitmproxy-certificate-authority.


docker cp ~/.mitmproxy/mitmproxy-ca-cert.pem ace:/


With this command, we are copying the root certificate of mitmproxy into the container, into the root folder. Let’s run the same curl command now, providing it this root cert:


docker exec ace curl --proxy host.docker.internal:9020 --cacert /mitmproxy-ca-cert.pem https://httpbun.com/get


Now we’ll see the correct response, as well as full details of this request in the proxy UI.

Setting proxy on the whole container

We’re now at the point where it’s possible for requests inside the container to be run via the proxy, without any cert validation errors.

But this currently needs to be deliberate. Like in the example above, the curl command needs the cert to be specified explicitly. Instead, we’d like even ordinary curl commands to always go through the proxy, since, that’s how a firewall would work, and ultimately, that’s what we are trying to reproduce here.

Let’s stop the ace container and start it again with proxy configuration set.


docker stop acedocker run --rm -d --name ace -p 80:9022 \    -e HTTP_PROXY=http://host.docker.internal:9020 \    -e HTTPS_PROXY=http://host.docker.internal:9020 \    -e http_proxy=http://host.docker.internal:9020 \    -e https_proxy=http://host.docker.internal:9020 \    appsmith/appsmith-ce


Yep, that’s right. We need to set both http_proxy and HTTP_PROXY for all applications inside the container to take it seriously. 🤦

Let’s run a normal curl request on this container to see if the proxy settings are applied:


docker run ace curl http://httpbun.com/get

If the proxy configuration is working, then you should see this request appear in the proxy UI. Also for https URLs:


docker run ace curl https://httpbun.com/get

This, as we can expect, fails due to a cert validation error, since it’s using the proxy, but the proxy’s certificate can’t be verified. We can provide the root cert of mitmproxy using the --cacert argument, but we want it to apply to all requests in the container, without such explicit configuration, so we won’t do that.

Instead, we want to install the root certificate of mitmproxy to the truststore, so that it’s available to all processes in the container for validating SSL certificates.

How this is done, depends on the operating system, but in our case, since the container is Ubuntu, all we need to do is:

  • Copy the certificate file to /usr/local/share/ca-certificates.
  • If the cert has the .pem extension, rename it to use the .crt extension. This is because Ubuntu’s update-ca-certificates command only picks files with a .crt extension.
  • Run update-ca-certificates.

Let’s copy the root cert into the container, and install it by running the above commands inside the container:


docker cp ~/.mitmproxy/mitmproxy-ca-cert.pem ace:/usr/local/share/ca-certificates/mitmproxy-ca-cert.crtdocker exec ace update-ca-certificates


The output should say that one certificate has been added to the truststore.

Let’s run the same https request again:


docker exec ace curl https://httpbun.com/get


This should now print the correct response, as well as show up on the proxy UI with full details for inspection. 🎉

Conclusion

This has culminated in creating the PR #14207. This PR contains a fer QoL improvements over the solution above.

  1. We install ca-certificates-java, so that when we run update-ca-certificates, they are also installed into the JVM truststore. This is important since, one, Java maintains its own truststore (like Firefox), and two, Appsmith’s server runs on the JVM so we need this there as well.
  2. We provide support for a ca-certs folder in the volume, where users can drop any root cert files which will be auto-added on container startup.
  3. We run update-ca-certificates --fresh instead of just update-ca-certificates, so that any cert file removed from the ca-certs folder, also gets removed from the truststores.
  4. We mix up values of the proxy env variables, so that setting just one of http_proxy and HTTP_PROXY would be enough. This is also done for https_proxy and HTTPS_PROXY.
  5. We provide a friendly warning when there’s .pem files in the ca-certs folder, since, most likely, they are there because the user forgot to rename them to use the .crt extension.
  6. The JVM needs the -Djava.net.useSystemProxies=true to use the system configured proxy. Additionally, we also set the individual proxy configuration as additional system properties, so we can apply them when executing requests via Apaches’ web client libraries. Since, well, that library doesn’t respect system proxy configuration, although the rest of JVM does. Go figure.
  7. We set a NO_PROXY env variable to hosts that should not go through the proxy, like localhost and 127.0.0.1.

Of course, considering our premise, which is to be able to use Appsmith behind an SSL decrypting proxy, all a user needs to do, is to place the firewall’s root certificate in the ca-certs folder, and restart the Appsmith container.

Bonus: Using Charles

Notes on using Charles instead of mitmproxy.

Install with:


brew install charles


Open Charles

Go to Proxy -> SSL Proxying Settings, under “SSL Proxying”, add a few domains you want SSL decryption to be done. Let’s add an entry under “Incude”, with host set to httpbun.com and port set to 443 (which is the default port of HTTPS).

Check with http curl, response should show up correctly, and the request should show up in Charles with full information.

Check with https curl, get an error response back, and the request should show up in Charles with incomplede information, and a red error icon.

To get the Charles’ root certificate, go to Help -> SSL Proxying -> Save Charles Root Certificate.... Provide a location to save this cert, like your home folder.

The other steps should be the same as explained above for mitmproxy.

Build an Invoice Approval Inbox with Xero
8
August
2022
Tutorial

Build an Invoice Approval Inbox with Xero

Build an Invoice Approval Inbox with Xero
Luke Arran
0
 minutes ↗
#
databases
Tutorial

In the previous chapter, ‘How to Connect the Xero API to Appsmith’ we created an Appsmith application which connected to your Xero account through the oAuth API and displayed a list of invoices on a table. In this chapter, we’re going to extend that application further by adding actions to enable the user to approve an invoice. The previous chapter is available here in the news and resources section of the Tick 9 website.

Requesting New Permissions

Up to now, we created a read-only Xero application, however in this chapter we’ll be writing changes back to your Xero account. So, we’ll need to request additional permissions from Xero.

Under ‘Datasources’ on the left-hand side of Appsmith, click on your Xero API connection and press the ‘Edit’ button on the top-right. In the ‘Scopes’ field, simply update the value with the below:

openid,

accounting.transactions,

profile,

offline_access,

accounting.contacts.read,

email

Then, click on the “Save and Re-Authorize” button to reauthorize with Xero with the additional permissions enabled.

Cleaning Up

This image has an empty alt attribute; its file name is CleanShot%202022-03-21%20at%2013.57.05.gif

If you’re following from the previous chapter, when you bind an array of objects to a table, it will by default, display every field from the objects in the array. So let’s clean this table by hiding the columns we no longer need.

In the ‘Edit’ mode, click on the table on the page, and under ‘Columns’ press the button on the far right to hide columns you don’t need.

Now you’ve tidied up the columns, do you want to display every invoice, or only the invoices which are awaiting approval? If you require the invoices only needing approval, go over to the getInvoices query, select the Params , create a new row with the name Statuses with the value DRAFT,SUBMITTED . Once you re-run the query you will find that the table will show only the invoices which require approval.

Creating an Action Menu

This image has an empty alt attribute; its file name is Screenshot%202022-03-21%20at%2014.14.24.png

Whilst selecting the table, on the right hand side, go to the bottom of the ‘Columns’ list and click on ‘Add a New Column’. Then, under the ‘Column Type’ menu, select the item ‘Menu Button’.

On our menu, the user will have a choice of two actions, ‘Authorize’ which will set the status of the invoice as ‘AUTHORIzED’ in Xero, and ‘View Line Items’ which will open a dialog for the user to view the individual line items of the selected invoice.

You may choose the customise your menu item further by setting an icon, background and text colours.

Viewing Line Items

This image has an empty alt attribute; its file name is Screenshot%202022-03-21%20at%2014.22.25.png

Next up, let’s create the dialog which will appear when the user clicks on the ‘View Line Items’, go back to the ‘Widgets’ section on the left hand side and drag-and-drop a ‘modal’ widget and give it a name (e.g lineItemsDialog). Then, within the same modal, drop a ‘table’ widget inside of it. Once placed comfortably within the dialog, bind the table to the following data source {{invoiceTable.selectedRow.LineItems}} . This will now display the list of line items on the table.

Now, let’s make the dialog open when we click the menu option, go back to your main table widget on the page and find the menu column you just created. Go to the ‘View Line Items’ menu option, under the onItemClick menu option, select Show modal and then click on the dialog you created (e.g lineItemsDialog).

Great, deploy your application and try out the dialog you just created.

Approving an Invoice

Let’s now connect up the ‘Authorize Invoice’ button to an API action, so when you click on the button, it will send the request to the Xero API to change the status of the invoice to the ‘AUTHORIzED‘ type.

On the left-hand side, click on ‘Add Query/JS’ and select on ‘New Xero Query’. Set the name approveInvoice and set POST as the HTTP action. In the URL field, we want to bind the selected Invoice ID to the query – so paste the following:

https://api.xero.com/api.xro/2.0/Invoices/{{invoiceTable.selectedRow.InvoiceID}}

Then we need to apply the same standard headers to inform Xero of the organization, and the type of data we’re sending/receiving.

This image has an empty alt attribute; its file name is Screenshot%202022-03-21%20at%2014.54.44.png

Next, click on the ‘Body’ tab, select the ‘JSON’ switch and paste the below JSON body. This will provide Xero with the fields which we’re changing, in our case, the status of the invoice.

{ "Status": "AUTHORIZED"}

Then, click on the ‘Settings’ tab and enable ‘Request confirmation before running API’ – this will prevent accidental approval of invoices, by confirming with the user before committing to the action.

Finally we need to wire up the button on the table menu to the API action. Return to your page, select on the table and find your ‘Action’ column. In the ‘Authorize’ menu option, click on the JS button alongside the onItemClick label and paste the below JavaScript.

{    {        approveInvoice.run(            () => {                showAlert('Great, your invoice was approved!', 'success');                getInvoices.run();            },            () => {                showAlert('Oops! An error occured. Please check your API connection and try again.', 'error');            }        )    }}

Let’s break-down what this code snippet is doing. When the user clicks on the menu button, it will run the approveInvoice query. In the first argument, the code is executed when the request was successful, so we’ll display a notification to the user informing them of the successful action, and then refresh the getInvoices query. The second argument will execute on failure, in this case, display a notification to the user that an error has occurred and that they may want to try again.

This image has an empty alt attribute; its file name is CleanShot%202022-03-21%20at%2015.09.09.gif

Great, that’s it! If everything has gone to plan, you should be able to deploy the application, click on the menu and approve an invoice on the table.



Thank you for reading! If you’ve got any questions, or have an issue following this guide, then please don’t hesitate to reach out by emailing luke@tick9.co.uk.

Connect Xero API to Appsmith
8
August
2022
Tutorial

Connect Xero API to Appsmith

Connect Xero API to Appsmith
Luke Arran
0
 minutes ↗
#
databases
Tutorial

In this guide – we’ll walk you through connecting your Xero account to Appsmith to create an application around its data.

Setting up Appsmith

Appsmith can be downloaded and hosted within your local business network. But this guide won’t cover the installation process; if you want to try Appsmith, you can use the cloud service provided by Appsmith or speak with a member of our team for advice on installing Appsmith within your local network.

Open Appsmith, create a new application called “Xero – Invoices,” and click “Build with drag & drop.” You’ll see an empty page with “Drag and drop a widget here.” We now need to connect Appsmith to your Xero API account.

Step 2) Setting Up the Data Source

On the left-hand side of Appsmith – you’ll find a toolbar combining “Widgets,” “Queries/JavaScript,” and “Data Sources.” Let’s start by connecting to your business account on Xero through the Xero API.

Click on the plus button to the right of “Datasources” and then select “Authenticated Account”. Appsmith will now create a new REST API datasource within your application. But before using it, we need to configure the datasource to communicate with Xero’s OAuth Authentication correctly.

  1. In the URL field, paste the base address of Xero’s API (https://api.xero.com/).
  2. Click on the Authentication Type dropdown, and select OAuth 2.0.
  3. Scroll down to Grant Type and select Authorization Code.
  4. Within the Access, Token URL field, paste the followinghttps://identity.xero.com/connect/token.
  5. We now need to provide the scope of our API access. In this guide, we’ll need to access our organization's contacts and accounting data. So paste the following values into the field OpenID, offline_access, accounting.transactions.read,profile,accounting.contacts.read,email.
  6. Within the Authorization URL, paste the following https://login.xero.com/identity/connect/authorize.

In order to get our Client ID and Client Secret – we need to make a quick diversion to Xero. Head over to the following link and click on the blue “New App” button once logged in. Give your application a name (e.g., Northwinds Appsmith), and then paste your generated “Redirect URL” from Appsmith into the box at the bottom.

Once created, go into the registered application and select “Configuration” on the left-hand side. Take note of the Client ID and Client Secret (if you don’t have one, click on the generation button). Now return to Appsmith and paste these values into the respective fields.

We should now be ready to authorize your access with Xero. Simply click on the “Save and Authorize” button at the bottom of the page and wait a few moments until you’re redirected to Xero (as shown in the screenshot above). Select the organization you want to grant access to, and click “Allow access.” You’ll then be taken back to Appsmith.

Step 3) Selecting Your Organization

Now you’ve successfully connected Xero to Appsmith – we can retrieve data from your Xero account. Let’s begin by getting the information of organizations from your Xero account.

On the left-hand side of Appsmith – click on your data source (e.g. Xero API) and click on New API +. You’ll now be taken to Appsmith’s query editor for REST APIs. In the URL bar, type in /connections after the URL. Appsmith will automatically handle the oAuth 2.0 authentication in the background and populate the request with the required headers. Once you click the Run button, you’ll see the JSON response from your request at the bottom of the page. It should contain an array of objects listing the Xero organizations you’ve granted access to.

Let’s now create a drop-down list on your application so that your users can select the organization which they want to view data from. On the left-hand side, under “Pages” select on the first page (e.g Page1) and then click on Widgets .

Click on your widget, and within the Options code block we need to bind the values from our API response to the Select widget. Some JavaScript code may have already been populated, which creates an array of items with two values for the widget, a label value to be displayed to the user and the value which should be the ID of the organization. Paste, or enter the below code into the Options block.

.
{{getTenants.data.map( (obj) =>{ return  {'label': obj.tenantName, 'value': obj.tenantId } })}}

Before we move onto the next stage, make sure to provide the widget with a name (e.g tenantSelect – we will need to reference back to the widget in our next query!

Step 4) Getting Invoice Data

Let’s now retrieve the invoice data from your Xero account! On the left-hand side, click on your Xero datasource and click on New API+. Name the query getInvoices and press return.

In the URL bar, enter /api.xro/2.0/Invoices after the base address.

Under the Headers tab, we need to specify the organization in Xero which we want to pull back the invoices for. You’ll see two rows under this tab, under Key 1 enter Xero-tenant-id and then in Value 1 we need to bind to the selected value from the drop-down we previously placed on the page.

Enter the value

{{tenantList.selectedOptionValue}}

Next, we need to tell Xero that we want the API to respond with JSON, and not XML which is the default behaviour. To do this, simply enter Accept in the next row under the Headers tab, and enter application/json .

Now press “Run”, and if everything has gone to plan – the API would have responded with a list of invoices from your Xero account.

Step 5) Displaying Invoice Data

We’ve now created a query which retrieves invoice data from your Xero account, but let’s now create a table which will display the list of invoices.

On your page, drag and drop a button next to the select button. In the Label field, give the name Refresh . When we click this button, we want Appsmith to execute the getInvoices query which we created in the previous stage – so under Events on the right-hand side, click on the drop-down under onClick and select getInvoices under Execute a query . Then let’s display a useful alert to the user informing them that the data has been refreshed, under onSuccess click on Show message and enter Successfully retrieved invoices from Xero .

Next, find the Table widget and place it on your page. Give the widget a useful name, such as invoiceTable . Then the right-hand side, under Table Data bind to the array of invoices from the API response by entering the following value {{getInvoices.data.Invoices}} . After a few moments, the table will display the list of invoices from your Xero account.

However, this will only display the first page of invoices from the Xero API which is limited to 100 records. In order to display all your invoices, you will have to enable server side pagination – on the right-hand side, scroll down to Server Side Pagination and make sure this switch is enabled.

Return to the getInvoices query – under the Pagination tab select on Paginate with Table Page No . And then go to the Params tab, under Key 1 enter page , and then in the value input bind to the current page of the table with the following value {{invoiceTable.pageNo}} .

Then back on the table widget, run the getInvoices query when onPageChange is triggered. Once this has been enabled you can click on the right arrows at the top of the table to navigate through all your invoices.

Next Steps

That’s it for this article! Click on the “Deploy” button at the top-right to see the the final version of your application.

In the next article, we’ll delve further into how we can modify our application to write changes back to Xero.