Piping your JS

Erez Carmel
Israeli Tech Radar
3 min readFeb 2, 2022

--

Recently, I came across this article about the ‘pipe operator for Javascript’ proposal from the TC39 group website, and their GitHub.

Although this article was well written and very detailed, I thought it was a little bit too long to read and requires a TL;DR hero to simplify it. So here comes your hero!

So what’s this proposal all about?

Actually, there were two proposals for the new pipe operator, both inspired by other programming languages. F# by Microsoft which was inspired by OCaml, and Hack by Facebook which was inspired by PHP. Both proposals do the same thing, but with different syntax.

Let’s start with a simple Javascript example:

const i = d(c(b(a)));

The a variable is applied to b, which applied to c, which applied to d, and all of this is assigned to i.

Now let’s use the new pipe operator:

|>

This is how it will look like with Microsoft’s F#:

const i = a |> b |> c |> d;

And with Facebook’s Hack:

const i = a |> b(%) |> c(%) |> d(%)

You can see the main difference between the proposal syntaxes. While the F# is piping the variable to the next step, Hack needs you to use the % placeholder to define where the variable will be piped into.

So if we want to run a stringed number with parseInt, it’ll look like this:

'100' |> parseInt    // F#
'100' |> parseInt(%) // Hack

Looks the same, what’s the difference?

The Hack will be easier to use when we need to use methods, arrays, operators, objects or await:

value |> $ => $.someMethod() // method call, value.someMethod()
value |> $ => $ + 1 // operator, value+ 1
value |> $ => [$, 'b', 'c'] // Array literal, [value, 'b', 'c']
value |> $ => {prop: $} // object literal, {prop: value}
value |> await // awaiting a Promise, await value

On the other side, F# will be easier with destructuring:

const str = obj |> ({a, b}) => `${a} ${b}`;

What can I do with it?

Let’s see a very simple usage for the pipe operator:

// Hack
const namesArray = arr
|> filter(%, obj => obj.enabled)
|> map(%, obj => objecy.name)
|> console.log(%)
;

// F#
const namesArray = arr
|> filter~(?, obj => obj.enabled)
|> map~(?, obj => obj.name)
|> console.log
;

in both examples, we can see how to pipe filter & map and print the final result to console.log.

Of course, there are lots of other use cases the pipe operator can be very helpful, but I’ll leave you something to Google yourself :)

I hope this quick post was helpful for understanding the new pipe operator. Let me know what you think.

--

--

Erez Carmel
Israeli Tech Radar

Full stack developer, consultant & lecturer, experienced with developing interfaces on various platforms.