9
June
2021
Tutorial

Connecting Mixpanel, Reply.io and Active Campaign using Appsmith to engage with your users

0
 minutes

Like most companies, we use analytics and marketing automation software to run our daily operations and engage with different segments of users. We use Mixpanel, ActiveCampaign and Reply.io for analytics, managing lists and automation, and email engagement.

To determine which users we need to reach out to, we have a report we run on Mixpanel. Sometimes we need to send them a simple email, and sometimes we need to send them an engaging sequence of emails. This decision is again based on the report from Mixpanel. ActiveCampaign helps us with the one-off emails, but we use reply.io for engaging and personalised sequences.

This is what the process looks like:

  • Mixpanel reports generating cohorts
  • Feed relevant cohort data to ActiveCampaign for single one-off emails
  • Feed relevant cohort data along with user specifics to reply.io for engagement

We’re still young, and we look at most users we want to engage with personally, and doing this manually every day would take a lot of time and workforce. So we ended up building a dashboard on which, with a single click of a button, we can customise and send out emails to our users.

This is what our process looks like now:

  • Look at user details in the Appsmith dashboard
  • Personalise engagement based on an app built, usage and organisation
  • Click on the button to engage the user

It saves us a LOT of time and helps us keep our core focus on our users.

In this tutorial, we’ll be walking through different steps to build such workflows with various APIs and extend them based on our use cases using Appsmith.

Appsmith is an open-source framework that lets developers build dashboards, workflows, and CRUD apps with only the necessary code. You can connect to any API or databases like MongoDB, PostgreSQL, or MYSQL and get access to multiple widgets, including charts, tables and forms, for building a UI fast.

Setting up Mixpanel API on Appsmith

Mixpanel is a product analytics tool that’ll give reports based on defined queries. It also provides API, which we’ll consume on Appsmith to pull out all the reports of users who have invited others. Now, let’s follow the below steps to set Mixpanel API as a data source on Appsmith:

  • Create a new account on Appsmith (it’s free!), if you are already an existing user, log in to your Appsmith account.
  • Next, create a new application by clicking on the “Create New” button under the Appsmith dashboard.
  • We’ll now see a new Appsmith app with an empty canvas and a sidebar with Widgets, APIs and DB Queries.
  • Now, click on the + icon next to the APIs section and choose Create new.
  • Now add the following Mix Panel API endpoint URL in the request input.
https://mixpanel.com/api/2.0
  • Click on the SAVE AS DATASOURCE button next to the URL, rename this data source as MixPanel API, and hit Save.
  • Now choose the data source and create a new API; let’s rename it asget_users, add the following route at the end of the URL: /engage?project_id=2032485. This is how our API should look like:
https://mixpanel.com/api/2.0/engage?project_id=2032485
  • Sometimes, Mixpanel APIs might be slow to process; hence we’ll have to increase the API timeout options; we can simply do this by going to the settings tab and increasing the time out to 100000.
  • Lastly, set the request type to POST and hit RUN; we should see the list of users that are inside the Mixpanel report with id 2032485
The API's and ids used in these tutorials are examples created for demo purposes. These do not depict the original data. Feel free to work with your APIs or follow along with these tutorials with the given examples.

Fantastic, we should now see the response from API having a set of users for whom we want to build customised email engagements.

In the next section, let’s show the users on a List widget and customise it based on our UI preferences.

Binding Users onto the List Widget

Let’s use the List widget to show all the invited users from the get_users API endpoint. Follow the below steps:

  • Click+ icon next to the Widgets from the left navigation and drop the List widget on canvas.
  • Now open the list property pane by clicking on the cog icon on the top-right of the list widget. Inside the property pane, we can bind the data and create necessary actions using the pre-defined properties.
  • Now paste the following code snippet into the Items property in the property pane:
{
{
  get_users.data.results.map((r) => ({
    email: r.$properties.$email,
    last_name: r.$properties.$last_name,
    first_name: r.$properties.$first_name,
    lat: r.$properties.clearbit_company_geo_lat,
    city: r.$properties.$city,
    lng: r.$properties.clearbit_company_geo_lng,
    company: r.$properties.clearbit_company_domain,
    country: r.$properties.clearbit_company_geo_country,
  })).filter(r => r.lat);
}
}

Above, we have used the moustache syntax and consumed the get_users API, which was defined previously. In Appsmith, we can use the moustache syntax anywhere, anytime and write JS to manipulations. In this case, we are returning the important variables like email, last name, location of user, company to the list.

