What is Joinable: A library to join strings together without the need to check if a value is a falsy like undefined.

Why use it: Keep your code base clean by removing the if else statements and improve the readability.

Joinable API in the read me on Github and is an NPM package.

In situations where you need to concat a string to form a message based on some input, you typically create logic to construct it. You might find that you repeat an if checking values are not a falsy. Joinable removes this from the function body and help towards readability. Joinable can be used for more than building messages see below for another example.

With Joinable it should be easy to construct strings like form validation messages, CSS classes, URLs and more.

What does it look like?

ES6 example

import joinable from 'joinable';

let myString = joinable('potato', null, 'rice', undefined, 'carrot'); // => 'potato rice carrot'

Falsies handled: false, 0, "", undefined, null, NaN

Example joining classNames in ReactJs with logic

Problem

Example of typical logic string concatenation in ReactJS component with if statements. General issues: verbose, unnecessary repetitive complexity and mutation:

const MyComponent = ({ children, className, hide }) => {
  let myClass = 'potato ';
  if(hide)
    myClass += 'invisible';

  if(className)
    myClass += className;

  return (
    <div className={myClass}>{children}</div>
  );
}

render(<MyComponent className="cucumber">Hello world</MyComponent>); 
// => <div class="potato cucumber">Hello world</div>
render(<MyComponent className="cucumber" hide>Hello world</MyComponent>); 
// => <div class="potato invisible cucumber">Hello world</div>
render(<MyComponent>Hello world</MyComponent>); 
// => <div class="potato undefined">Hello world</div>

While this works fine you will probably need to repeat that similar flow for a lot of components and some will have additional complexity round it.

Joinable solution

Lets hide that logic away and keep it clean with joinable.

const MyComponent = ({ children, className, hide }) => {
  const myClass = joinable('potato', className, [hide, 'invisible']);
  return (
    <div className={myClass}>
    {children}
    </div>
  );
}

render(<MyComponent className="cucumber">Hello world</MyComponent>); 
// => <div class="potato cucumber">Hello world</div>
render(<MyComponent className="cucumber" hide>Hello world</MyComponent>); 
// => <div class="potato invisible cucumber">Hello world</div>
render(<MyComponent>Hello world</MyComponent>); 
// => <div class="potato">Hello world</div>

If else

Adding a conditional check in Joinable is easy with an Array structure and a length of two or three.

const condition = variableA === variableB; // let's assume it's true
const myString = joinable('one', [condition, 'plus', 'minus'], 'one'); // => one plus one

Customisable separator

Joinable allows you to change the separator default of space, helping you to solve other joinString challenges:

Example of building a URL:

const url = joinable('http://www.richardkotze.com', 'projects', 'joinable', { separator: '/' });
console.log(url); // => http://www.richardkotze.com/projects/joinable

Performance focused

I’ve put effort into ensuring Joinable has good performance and has been great learning.

Things that I found made significant gains was:

  • Removing the need to use Array slice.
  • Checking for joinable types string and number early.
  • Using continue if value is a falsy.
  • In joinIf function using plain if statements instead of spread operator and slice to run conditional array.

If you’re interested you can clone the repo and run the benchmark tests npm run benchmark.

Any ideas or suggestions to improve Joinable please make an issue.