Learning by Doing: ManipulateStrings

My recent widget is called ManipulateStrings. It’s an AngularJS app. The source code is here: https://github.com/xerocross/manipulate-strings. It’s actually a little more complex than it appears on first glance. You enter any string you want, and the widget has several built-in methods for manipulating a string. You can reverse the string or alphabetize the characters or do a global replacement of one substring with another. For one thing, I needed practice writing those kinds of utility functions where you treat a string as an array of characters. Substring replacement can turn into an infinite loop if you aren’t careful. Consider if you just write a function that loops over the string, always starting from the beginning, and replaces every instance of the substring “a” with the new substring “bat”. This will put you in an infinite loop.

Part of what I was practicing when I wrote this was test-driven development. I wrote an AngularJS service to do these string manipulations, and I wrote a full battery of unit tests for it, which are available in the source repo, and I wrote the tests before writing the code that satisfied them.

The widget is more interesting than just an interface for applying these string transformations. The widget doesn’t just keep track of an input string and report what happens if you apply one transform. You can apply more than one transform in whatever sequence you want, and the input string gets piped through each transform in order, and you can see all of the intermediate values after these transforms.

What’s even cooler is that the state we maintain is not a list of strings. Instead, what we maintain is the list of transforms. What this means is that you can change the input string and leave the transforms alone, and then the new input string gets piped through the same sequence of transforms. And this is live-updating.

I think this technique could prove useful in other situations. For example, you might want to pipe numbers or functions through mathematical transformations and see the result. Unlike a calculator, you can alter the input value at will and see how the result value changes automatically, immediately.

For the sake of learning something else I didn’t already know, I decided to add tooltips to this widget. I’m not a huge fan of tooltips in general. I think Wikipedia overuses them so much that there is no safe place to leave your mouse without it bringing up a message that covers what you are trying to read. But for the sake of learning, I added a few. To do that, I used the tooltip apparatus built on top of Bootstrap.

This simple task took me far afield into matters of dom manipulation and how best to do that in an AngularJS context. My main controller quickly became a mess of view logic intermingled with business logic. That’s why I brought in my good friend Redux. You rarely see AngularJS and Redux mentioned in the same breath, but they can totally work together. Redux is not react specific.

To use Redux, I used a fairly boilerplate setup. I wrote just one simple reducer function and moved all of the business logic into it. At this point, the Angular controller really only does minor things before passing the logic into my Redux reducer function using Actions. This allows for a much cleaner separation of concerns. And since the redux function has no view logic in it at all, it’s much easier to read it and understand how the app works.

Overall, this widget was a fun exercise, and I’m glad I had the idea of refactoring things using Redux and that it works well. Later, I think I will do something very similar to this widget but instead I’ll use mathematical transforms.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s