Following is a screenshot of how the evaluated value looks like after we add in the JS:

CleanShot 2021-06-09 at 01.58.51.jpeg

Now let’s drag and drop a few text widget’s on the first list item and bind the values from the list Items property.

  • Find the text widget from the Widgets section drag and drop four of these; the first two text widgets will act as the Label’s, and the last two will act as the Values from the API.

For the first two widgets, set the values like Name and Email. Next, set the following text Values to {{currentItem.email}} and {{currentItem.first_name + ' ' + currentItem.last_name}} for the other two widgets. Now add one more text widget and customise it with a background colour such that it looks like a button; this is because whenever we click this, we can use the list’s selected item property and show the details of the selected user from the list.

Below is a screenshot of how our list widget looks now:

CleanShot 2021-06-09 at 02.07.57.jpeg

Now, let’s add a Map widget and bind the latitude and longitude to locate the user visually. Let’s follow the below steps:

  • First, find the map widget’s from the widget’s section and drag and drop a new Map Widget next to our user’s table.
  • Now, open the Map’s property and add the following JS in the Initial location property by toggling the JS button next to it:
{
    "lat": {{users_list?.selectedItem?.lat || 0}},
    "long": {{users_list?.selectedItem?.lng || 0}},
    "title": "{{users_list.selectedItem.city}}"
}

Here, we’re setting the initial tag to the latitude, longitude and title from the list widget based on the selected item using the selectedItem property.

  • We’ll also need to set the Default markers to the following:
[{
"lat": {{users_list?.selectedItem?.lat || 0}},
"long": {{users_list?.selectedItem?.lng || 0}},
"title": "{{users_list.selectedItem.city}}"
}]

This is usually an array that takes details of markers we mark on the map. We need only one marker hence adding only a single object from the selected list item. With this, we should see our map, and when an item is selected, we can see the users' location. Simple right!

Below is a screenshot of the Map widget:

CleanShot 2021-06-09 at 02.22.04.jpeg

Fetch Smartlook Recordings from Mix Panel API

In this section, we’ll add one more workflow where when clicked on a button, we should be redirected to the list-item selected user’s smart look recordings. These smart look recordings are added in a different mix panel API which is protected. Hence we’ll be using an authorization mode to access this API. Follow the below steps to follow:

  • Use the Mixpanel API data source we’ve created before and click Create new.
  • Now, add the following route to the end of the data source: /jql?project_id=2032485, this is how the API should look overall.
https://mixpanel.com/api/2.0/jql?project_id=2032485
  • Now let’s add Authorisation in the headers, copy-paste the below into the key-value pairs:

Authorization : Basic YmZkNDhhYjk1NzcxNTg4NjI0M2VhZDYyNzNhNDhlMTk6

content-type: application/x-www-form-urlencoded

  • Now, navigate to the Body tag and set the type to X-WWW-FORM-URLENCODED and add the following as a key-value pair.
Key: script
Value:
function main() {
  return Events({
    from_date: '2021-01-01',
    to_date: '{{moment().format('YYYY-MM-DD')}}',
    event_selectors: [
      {
        event: 'WIDGET_DROP',
        selector: '"{{users_list.selectedItem.email}}" in properties["$email"]',
        label: 'Invite Graph',
      },
    ],
  });
}

Awesome, this is a custom configuration for our Mixpanel Report to fetch the Smartlook recordings, you can customise this based on your report or use this as an example. Now let’s add a button below the Map widget.

Now, whenever this button is clicked, we should be redirected to the Smartlook URL of that particular users. Hence, we have to use JS to solve this. Now drag and drop a button widget beneath the map widget and set the onClick property to the following:

{{navigateTo(get_recording.data[0].properties.smartlookPlayUrl,'{}','NEW_WINDOW')}}

Here, when the button is clicked, we navigate to a new page, and the target link is the link that’s returned from the get_recording. We’ve done some additional parsing to fetch the smartlookPlayUrl property.

If the API’s are slow, we can always increase the Timeout.

Sending Customised Emails to the Users

In this section, we'll be using the APIs of reply.io to send emails to the users shown on the list.

First, let’s make a simple UI, we’ll have a button labelled, send Email when clicked these email campaign should start.

For this, we'll be needing to create two APIs; follow the steps below:

1. Fetch the Emails from Appsmith API

