One place where AI code assist helps

How AI can assist you with obscure libraries

AI coming to the rescue when using poorly documented libraries

19th Oct 2024

aitypescriptangular

Introduction

Coding assistants like ChatGPT and Claude get a lot of bad rep in the developer community. However, I recently found that they're incredibly good at helping you work with obscure libraries that aren't well documented. In this short article, I'll explain how ChatGPT helped me overcome a really strange bug. This all begins with a project I'm working on that uses the ngx-intl-tel-input library.

The bug

Our site helps people send mobile credit to their relatives in Africa. However, we had this mysterious bug where when users paste numbers such as +211 921 123 125, it gets sent to the backend as +21192112312. All the spaces are removed, but more importantly, the last digit, 5 is cut off. This seems to be caused by having spaces in the original number. This caused issues at the backend because we trusted this library to handle this edge case, but it didn't. The library provides other useful features such as correctly appending the area code, stripping away +, and validating number length and which number formats are valid for that country.

This is what the bug looked like, as you can see we are missing that last digit. We expect 12 numbers. Figure 1. Bug

The Fix

The first round of assistance with ChatGPT was to give me the code that listens for paste events on the telephone number input and removes all the spaces. However, after adding the below code to my ngAfterViewInit:

 this.phoneInputElement = this.phoneInputFormElement?.nativeElement.querySelector('#phoneInput');
fromEvent<ClipboardEvent>(this.phoneInputElement, 'paste')
  .pipe(
    map((event: ClipboardEvent) => {
      event.preventDefault();
      const pastedPhoneNumber = event.clipboardData?.getData('text') || '';
      const cleanedPhoneNumber = pastedPhoneNumber.replace(/\s+/g, '');

      const inputEl = this.phoneInputElement;
      const startPos = inputEl.selectionStart;
      const endPos = inputEl.selectionEnd;

      return { cleanedPhoneNumber, startPos, endPos };
    }),
    takeUntil(this.destroyed$)
  )
  .subscribe(({ cleanedPhoneNumber, startPos, endPos }) => {
    const currentValue = this.phoneInputElement.value;
    this.phoneInputElement.value =
      currentValue.substring(0, startPos) + cleanedPhoneNumber + currentValue.substring(endPos);
    const newCaretPos = startPos + cleanedPhoneNumber.length;
    this.phoneInputElement.setSelectionRange(newCaretPos, newCaretPos);
  });

There was strange behavior - validation was not being run, so my continue button was not appearing that lets users go to the next page to choose how much they want to send. So I went back to ChatGPT and told it that I need the library to trigger revalidation after text is pasted, and voilà! It delivered. It found that I needed to do something like this:

   this.phoneForm.get('phone')?.setValue(cleanedPhoneNumber);
   this.phoneForm.get('phone')?.updateValueAndValidity();

I added it to the subscribe callback above and everything worked. I looked online for documentation about this, but there was none. The README for the project is very shallow.

Conclusion

AI is not perfect. However, when it comes to finding documentation or working with obscure libraries like ngx-intl-tel-input, it can be immensely useful. You might question why not just roll out your own input component that does all of this. The answer is obvious: I needed to move fast with this application, and so I paid the price of relying on someone else's code. Sure, we could have also replaced it, but then we had the sunk cost of having written so much code around it.

One of the downsides with AI is that it might have just offered you this solution, but a few months later, a new bug may arise, so you are constantly left fixing bugs and defects which may hurt your ability to ship new features and keep your customers happy. Nonetheless, AI chatbots like ChatGPT and Claude can be helpful when you're working with libraries that lack clear documentation. It's easy to find examples for what you're trying to do because they've scoured the internet and seen some of these examples.