<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Drew</title>
    <description>The latest articles on DEV Community by Drew (@dhack).</description>
    <link>https://dev.to/dhack</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F77259%2F6f38f0a4-5416-4370-9187-f6c1cf760659.jpg</url>
      <title>DEV Community: Drew</title>
      <link>https://dev.to/dhack</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dhack"/>
    <language>en</language>
    <item>
      <title>Merge Functions</title>
      <dc:creator>Drew</dc:creator>
      <pubDate>Fri, 22 Jan 2021 11:08:24 +0000</pubDate>
      <link>https://dev.to/dhack/merge-functions-4d8e</link>
      <guid>https://dev.to/dhack/merge-functions-4d8e</guid>
      <description>&lt;p&gt;Part of a series to track the 90-Day Beat Down&lt;/p&gt;

&lt;p&gt;I recently got hired for a new gig. They hired 2 of us on a 90-day prove-yourself contract. Pretty sure this is a "competition" of sorts to see which of us can rise to the top.&lt;/p&gt;

&lt;p&gt;This is how I internalize things I review and learn.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's Combine Multiple Async Behaviors
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Async
&lt;/h3&gt;

&lt;p&gt;Wait- what's an async behavior? &lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LZ6MZhoh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/i5wpxq9jo270ectsr37t.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LZ6MZhoh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/i5wpxq9jo270ectsr37t.jpg" alt="sink" width="474" height="474"&gt;&lt;/a&gt;&lt;br&gt;
Let's get the exact description from &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function"&gt;MDN&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Async functions can contain zero or more await expressions. Await expressions suspend progress through an async function, yielding control and subsequently resuming progress only when an awaited promise-based asynchronous operation is either fulfilled or rejected. The resolved value of the promise is treated as the return value of the await expression. Use of async / await enables the use of ordinary try / catch blocks around asynchronous code.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;What does that even mean? It's basically a giant game of redlight, greenlight. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Do something

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;red light!&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;...waiting for completion...&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;green light!&lt;/strong&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Do the next thing

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;red light!&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;...waiting for completion...&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;green light!&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Do the next thing, etc. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now let's &lt;a href="https://dev.to/dhack/upskill-for-the-day-job-25o8"&gt;think back to post 1&lt;/a&gt;. Our goal was to do a better job of writing customizable, reusable functions by a) returning functions from functions and b) using functions as parameters (providing &lt;em&gt;listeners&lt;/em&gt; or &lt;em&gt;callbacks&lt;/em&gt;). &lt;/p&gt;

&lt;p&gt;Let's take a look at a lot of code. Go slowly, review this chunk, and see if you notice any patterns:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let addOneListener = (selector) =&amp;gt; (eventType) =&amp;gt; (listener) =&amp;gt; {
  let element = document.querySelector(selector);
  element.addEventListener(eventType, listener);

  return () =&amp;gt; {
    element.removeEventListener(eventType, listener);
  };
};

let createTheInterval = (time) =&amp;gt; (listener) =&amp;gt; {
  let id = setInterval(listener, time);
  return () =&amp;gt; {
    clearInterval(id);
  };
};

let addBtnListener = addOneListener("#button");
let addBtnClickListener = addBtnListener("click");

let oneSec = createTheInterval(1000);

let cancelOneSecond = oneSecond(() =&amp;gt; {
  console.log("one")
})

cancelOneSecond()