In this step, we'll have to fetch the profiles from the Appsmith account. Hence, we need to consume one of our Appsmit APIs and pass in the Email that's selected on the list widget.

  • First, let's create a new API called get_user and set the URL as follows:
https://appsmith.api-us1.com/api/3/contacts?email={{users_list.selectedItem.email}}
  • Here, user_list is the name of the list widget, and we're binding the selected email using the moustache API.
  • This API is secure, hence, we'll need to add an API key in header, in our case, it's Api-Token and the value is a60fdd2cb979167412b0a4daa60de8837db13f08538e7221e0d63126a7163c795eb04f7a

2. Send Email

Now, let's create one more API with reply.io to send customised Emails by clicking a button widget.

  • Create a new API and name it as send_email and set the URL as follows:
https://api.reply.io/v1/actions/addandpushtocampaign
  • In the header, we'll need to add the API keys that can found in the reply.io dashboard.
  • Now in the body, we take the inputs from the form widget and then run the API's to send the emails. Below is the JS.
{
    campaignid: 558301,
    lastName : {{users_list.selectedItem.last_name}},
    firstName: {{users_list.selectedItem.first_name}},
    email: {{users_list.selectedItem.email}}
}

Now set the button onClick property to the following JS:

{{
  get_user.run(() =>
    send_email.run(
      () => showAlert("Reached out to user", "success"),
      () => showAlert(send_email.data, "warning")
    ));
}}

Here, we’re fetching the users and sending them the Emails using a reply.io campaign that's already created!

Wrapping Up

Deploy your application on the cloud and share it with others, and that's it. We're done!

You've seen how easy it is to build a customised workflow on Appsmith. Similarly, we can integrate the number of APIs and data sources and build customised dashboards.

If you like this tutorial, drop us a star on our GitHub repository here

Connecting Mixpanel, Reply.io and Active Campaign using Appsmith to engage with your users

Share this

Like most companies, we use analytics and marketing automation software to run our daily operations and engage with different segments of users. We use Mixpanel, ActiveCampaign and Reply.io for analytics, managing lists and automation, and email engagement.

To determine which users we need to reach out to, we have a report we run on Mixpanel. Sometimes we need to send them a simple email, and sometimes we need to send them an engaging sequence of emails. This decision is again based on the report from Mixpanel. ActiveCampaign helps us with the one-off emails, but we use reply.io for engaging and personalised sequences.

This is what the process looks like:

  • Mixpanel reports generating cohorts
  • Feed relevant cohort data to ActiveCampaign for single one-off emails
  • Feed relevant cohort data along with user specifics to reply.io for engagement

We’re still young, and we look at most users we want to engage with personally, and doing this manually every day would take a lot of time and workforce. So we ended up building a dashboard on which, with a single click of a button, we can customise and send out emails to our users.

This is what our process looks like now:

  • Look at user details in the Appsmith dashboard
  • Personalise engagement based on an app built, usage and organisation
  • Click on the button to engage the user

It saves us a LOT of time and helps us keep our core focus on our users.

In this tutorial, we’ll be walking through different steps to build such workflows with various APIs and extend them based on our use cases using Appsmith.

Appsmith is an open-source framework that lets developers build dashboards, workflows, and CRUD apps with only the necessary code. You can connect to any API or databases like MongoDB, PostgreSQL, or MYSQL and get access to multiple widgets, including charts, tables and forms, for building a UI fast.

Setting up Mixpanel API on Appsmith

Mixpanel is a product analytics tool that’ll give reports based on defined queries. It also provides API, which we’ll consume on Appsmith to pull out all the reports of users who have invited others. Now, let’s follow the below steps to set Mixpanel API as a data source on Appsmith:

  • Create a new account on Appsmith (it’s free!), if you are already an existing user, log in to your Appsmith account.
  • Next, create a new application by clicking on the “Create New” button under the Appsmith dashboard.
  • We’ll now see a new Appsmith app with an empty canvas and a sidebar with Widgets, APIs and DB Queries.
  • Now, click on the + icon next to the APIs section and choose Create new.
  • Now add the following Mix Panel API endpoint URL in the request input.
https://mixpanel.com/api/2.0
  • Click on the SAVE AS DATASOURCE button next to the URL, rename this data source as MixPanel API, and hit Save.
  • Now choose the data source and create a new API; let’s rename it asget_users, add the following route at the end of the URL: /engage?project_id=2032485. This is how our API should look like:
