Unleashing the Power of JavaScript in Bubble.io Backend Workflows: A Case Study
Tags: bubble, nocode, javascript, regex
Published: 2023-05-30 13:09:53

Integrating advanced features in Bubble.io, a no-code tool for creating web applications, can occasionally present challenges. This article illustrates one such challenge, and how JavaScript was leveraged to overcome it, enhancing both the frontend and backend workflows of a Bubble.io application.

**The App and Its Features:**
My social networking application allows users to publish posts and leave comments on each other's posts. These features enable dynamic user interaction, keeping the platform engaging and alive.

**Implementing the Tagger Plugin:**
To enhance user interaction further, I sought to introduce a 'mentions' feature, allowing users to tag their colleagues within their comments. To achieve this, I implemented the Tagger plugin (https://bubble.io/plugin/tagger-1507658968231x782106515828375600) which attaches to any input, enabling users to select and tag their colleagues from a dropdown list.

![How the comments look before posting](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/agm1h824f7qer355fdw8.png)

**Implementing Frontend JavaScript:**
Despite implementing the Tagger plugin, Bubble would not save tags as clickable links (without using other other plugins such as various editors for RTF that I couldn't do in my case because I needed a plain input), which was a significant limitation. To tackle this, I came up with a two-step journey to resolve this challenge:

1. Creating a Regex Pattern: The first step was to formulate a Regex pattern capable of identifying all tags in the form "@name". Here's the pattern used: "/(^|(?<=\s))@[a-zA-Z0-9+-]+(?=(\s|$)|[!?:;-=+,\.])/g".

2. Implementing JavaScript: To transform the tags into clickable HTML links swiftly and efficiently, I integrated a JavaScript code. This step proved crucial as Bubble's native solutions could not execute loops at this moment, and using a backend workflow would pose the risk of user dissatisfaction due to slower comment publishing. Note: this solution was only applicable to new comments:

```
function processText(input) {
    const regex = /(^|(?<=\s))@[a-zA-Z0-9+-]+(?=(\s|$)|[!?:;-=+,\.])/g;
    return input.replace(regex, function(match) {
        let username = match.trim().substring(1); // Remove the @ symbol
        return `<span class="mention" data-index="0" data-denotation-char="@"  style="cursor: pointer;" tabindex="">﻿<span contenteditable="false" tabindex=""><span class="ql-mention-denotation-char" tabindex="">@</span><a href="Website home URL contains version-live:formatted as textprofile/${username}">${username}</a></span>﻿</span> `;
    });
}

let processedText = processText('Comment');
bubble_fn_newtextt(processedText);

```
The result looked like this:

![How the comment looks after publishing it using the JS code to replace tags with links](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/irbdr8a379sq0wonh8ui.png)

Below see the workflow sequence to replicate the flow:

1. ![Firstly, run the JS code and save the result to varible Bubble_fn_nextextt](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/apiwlvefve1li3qc73dq.png)
2. 
![Secondly, use the toolbox JS event to save the result only after the code has been executed](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iwqhh4t7xr9yirddkx22.png)

**Upgrading Existing Comments using Backend Workflows:**
To handle thousands of pre-existing comments on the platform, I implemented a recursive backend workflow, deploying the same JavaScript code as a backend script. Here is the JavaScript code I used for the backend:

```
function processText(input) {
    const regex = /(^|(?<=\s))@[a-zA-Z0-9+-]+(?=(\s|$)|[!?:;-=+,\.])/g;
    return input.replace(regex, function(match) {
        let username = match.trim().substring(1); // Remove the @ symbol
        return `<span class="mention" data-index="0" data-denotation-char="@"  style="cursor: pointer;" tabindex="">﻿<span contenteditable="false" tabindex=""><span class="ql-mention-denotation-char" tabindex="">@</span><a href="Website home URL contains version-live:formatted as textprofile/${username}">${username}</a></span>﻿</span> `;
    });
}

let processedText = processText('comments:item #i's Text');
processedText;
```
See the backend workflow sequence:
1. ![Firstly, run the code and state the variable as the last expression to use the results in the next step](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ipmq65baxhfdqtnll5jn.png)
2. ![Use the result calculated in the first step to save into the Database](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4k2e0fw0obt04f9akgkb.png)

**Overcoming Challenges:**
The integration of JavaScript into Bubble was not without hurdles. The Toolbox plugin initially ran JS functions parallel to other Bubble workflows, disrupting the sequence. Thanks to the Toolbox plugin's JavascripttoBubble event, I was able to sequence actions, ensuring smooth execution.

**Benefits of Using JavaScript in Bubble:**
The integration of JavaScript resulted in the swift transformation of tags into clickable links, leveraging Bubble.io's no-code power, and enhancing the overall user experience. The application now offers seamless tagging functionality and an engaging user interface.

**Limitations and Risks:**
Despite its advantages, this approach does have its risks. Poorly written code can inadvertently cause server issues, potentially requiring intervention from the Bubble team.

**Conclusion:**
By judiciously integrating JavaScript with Bubble.io, we can break free from the limitations of no-code platforms and deliver an enhanced user experience. As developers, it's our endeavor to push boundaries and continue to innovate, even when confronted with challenges. Through a blend of creativity and perseverance, there's no problem that can't be solved.