let twoSeconds = createInterval(2000)
twoSeconds(() =&amp;gt; {
  console.log("two")
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have ^^^ a number of functions that all &lt;strong&gt;expect to receive a &lt;em&gt;listener&lt;/em&gt; as a parameter&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Now that we see this pattern, we can start combining functions in interesting ways. &lt;/p&gt;

&lt;h3&gt;
  
  
  Broadcasters (accepting the listeners)
&lt;/h3&gt;

&lt;p&gt;I'm going to refer to functions that accept listeners as broadcasters, because that's how I was taught. You may also hear these named &lt;em&gt;sources&lt;/em&gt; or other words that describe &lt;strong&gt;things that push out values&lt;/strong&gt;. For now, a broadcaster is a function that accepts a listener.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let comboFunction = (broadcaster1, broadcaster2) =&amp;gt; listener =&amp;gt; {
  let cancel1 = broadcaster1(listener)
  let cancel2 = broadcaster2(listener)

  return () =&amp;gt; {
    cancel1()
    cancel2()
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a lot of code (again), so let's break it down: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;comboFunction&lt;/code&gt; is a variable that is declared&lt;/li&gt;
&lt;li&gt;we initialize this variable and assign it the value of a function declaration&lt;/li&gt;
&lt;li&gt;that function accepts 2 additional functions as parameters (our &lt;em&gt;broadcasters&lt;/em&gt;)&lt;/li&gt;
&lt;li&gt;our function &lt;strong&gt;is&lt;/strong&gt; a variable until we decide to execute it like so:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let timePass_or_eventHandle = comboFunction(addBtnClickListener, oneSec);
let cancelBoth = timePass_or_eventHandle(() =&amp;gt; {
  console.log("time pass or event happened ");
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://codesandbox.io/s/comboasyncpractice-bxux6"&gt;Try using this code all combined code&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;By initializing the variable &lt;code&gt;cancelBoth&lt;/code&gt; and assigning it the value of &lt;code&gt;timePass_or_eventHandle&lt;/code&gt;, we actually cause the function to execute. &lt;br&gt;
&lt;a href="https://i.giphy.com/media/gPemXeO9J2wEMMmz4T/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/gPemXeO9J2wEMMmz4T/giphy.gif" alt="clickTickGif" width="480" height="238"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What happens if we add &lt;code&gt;cancelBoth();&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Nothing! The "time pass" doesn't reach the console and the clicked button does nothing as well. &lt;/p&gt;

&lt;p&gt;Next time we can add in some &lt;a href="https://lodash.com/docs/4.17.15#curry"&gt;awesome lodash functionality&lt;/a&gt; to help make our function wrapping a bit more concise and readable.  &lt;/p&gt;

</description>
    </item>
    <item>
      <title>JS Function Wrapping</title>
      <dc:creator>Drew</dc:creator>
      <pubDate>Thu, 21 Jan 2021 10:45:34 +0000</pubDate>
      <link>https://dev.to/dhack/upskill-for-the-day-job-25o8</link>
      <guid>https://dev.to/dhack/upskill-for-the-day-job-25o8</guid>
      <description>&lt;p&gt;Part of a series to track the 90-Day Beat Down&lt;/p&gt;

&lt;p&gt;I recently got hired for a new gig. They hired 2 of us on a 90-day prove-yourself contract. Pretty sure this is a "competition" of sorts to see which of us can rise to the top.&lt;/p&gt;

&lt;p&gt;This is my way of internalizing what I learn along the way. &lt;/p&gt;

&lt;h3&gt;
  
  
  Shore Up the Foundation with JavaScript
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Callbacks and Closure Patterns
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Sometimes javascript apis are inconsistent in how they act. By wrapping them in functions, we have more control, more customization, and stronger callbacks...
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let createTimeout = (time) =&amp;gt; {
    setTimeout(() =&amp;gt; {
        console.log('done');
    }, time)
};

createTimeout(100);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This mostly works just fine, but with small amounts of time, it becomes increasingly difficult to know if the timeout is actually occurring. Let's wrap it in another fatarrow function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let createTimeout = (time) =&amp;gt; () =&amp;gt; {
    setTimeout(() =&amp;gt; {
        console.log('done');
    }, time);
};

let timeout1s = createTimeout(1000);
let timeout2s = createTimeout(2000);
let timeout3s = createTimeout(3000);
timeout1s();
timeout2s();
timeout3s();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;^^^ that code provides us with more customization. But it does not give us more control over what happens within setTimeout. What if we wanted to differentiate the callback behavior based on the time parameter? That would mean our code needed to act one way for 1s, a different way for 2s, etc.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let createTimeout = (time) =&amp;gt; (callback) =&amp;gt; {
    setTimeout(callback, time);
};

let timeout1s = createTimeout(1000);
let timeout2s = createTimeout(2000);
let timeout3s = createTimeout(3000);
// call the functions AND provide unique callbacks
timeout1s(() =&amp;gt; {
    console.log("one");
});
timeout2s(() =&amp;gt; {
    console.log("two");
});
timeout3s(() =&amp;gt; {
    console.log("three");
}); 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;This puts us on track to deal with async behavior more consistently. But a huge part of async behavior is building in an exit strategy. "What if we need to cancel mid-function?"
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let createTimeout = (time) =&amp;gt; (callback) =&amp;gt; {
    // setTimeout returns an id we can use
    let id = setTimeout(callback, time); 
    // return that from our function so we can access it
    return id;
};

let timeout1s = createTimeout(1000);
let timeout2s = createTimeout(2000);
let timeout3s = createTimeout(3000);

let id1s = timeout1s(() =&amp;gt; {
    console.log("one");
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;id1s now holds the value of the setTimeout id that was created, and we can clear it with &lt;code&gt;clearTimeout(id1s)&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;But if we want even more control over our code (which we do), we can actually continue to wrap our functionality inside more functions!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let createTimeout = (time) =&amp;gt; (callback) =&amp;gt; {
    let id = setTimeout(callback, time);
    // returns a function to capture **behavior**
    return () =&amp;gt; clearTimeout(id1s);
};

let timeout1s = createTimeout(1000);
let timeout2s = createTimeout(2000);
let timeout3s = createTimeout(3000);

let cancel1s = timeout1s(() =&amp;gt; {
    console.log("one");
});
cancel1s();
timeout2s(() =&amp;gt; {
    console.log("two");
});

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The big picture concepts I'm trying to capture (and use moving forward) are: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You increase code flexibility by &lt;strong&gt;returning&lt;/strong&gt; functions from within functions&lt;/li&gt;
&lt;li&gt;You increase flexibility and customization by passing functions &lt;strong&gt;in&lt;/strong&gt; to other functions&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let's go through the same process with an event listener&lt;br&gt;
End goal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let addListener = selector =&amp;gt; eventType =&amp;gt; listener =&amp;gt; {
    let element = document.querySelector(selector);
    element.addEventListener(eventType, listener);
    return () =&amp;gt; {
        element.removeEventListener(eventType, listener);
    }
};

let addButtonListener = addListener('button');
let addButtonClickListener = addButtonListener("click")
let removeBtnClickListener = addButtonClickListener(() =&amp;gt; {
    console.log('button clicked');
})
// removeBtnClickListener();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;How did we get there?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Each piece of the function &lt;code&gt;addListener&lt;/code&gt; is returning another function.&lt;/li&gt;
&lt;li&gt;Anytime we invoke a piece of that chain, we're getting a function returned to us &lt;em&gt;in addition to&lt;/em&gt; the function being executed. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let's break it down:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let addListener = selector =&amp;gt; eventType =&amp;gt; listener =&amp;gt; {
    let element = document.querySelector(selector);
    element.addEventListener(eventType, listener);
    return () =&amp;gt; {
        element.removeEventListener(eventType, listener);
    }
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;when we call &lt;code&gt;addListener('button');&lt;/code&gt; what do we have?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let addButtonListener = addListener('button');
console.log(addButtonListener);
let addButtonClickListener = addButtonListener("click")
console.log(addButtonClickListener);
let removeBtnClickListener = addButtonClickListener(() =&amp;gt; {
    console.log('button clicked');
});
console.log(removeBtnClickListener);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Those logs in the console are pretty informative:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fio0nm2luwqa2e7l3v87i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fio0nm2luwqa2e7l3v87i.png" alt="console logs"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Each thing logged is a function! and the first two return another function! We now have control over how addEventListener interacts with other APIs, like setTimeout, gives us confidence in our pattern moving forward &lt;/p&gt;

&lt;p&gt;Place this code in a js file, add that file into a simple html with 1 btn, and see what happens:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// index.html
&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang="en"&amp;gt;
    &amp;lt;body&amp;gt;
        &amp;lt;button id="button"&amp;gt;Click My Dick&amp;lt;/button&amp;gt;
        &amp;lt;script src="./index.js" type="text/javascript" /&amp;gt;
    &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//index.js
let addButtonListener = addListener('button');

let addButtonClickListener = addButtonListener("click")

let removeBtnClickListener = addButtonClickListener(() =&amp;gt; {
    console.log('button clicked');
})

// removeBtnClickListener();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the remove call is commented out, we see the clicks log to the console. With the remove un-commented, the listener is removed before we (the user) ever have a chance to click anything. &lt;/p&gt;

&lt;p&gt;Always check devTools to confirm these things. console.log can only take you so far and is annoying at best): &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fkbgn0hy6cjf651f75qai.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fkbgn0hy6cjf651f75qai.png" alt="click even vs none "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Just to reiterate the goal of this review: &lt;/p&gt;

&lt;h3&gt;
  
  
  Use functions to return other functions. Also, pass functions into other functions. This function wrapping will provide more code control, flexibility, and even reusability,
&lt;/h3&gt;

</description>
    </item>
  </channel>
</rss>