https://mixpanel.com/api/2.0/engage?project_id=2032485
  • Sometimes, Mixpanel APIs might be slow to process; hence we’ll have to increase the API timeout options; we can simply do this by going to the settings tab and increasing the time out to 100000.
  • Lastly, set the request type to POST and hit RUN; we should see the list of users that are inside the Mixpanel report with id 2032485
The API's and ids used in these tutorials are examples created for demo purposes. These do not depict the original data. Feel free to work with your APIs or follow along with these tutorials with the given examples.

Fantastic, we should now see the response from API having a set of users for whom we want to build customised email engagements.

In the next section, let’s show the users on a List widget and customise it based on our UI preferences.

Binding Users onto the List Widget

Let’s use the List widget to show all the invited users from the get_users API endpoint. Follow the below steps:

  • Click+ icon next to the Widgets from the left navigation and drop the List widget on canvas.
  • Now open the list property pane by clicking on the cog icon on the top-right of the list widget. Inside the property pane, we can bind the data and create necessary actions using the pre-defined properties.
  • Now paste the following code snippet into the Items property in the property pane:
{
{
  get_users.data.results.map((r) => ({
    email: r.$properties.$email,
    last_name: r.$properties.$last_name,
    first_name: r.$properties.$first_name,
    lat: r.$properties.clearbit_company_geo_lat,
    city: r.$properties.$city,
    lng: r.$properties.clearbit_company_geo_lng,
    company: r.$properties.clearbit_company_domain,
    country: r.$properties.clearbit_company_geo_country,
  })).filter(r => r.lat);
}
}

Above, we have used the moustache syntax and consumed the get_users API, which was defined previously. In Appsmith, we can use the moustache syntax anywhere, anytime and write JS to manipulations. In this case, we are returning the important variables like email, last name, location of user, company to the list.

Following is a screenshot of how the evaluated value looks like after we add in the JS:

CleanShot 2021-06-09 at 01.58.51.jpeg

Now let’s drag and drop a few text widget’s on the first list item and bind the values from the list Items property.

  • Find the text widget from the Widgets section drag and drop four of these; the first two text widgets will act as the Label’s, and the last two will act as the Values from the API.

For the first two widgets, set the values like Name and Email. Next, set the following text Values to {{currentItem.email}} and {{currentItem.first_name + ' ' + currentItem.last_name}} for the other two widgets. Now add one more text widget and customise it with a background colour such that it looks like a button; this is because whenever we click this, we can use the list’s selected item property and show the details of the selected user from the list.

Below is a screenshot of how our list widget looks now:

CleanShot 2021-06-09 at 02.07.57.jpeg

Now, let’s add a Map widget and bind the latitude and longitude to locate the user visually. Let’s follow the below steps:

  • First, find the map widget’s from the widget’s section and drag and drop a new Map Widget next to our user’s table.
  • Now, open the Map’s property and add the following JS in the Initial location property by toggling the JS button next to it:
{
    "lat": {{users_list?.selectedItem?.lat || 0}},
    "long": {{users_list?.selectedItem?.lng || 0}},
    "title": "{{users_list.selectedItem.city}}"
}

Here, we’re setting the initial tag to the latitude, longitude and title from the list widget based on the selected item using the selectedItem property.

  • We’ll also need to set the Default markers to the following:
[{
"lat": {{users_list?.selectedItem?.lat || 0}},
"long": {{users_list?.selectedItem?.lng || 0}},
"title": "{{users_list.selectedItem.city}}"
}]

This is usually an array that takes details of markers we mark on the map. We need only one marker hence adding only a single object from the selected list item. With this, we should see our map, and when an item is selected, we can see the users' location. Simple right!

Below is a screenshot of the Map widget:

CleanShot 2021-06-09 at 02.22.04.jpeg

Fetch Smartlook Recordings from Mix Panel API

In this section, we’ll add one more workflow where when clicked on a button, we should be redirected to the list-item selected user’s smart look recordings. These smart look recordings are added in a different mix panel API which is protected. Hence we’ll be using an authorization mode to access this API. Follow the below steps to follow:

  • Use the Mixpanel API data source we’ve created before and click Create new.
  • Now, add the following route to the end of the data source: /jql?project_id=2032485, this is how the API should look overall.
https://mixpanel.com/api/2.0/jql?project_id=2032485
  • Now let’s add Authorisation in the headers, copy-paste the below into the key-value pairs:

Authorization : Basic YmZkNDhhYjk1NzcxNTg4NjI0M2VhZDYyNzNhNDhlMTk6

