DEV Community

Cover image for Sailing the TypeScript Seas: My Adventure Adding File Upload Validation to React Chatbotify
Tasbi Tasbi
Tasbi Tasbi

Posted on

Sailing the TypeScript Seas: My Adventure Adding File Upload Validation to React Chatbotify

Ahoy, fellow coders! ๐Ÿดโ€โ˜ ๏ธ

Have you ever felt like a pirate setting sail on the vast ocean of code, only to realize you're navigating a storm without a compass? That's exactly how I felt when I embarked on my latest coding adventure: adding file upload validation to the React Chatbotify input-validator plugin.

As someone who can code in JavaScript in my sleep but is still getting acquainted with TypeScript, I knew I was in for a wild ride. But hey, what's life without a little challenge, right?

Grab your favorite beverage (mine's a cup of coffee with a splash of excitement), and join me as I recount my journey through TypeScript, React Chatbotify, and the quirks of file upload validation. Let's dive in! ๐ŸŒŠ


Chapter 1: Setting Sail Without a Map ๐Ÿ—บ๏ธ

The Quest Begins

It all started when I decided to contribute to the React Chatbotify Plugins repository. The issue at hand was straightforwardโ€”or so I thought:

Add support for file upload validation (Issue #1)

The plugin currently supports text input validation, but there's a need to validate file uploads as well. "Simple enough," I mused. Little did I know, I was about to enter uncharted waters.

Lost in Documentation
First things first, I needed to understand how React Chatbotify and its plugins work. I dived into the documentation and explored the react-chatbotify GitHub repo.

As someone who hadn't worked with plugins before, I felt like I was reading hieroglyphs. But with patience and copious amounts of caffeine, I began to piece together how everything fit.


Chapter 2: The Mysterious Case of the Missing Plugin ๐Ÿ•ต๏ธโ€โ™€๏ธ

Writing the Validation Logic
I rolled up my sleeves and started coding the file upload validation logic. I added a new event listener for rcb-user-upload-file in the useRcbPlugin hook:

window.addEventListener("rcb-user-upload-file", handleUserUploadFile);

  return () => {
    window.removeEventListener("rcb-user-upload-file", handleUserUploadFile);
  };
Enter fullscreen mode Exit fullscreen mode

Feeling confident, I fired up the app to test it out. And... nothing happened. The file upload wasn't working at all.

The "Aha!" Moment

After hours of frustration and questioning my life choices, I realized that I hadn't actually called the plugin in my main app. ๐Ÿคฆโ€โ™‚๏ธ

Here's what I was missing in App.tsx:

import ChatBot, { Flow } from "react-chatbotify";
import RcbPlugin from "./factory/RcbPluginFactory";

const App = () => {
  // Initialize the plugin
  const plugins = [RcbPlugin()];

  // ... rest of the code
};

export default App;
Enter fullscreen mode Exit fullscreen mode

Once I added the plugin to my app, the file upload functionality sprang to life. Lesson learned: Always remember to include your plugins, folks!


Chapter 3: The Validation Conundrum ๐Ÿงฉ

Adding File Validation Logic
With the plugin properly invoked, I set out to write the file validation logic. I created a separate function validateFile:

// validateFile.ts

import { ValidationResult } from "../types/ValidationResult";

export const validateFile = (file?: File): ValidationResult => {
  const allowedTypes = ["image/jpeg", "image/png"];
  const maxSizeInBytes = 5 * 1024 * 1024; // 5MB

  if (!file) {
    return {
      success: false,
      promptContent: "No file uploaded.",
      promptDuration: 3000,
      promptType: "error",
    };
  }
Enter fullscreen mode Exit fullscreen mode

I thought I had everything sorted out. But then, another problem reared its head.


Chapter 4: When Validation Goes Rogue ๐Ÿดโ€โ˜ ๏ธ

The Unexpected Behavior
Upon testing, I noticed that the text input validation wasn't working properly. When I typed in text, it was being blocked by the file upload validator. Wait, what?

This wasn't supposed to happen. The validateFileInput should only apply to file uploads, not text inputs.

Seeking Guidance
Stumped, I reached out to the plugin owner and showed them a screen recording of the issue. They pointed out that the validators were overlapping and suggested that the validateTextInput and validateFileInput should be independent of each other.

They also recommended adding a chatDisabled property to control when text input should be disabled.


Chapter 5: Righting the Ship โš“

Separating the Validators
I made changes to ensure that each validator only handled its respective input type.

  • Updated InputValidatorBlock Interface:
// InputValidatorBlock.ts

export interface InputValidatorBlock extends FlowBlock {
  validateTextInput?: ValidatorFunction<string>;
  validateFileInput?: ValidatorFunction<File>;
  // ... rest of the properties
}

Enter fullscreen mode Exit fullscreen mode

Testing Again

With these changes, I ran the app once more. Success! ๐ŸŽ‰

Text inputs were validated using validateTextInput.
File uploads were validated using validateFileInput.
Users could provide a URL or upload a file, offering flexibility.

Challenges Post-PR

Once my pull request was submitted, it underwent a rigorous review process. Several changes were requested by the plugin owner, which was both educational and, at times, exhausting. Here are some of the significant updates I made based on the feedback:

Emotional Rollercoaster

Each round of feedback was a mix of "aha moments" and "why didn't I think of that?" While the process was tiring, it pushed me to improve the quality of my work. Ultimately, the back-and-forth discussions helped me gain a deeper understanding of the plugin's architecture.


Chapter 6: Key Takeaways ๐Ÿ“

What I Learned

  1. The Value of Reviews: Code reviews are not just about pointing out mistakesโ€”they're about collaboration and improvement. I came out of this process with a sharper eye for detail.

  2. Patience Pays Off: Open-source contributions can be challenging, especially when you're new to the technology stack. Taking time to absorb feedback and iterate on your work is essential.

  3. Typescript Confidence: This project significantly boosted my confidence in TypeScript. Understanding interfaces, custom types, and type-safe validation was a steep but rewarding learning curve.


Chapter 7: Challenges Faced ๐Ÿ”๏ธ

TypeScript Trials

Being new to TypeScript, I found myself wrestling with type definitions and interfaces. Understanding how to define and use custom types like ValidationResult and ValidatorFunction was a steep learning curve.

Event Handling Headaches

Handling custom events like rcb-user-upload-file required a deep dive into the event system of React Chatbotify. Ensuring that event listeners were added and removed correctly was crucial to prevent memory leaks and unexpected behavior.

Fatigue from Iterations

The repeated back-and-forth for changes in my pull request was draining. While it improved the quality of my work, it also tested my perseverance.


Chapter 8: Wrapping Up ๐Ÿ›ณ๏ธ

Contributing to the React Chatbotify plugin was a rewarding experience. Despite the challenges, I walked away with valuable skills and a deeper appreciation for open-source development.

You can explore the pull request here and view the full commit history. I hope this story inspires others to dive into open source, even if the waters seem intimidating at first.


Final Thoughts ๐Ÿ’ญ

Thanks for joining me on this journey! I hope my experiences can help others who might be navigating similar waters. If you have any questions or want to share your own coding adventures, feel free to leave a comment below.

Happy coding! ๐Ÿš€

Top comments (0)