content-type: application/x-www-form-urlencoded

  • Now, navigate to the Body tag and set the type to X-WWW-FORM-URLENCODED and add the following as a key-value pair.
Key: script
Value:
function main() {
  return Events({
    from_date: '2021-01-01',
    to_date: '{{moment().format('YYYY-MM-DD')}}',
    event_selectors: [
      {
        event: 'WIDGET_DROP',
        selector: '"{{users_list.selectedItem.email}}" in properties["$email"]',
        label: 'Invite Graph',
      },
    ],
  });
}

Awesome, this is a custom configuration for our Mixpanel Report to fetch the Smartlook recordings, you can customise this based on your report or use this as an example. Now let’s add a button below the Map widget.

Now, whenever this button is clicked, we should be redirected to the Smartlook URL of that particular users. Hence, we have to use JS to solve this. Now drag and drop a button widget beneath the map widget and set the onClick property to the following:

{{navigateTo(get_recording.data[0].properties.smartlookPlayUrl,'{}','NEW_WINDOW')}}

Here, when the button is clicked, we navigate to a new page, and the target link is the link that’s returned from the get_recording. We’ve done some additional parsing to fetch the smartlookPlayUrl property.

If the API’s are slow, we can always increase the Timeout.

Sending Customised Emails to the Users

In this section, we'll be using the APIs of reply.io to send emails to the users shown on the list.

First, let’s make a simple UI, we’ll have a button labelled, send Email when clicked these email campaign should start.

For this, we'll be needing to create two APIs; follow the steps below:

1. Fetch the Emails from Appsmith API

In this step, we'll have to fetch the profiles from the Appsmith account. Hence, we need to consume one of our Appsmit APIs and pass in the Email that's selected on the list widget.

  • First, let's create a new API called get_user and set the URL as follows:
https://appsmith.api-us1.com/api/3/contacts?email={{users_list.selectedItem.email}}
  • Here, user_list is the name of the list widget, and we're binding the selected email using the moustache API.
  • This API is secure, hence, we'll need to add an API key in header, in our case, it's Api-Token and the value is a60fdd2cb979167412b0a4daa60de8837db13f08538e7221e0d63126a7163c795eb04f7a

2. Send Email

Now, let's create one more API with reply.io to send customised Emails by clicking a button widget.

  • Create a new API and name it as send_email and set the URL as follows:
https://api.reply.io/v1/actions/addandpushtocampaign
  • In the header, we'll need to add the API keys that can found in the reply.io dashboard.
  • Now in the body, we take the inputs from the form widget and then run the API's to send the emails. Below is the JS.
{
    campaignid: 558301,
    lastName : {{users_list.selectedItem.last_name}},
    firstName: {{users_list.selectedItem.first_name}},
    email: {{users_list.selectedItem.email}}
}

Now set the button onClick property to the following JS:

{{
  get_user.run(() =>
    send_email.run(
      () => showAlert("Reached out to user", "success"),
      () => showAlert(send_email.data, "warning")
    ));
}}

Here, we’re fetching the users and sending them the Emails using a reply.io campaign that's already created!

Wrapping Up

Deploy your application on the cloud and share it with others, and that's it. We're done!

You've seen how easy it is to build a customised workflow on Appsmith. Similarly, we can integrate the number of APIs and data sources and build customised dashboards.

If you like this tutorial, drop us a star on our GitHub repository here

What’s a Rich Text element?

The rich text element allows you to create and format headings, paragraphs, blockquotes, images, and video all in one place instead of having to add and format them individually. Just double-click and easily create content.

  • xvcmbmvkmnkmbknmbkmlnj
  • A rich text element can be used with static or dynamic content. For static content, just drop it

A rich text element can be used with static or dynamic content. For static content, just drop it into any page and begin editing. For dynamic content, add a rich text field to any collection and then connect a rich text element to that field in the settings panel. Voila!

  1. A rich text element can be used with static or dynamic content. For static content, just drop it into any page and begin editing. For dynamic content, add a rich text field to any collection and then connect a rich text element to that field in the settings panel. Voila!

How to customize formatting for each rich text

Headings, paragraphs, blockquotes, figures, images, and figure captions can all be styled after a class is added to the rich text element using the "When inside of" nested selector system.

ksnopirirfnb [aorewmb[oiewsn b[opebr
  1. then connect a rich text

dfbstjsrykmsry

Square
Try Appsmith
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.