tag:blogger.com,1999:blog-35319698478694136272024-03-13T15:00:03.751-04:00Boduch's BlogProgramming the web.Adam Boduchhttp://www.blogger.com/profile/00484502507931628726noreply@blogger.comBlogger684125tag:blogger.com,1999:blog-3531969847869413627.post-36294723353813934462019-04-23T14:01:00.000-04:002019-04-23T14:01:33.355-04:00Refreshing Next.js Page DataSomething that I struggled wrapping my head around when learning Next.js was refreshing data on a given page. It seemed that the only option was to trigger the browser to reload the page, which isn't at all what I was going for. Next.js does a fantastic job of populating the page with data, whether it's rendered on the server or in the browser. The initial page data and the plumbing needed to fetch it is something I just don't need to think about.<br />
<br />
In this post, I'll walk through my stumbling points for refreshing page data and the approach that I took to get around the issue. Let's start off by looking at a trivial page in a Next.js app:<br />
<pre><code class="language-jsx">
async function getInitialProps() {
const response = await fetch('/api/some/endpoint');
const myFetchedData = await response.json();
return { myFetchedData };
}
export default function MyPage(props) {
return <strong>{props.myFetchedData}</strong>;
}
MyPage.getInitialProps = getInitialProps;
</code></pre>
<br />
The <span style="font-family: "courier new" , "courier" , monospace;">getInitialProps()</span> function fetches the data that our page needs. It makes a <span style="font-family: "courier new" , "courier" , monospace;">fetch()</span> call to some imaginary API endpoint, gets the JSON response by calling <span style="font-family: "courier new" , "courier" , monospace;">response.json()</span>, and returns an object with a <span style="font-family: "courier new" , "courier" , monospace;">myFetchedData</span> property. The object that is returned is passed to the <span style="font-family: "courier new" , "courier" , monospace;">MyPage</span> component as props. You can see that our component uses the <span style="font-family: "courier new" , "courier" , monospace;">props.myFetchedData</span> value when rendering its content. Finally, the <span style="font-family: "courier new" , "courier" , monospace;">getInitialProps()</span> function is assigned to <span style="font-family: "courier new" , "courier" , monospace;">MyPage.getInitialProps</span>. This is how Next.js knows how to populate our page data. It will call this function on the server if this page is requested, or in the browser if this page is navigated to after the initial load.<br />
<br />
At this point, we have a page that loads data on initial render. But what happens if the data returned by the API endpoint has changed somehow? For example, some other component in our application changes this value or creates a new resource, etc. There are any number of reasons that you might want to refresh the data that's passed to <span style="font-family: "courier new" , "courier" , monospace;">MyPage</span> as properties. This is where I got stuck.<br />
<br />
To illustrate the issue, let's add a refresh button to our page that simply calls the <span style="font-family: "courier new" , "courier" , monospace;">getInitialProps()</span> function, thus calling the API again and getting updated data:<br />
<pre><code class="language-jsx">
async function getInitialProps() {
const response = await fetch('/api/some/endpoint');
const myFetchedData = await response.json();
return { myFetchedData };
}
export default function MyPage(props) {
return (
<main>
<strong>{props.myFetchedData}</strong>
<button onclick={getInitialProps}>Refresh</button>
</main>
);
}
MyPage.getInitialProps = getInitialProps;
</code></pre>
<br />
The <span style="font-family: "courier new" , "courier" , monospace;">onClick</span> handler of the new refresh button gets us partway there. It makes the API call, which responds with updated data, but then it doesn't do anything with it. At this point, I realized that if your Next.js page has data that needs to be refreshed, it needs to be stateful. Thankfully, you can still use the <span style="font-family: "courier new" , "courier" , monospace;">getInitialProps</span> mechanism of Next.js to handle data fetching for the initial page load. Here's what the pattern looks like:<br />
<pre><code class="language-jsx">
import { useState } from 'react';
async function fetchData() {
const response = await fetch('/api/some/endpoint');
const myFetchedData = await response.json();
return { myFetchedData };
}
export default function MyPage(props) {
const [
myFetchedData,
setMyFetchedData
] = useState(props.myFetchedData);
async function refresh() {
const refreshedProps = await fetchData();
setMyFetchedData(refreshedProps.myFetchedData);
}
return (
<main>
<strong>{myFetchedData}</strong>
<button onclick="{refresh}">Refresh</button>
</main>
);
}
MyPage.getInitialProps = fetchData;
</code></pre>
<br />
The <span style="font-family: "courier new" , "courier" , monospace;">MyPage</span> component now has <span style="font-family: "courier new" , "courier" , monospace;">myFetchedData</span> as state. The original <span style="font-family: "courier new" , "courier" , monospace;">myFetchedData</span> property is still passed to the component because this is how the Next.js mechanism for data fetching passes data to our components. However, the <span style="font-family: "courier new" , "courier" , monospace;">useState()</span> hook uses the <span style="font-family: "courier new" , "courier" , monospace;">myFetchedData</span> property value as default state value for the <span style="font-family: "courier new" , "courier" , monospace;">myFetchedValue</span> state. This means that you don't need to worry about the <span style="font-family: "courier new" , "courier" , monospace;">myFetchedValue</span> property - just use the <span style="font-family: "courier new" , "courier" , monospace;">myFetchedValue</span> state instead since it has the same value.<br />
<br />
Now that we've setup <span style="font-family: "courier new" , "courier" , monospace;">myFetchedValue</span> to be stateful, we can implement a proper refresh function. But first, take note that we've renamed the <span style="font-family: "courier new" , "courier" , monospace;">getInitialProps()</span> function to <span style="font-family: "courier new" , "courier" , monospace;">fetchData()</span> because it's now more generic than fetching the initial page data. The <span style="font-family: "courier new" , "courier" , monospace;">refresh()</span> function calls <span style="font-family: "courier new" , "courier" , monospace;">fetchData()</span>, then calls <span style="font-family: "courier new" , "courier" , monospace;">setMyFetchedData()</span> to update the state and re-render the page.<br />
<br />
To summarize how state can help you with refreshing data used by your Next.js pages, just remember:<br />
<br />
<ol>
<li>The default value passed to <span style="font-family: "courier new" , "courier" , monospace;">useState()</span> is the value that is fetched initially by Next.js.</li>
<li>You can reuse your data fetching function any time you need fresh data. Just update the state when you have the new data.</li>
</ol>
Adam Boduchhttp://www.blogger.com/profile/00484502507931628726noreply@blogger.com0tag:blogger.com,1999:blog-3531969847869413627.post-9310566444735975102017-08-28T11:55:00.000-04:002017-08-28T11:55:27.323-04:00Lodash LogicIf you're using Lodash, you have a handful of tools at your disposal for organizing logic into functions. This is a nice alternative to imperative <span style="font-family: Courier New, Courier, monospace;">if</span> statements sprinkled throughout your code. For example, let's say that you only want to execute code if one of several choices is true. You could use the <span style="font-family: "courier new" , "courier" , monospace;">some()</span> function as follows:<br />
<br />
<pre style="background: #f9f9f9; color: #080808;"><span style="color: #a71d5d; font-style: italic;">const</span> choices <span style="color: #794938;">=</span> [
{ name: <span style="color: #0b6125;">'choice 1'</span>, value: <span style="color: #811f24; font-weight: 700;">true</span> },
{ name: <span style="color: #0b6125;">'choice 2'</span>, value: <span style="color: #811f24; font-weight: 700;">true</span> },
{ name: <span style="color: #0b6125;">'choice 3'</span>, value: <span style="color: #811f24; font-weight: 700;">false</span> }
];
<span style="color: #794938;">if</span> (_(choices).map(<span style="color: #0b6125;">'value'</span>).some()) {
<span style="color: #bf4f24;">console</span><span style="color: #693a17;">.log</span>(<span style="color: #0b6125;">'true'</span>);
<span style="color: #794938;">else</span> {
<span style="color: #bf4f24;">console</span><span style="color: #693a17;">.log</span>(<span style="color: #0b6125;">'false'</span>);
}
</pre>
<br />
The <span style="font-family: "courier new" , "courier" , monospace;">choices</span> array represents the choices that we have available. The <span style="font-family: "courier new" , "courier" , monospace;">name</span> property isn't actually used for anything in this code. The <span style="font-family: "courier new" , "courier" , monospace;">value</span> property is what we're interested in here. We want to run some code if any value is true.<br />
<br />
To do so, we're using an <span style="font-family: "courier new" , "courier" , monospace;">if</span> statement. With the help of the <span style="font-family: "courier new" , "courier" , monospace;">map()</span> and <span style="font-family: "courier new" , "courier" , monospace;">some()</span> Lodash functions, we can easily check for this condition. In this case, the statement evaluates to true because there's two true values in the array. We can also check to make sure that every value is true before executing a piece of code:<br />
<br />
<pre style="background: #f9f9f9; color: #080808;"><span style="color: #794938;">if</span> (_(choices).map(<span style="color: #0b6125;">'value'</span>).every()) {
<span style="color: #bf4f24;">console</span><span style="color: #693a17;">.log</span>(<span style="color: #0b6125;">'true'</span>);
<span style="color: #794938;">else</span> {
<span style="color: #bf4f24;">console</span><span style="color: #693a17;">.log</span>(<span style="color: #0b6125;">'false'</span>);
}
</pre>
<br />
In this case, the <span style="font-family: "courier new" , "courier" , monospace;">else</span> path is followed because not every value is true.<br />
<br />
The _.<span style="font-family: "courier new" , "courier" , monospace;">some()</span> and _.<span style="font-family: "courier new" , "courier" , monospace;">every()</span> functions are helpful with simplifying the conditions evaluated by <span style="font-family: "courier new" , "courier" , monospace;">if</span> statements. For example, _.<span style="font-family: "courier new" , "courier" , monospace;">some()</span> provides the same result as chaining together a bunch of logical or (<span style="font-family: "courier new" , "courier" , monospace;">||</span>) operators. Likewise, _.<span style="font-family: "courier new" , "courier" , monospace;">every()</span> replaces logical and (<span style="font-family: "courier new" , "courier" , monospace;">&&</span>) operators.<br />
<br />
The result is that instead of having to maintain the condition that's evaluated in the <span style="font-family: "courier new" , "courier" , monospace;">if</span> statement, we can simply add new values to the <span style="font-family: "courier new" , "courier" , monospace;">choices</span> collection. Essentially, this is a step toward declarative programming, away from imperative programming.<br />
<br />
Let's think about the <span style="font-family: "courier new" , "courier" , monospace;">if</span> statement used above, and what it's actually doing. It's calling <span style="font-family: "courier new" , "courier" , monospace;">console.log()</span> when some condition is true, and it's calling <span style="font-family: "courier new" , "courier" , monospace;">console.log()</span> again when the condition is false. The problem with <span style="font-family: "courier new" , "courier" , monospace;">if</span> statements like this is that they're not very portable. It'd be much easier to call a function with the possible choices as an argument, and the correct behavior is invoked.<br />
<br />
Here's what this might look like:<br />
<br />
<pre style="background: #f9f9f9; color: #080808;"><span style="color: #a71d5d; font-style: italic;">const</span> some <span style="color: #794938;">=</span> (yes, no) <span style="color: #794938;">=</span><span style="color: #794938;">></span> (...values) <span style="color: #794938;">=</span><span style="color: #794938;">></span>
<span style="color: #794938;">new</span> <span style="color: #bf4f24;">Map</span>([
[<span style="color: #811f24; font-weight: 700;">true</span>, yes],
[<span style="color: #811f24; font-weight: 700;">false</span>, no]
]).get(_.some(values))();
</pre>
<br />
Let's break this code down:<br />
<ul>
<li>We've created a higher-order function called <span style="font-family: "courier new" , "courier" , monospace;">some()</span> that returns a new function.</li>
<li>The returned function accepts an arbitrary number of values. These are tested with Lodash's <span style="font-family: "courier new" , "courier" , monospace;">_.some()</span>.</li>
<li>The <span style="font-family: "courier new" , "courier" , monospace;">some()</span> function accepts <span style="font-family: "courier new" , "courier" , monospace;">yes()</span> and <span style="font-family: "courier new" , "courier" , monospace;">no()</span> functions to run based on the result of calling <span style="font-family: "courier new" , "courier" , monospace;">_.some(values)</span></li>
<li>A <span style="font-family: "courier new" , "courier" , monospace;">Map</span> is used in place of an <span style="font-family: "courier new" , "courier" , monospace;">if</span> statement to call the appropriate logging function.</li>
</ul>
With this utility, we can now compose our own functions that values as arguments, and based on those arguments, run the appropriate function. Let's compose a function using <span style="font-family: "courier new" , "courier" , monospace;">some()</span>:
<br />
<br />
<pre style="background: #f9f9f9; color: #080808;"><span style="color: #a71d5d; font-style: italic;">const</span> hasSome <span style="color: #794938;">=</span> some(
() <span style="color: #794938;">=</span><span style="color: #794938;">></span> <span style="color: #bf4f24;">console</span><span style="color: #693a17;">.log</span>(<span style="color: #0b6125;">'has some'</span>),
() <span style="color: #794938;">=</span><span style="color: #794938;">></span> <span style="color: #bf4f24;">console</span><span style="color: #693a17;">.log</span>(<span style="color: #0b6125;">'nope'</span>)
);
</pre>
<br />
Now we have a <span style="font-family: "courier new" , "courier" , monospace;">hasSome()</span> function will log either <span style="font-family: Courier New, Courier, monospace;">"has some"</span> or <span style="font-family: Courier New, Courier, monospace;">"nope"</span>, depending on what values are passed to it:<br />
<br />
<pre style="background: #f9f9f9; color: #080808;">hasSome(<span style="color: #811f24; font-weight: 700;">0</span>, <span style="color: #811f24; font-weight: 700;">0</span>, <span style="color: #811f24; font-weight: 700;">0</span>, <span style="color: #811f24; font-weight: 700;">1</span>, <span style="color: #811f24; font-weight: 700;">0</span>);
<span style="color: #5a525f; font-style: italic;">// -> has some</span>
hasSome(<span style="color: #811f24; font-weight: 700;">0</span>, <span style="color: #811f24; font-weight: 700;">0</span>, <span style="color: #811f24; font-weight: 700;">0</span>, <span style="color: #811f24; font-weight: 700;">0</span>);
<span style="color: #5a525f; font-style: italic;">// -> nope</span>
</pre>
<br />
Now any time that you want an <span style="font-family: Courier New, Courier, monospace;">if</span> statement that evaluates simple boolean expressions and runs one piece of code or another, depending on the result, you can use <span style="font-family: "courier new" , "courier" , monospace;">some()</span> to compose a new function. You then call this new function with the choices as the arguments.<br />
<br />
Let's create an <span style="font-family: "courier new" , "courier" , monospace;">every()</span> function now that works the same way as <span style="font-family: "courier new" , "courier" , monospace;">some()</span> except that it tests that every value is true:<br />
<br />
<pre style="background: #f9f9f9; color: #080808;"><span style="color: #a71d5d; font-style: italic;">const</span> every <span style="color: #794938;">=</span> (yes, no) <span style="color: #794938;">=</span><span style="color: #794938;">></span> (...values) <span style="color: #794938;">=</span><span style="color: #794938;">></span>
<span style="color: #794938;">new</span> <span style="color: #bf4f24;">Map</span>([
[<span style="color: #811f24; font-weight: 700;">true</span>, yes],
[<span style="color: #811f24; font-weight: 700;">false</span>, no]
]).get(_.every(values))();
</pre>
<br />
The only difference between <span style="font-family: "courier new" , "courier" , monospace;">every()</span> and <span style="font-family: "courier new" , "courier" , monospace;">some()</span> is that we're using <span style="font-family: "courier new" , "courier" , monospace;">_.every()</span> instead of <span style="font-family: "courier new" , "courier" , monospace;">_.some()</span>. The approach is identical: supply <span style="font-family: "courier new" , "courier" , monospace;">yes()</span> and <span style="font-family: "courier new" , "courier" , monospace;">no()</span> functions to call depending on result of <span style="font-family: "courier new" , "courier" , monospace;">_.every()</span>.<br />
<br />
Now we can compose a <span style="font-family: "courier new" , "courier" , monospace;">hasEvery()</span> function, just like we did with the <span style="font-family: "courier new" , "courier" , monospace;">hasSome()</span> function:<br />
<br />
<pre style="background: #f9f9f9; color: #080808;"><span style="color: #a71d5d; font-style: italic;">const</span> hasEvery <span style="color: #794938;">=</span> every(
() <span style="color: #794938;">=</span><span style="color: #794938;">></span> <span style="color: #bf4f24;">console</span><span style="color: #693a17;">.log</span>(<span style="color: #0b6125;">'has every'</span>),
() <span style="color: #794938;">=</span><span style="color: #794938;">></span> <span style="color: #bf4f24;">console</span><span style="color: #693a17;">.log</span>(<span style="color: #0b6125;">'nope'</span>)
);
</pre>
<br />
Once again, we've avoided imperative <span style="font-family: "courier new" , "courier" , monospace;">if</span> statements in favor of functions. Now we can call <span style="font-family: "courier new" , "courier" , monospace;">hasEvery()</span> from anywhere, and pass in some values to check:<br />
<br />
<pre style="background: #f9f9f9; color: #080808;">hasEvery(<span style="color: #811f24; font-weight: 700;">1</span>, <span style="color: #811f24; font-weight: 700;">1</span>, <span style="color: #811f24; font-weight: 700;">1</span>, <span style="color: #811f24; font-weight: 700;">1</span>, <span style="color: #811f24; font-weight: 700;">1</span>)
<span style="color: #5a525f; font-style: italic;">// -> has every</span>
hasEvery(<span style="color: #811f24; font-weight: 700;">1</span>, <span style="color: #811f24; font-weight: 700;">1</span>, <span style="color: #811f24; font-weight: 700;">1</span>, <span style="color: #811f24; font-weight: 700;">1</span>, <span style="color: #811f24; font-weight: 700;">0</span>)
<span style="color: #5a525f; font-style: italic;">// -> nope</span>
</pre>
<br />
Lodash has a <span style="font-family: "courier new" , "courier" , monospace;">_.cond()</span> function that works similarly to our <span style="font-family: "courier new" , "courier" , monospace;">Map</span> approach in <span style="font-family: "courier new" , "courier" , monospace;">some()</span> and <span style="font-family: "courier new" , "courier" , monospace;">every()</span>, only more powerful. Instead of mapping static values, such as true and false, to functions to run, it maps functions to functions. This allows you to compute values to test on-the-fly.<br />
<br />
Before we get too fancy, let's rewrite our <span style="font-family: "courier new" , "courier" , monospace;">some()</span> and <span style="font-family: "courier new" , "courier" , monospace;">every()</span> functions using <span style="font-family: "courier new" , "courier" , monospace;">_.cond()</span>:<br />
<br />
<pre style="background: #f9f9f9; color: #080808;"><span style="color: #a71d5d; font-style: italic;">const</span> some <span style="color: #794938;">=</span> (yes, no) <span style="color: #794938;">=</span><span style="color: #794938;">></span> _.flow(
_.rest(_.some, <span style="color: #811f24; font-weight: 700;">0</span>),
_.cond([
[_.partial(_.eq, <span style="color: #811f24; font-weight: 700;">true</span>), yes],
[_.stubTrue, no]
])
);
</pre>
<br />
Let's break this down:<br />
<ul>
<li>The <span style="font-family: "courier new" , "courier" , monospace;">_.flow()</span> function creates a new function by calling the first function, then passing it's return value to the next function, and so on.</li>
<li>The <span style="font-family: "courier new" , "courier" , monospace;">_.rest()</span> function creates a new function that passes argument values as an array to it's wrapped function. We're doing this with <span style="font-family: "courier new" , "courier" , monospace;">_.some()</span> because it expects an array, but we just want to be able to pass it argument values instead.</li>
<li>The <span style="font-family: "courier new" , "courier" , monospace;">_.cond()</span> function takes an array of pairs. A pair is a condition function, and a function to call if the condition function returns true. The first pair that evaluates to true is run, and no other pairs are evaluated.</li>
<li>The <span style="font-family: "courier new" , "courier" , monospace;">_.partial(_.eq, true)</span> call makes a new function that tests the output of <span style="font-family: "courier new" , "courier" , monospace;">_.some()</span>.</li>
<li>The <span style="font-family: "courier new" , "courier" , monospace;">_.stubTrue()</span> function will always evaluate to true, unless something above it evaluates to true first. Think of this as the <span style="font-family: "courier new" , "courier" , monospace;">else</span> in an <span style="font-family: "courier new" , "courier" , monospace;">if</span> statement.</li>
</ul>
We can use this new implementation of <span style="font-family: "courier new" , "courier" , monospace;">some()</span> to compose the same <span style="font-family: "courier new" , "courier" , monospace;">hasSome()</span> function that we created earlier and it will work the same way. Likewise, we can implement the <span style="font-family: "courier new" , "courier" , monospace;">every()</span> function using the same approach.
<br />
<br />
For something as simple as the <span style="font-family: "courier new" , "courier" , monospace;">some()</span> and <span style="font-family: "courier new" , "courier" , monospace;">every()</span> functions, the <span style="font-family: "courier new" , "courier" , monospace;">_.cond()</span> approach doesn't present any clear advantage over the <span style="font-family: "courier new" , "courier" , monospace;">Map</span> approach. This is because there are exactly two paths. Either the condition evaluates to true, or it doesn't. Often, we're not working with simple yes/no logical conditions. Rather, there are a number of potential paths.
<br />
<br />
Think of this as a an <span style="font-family: "courier new" , "courier" , monospace;">if</span>-<span style="font-family: "courier new" , "courier" , monospace;">else</span> statement with lots of conditions. Suppose we had the following conditions:
<br />
<br />
<pre style="background: #f9f9f9; color: #080808;"><span style="color: #a71d5d; font-style: italic;">const</span> condition1 <span style="color: #794938;">=</span> <span style="color: #811f24; font-weight: 700;">false</span>;
<span style="color: #a71d5d; font-style: italic;">const</span> condition2 <span style="color: #794938;">=</span> <span style="color: #811f24; font-weight: 700;">true</span>;
<span style="color: #a71d5d; font-style: italic;">const</span> condition3 <span style="color: #794938;">=</span> <span style="color: #811f24; font-weight: 700;">false</span>;
</pre>
<br />
Instead of a simple yes/no question with two potential paths, now we have 3. Later on, we might have 4, and so on. This is how software grows to be complex. Here's how we would evaluate these conditions and execute corresponding code using <span style="font-family: "courier new" , "courier" , monospace;">_.cond()</span>:<br />
<br />
<pre style="background: #f9f9f9; color: #080808;"><span style="color: #a71d5d; font-style: italic;">const</span> doStuff <span style="color: #794938;">=</span> _.cond([
[_.constant(condition1), () <span style="color: #794938;">=</span><span style="color: #794938;">></span> <span style="color: #bf4f24;">console</span><span style="color: #693a17;">.log</span>(<span style="color: #0b6125;">'Condition 1'</span>)],
[_.constant(condition2), () <span style="color: #794938;">=</span><span style="color: #794938;">></span> <span style="color: #bf4f24;">console</span><span style="color: #693a17;">.log</span>(<span style="color: #0b6125;">'Condition 2'</span>)],
[_.constant(condition3), () <span style="color: #794938;">=</span><span style="color: #794938;">></span> <span style="color: #bf4f24;">console</span><span style="color: #693a17;">.log</span>(<span style="color: #0b6125;">'Condition 3'</span>)]
]);
doStuff();
<span style="color: #5a525f; font-style: italic;">// -> Condition 2</span>
</pre>
<br />
For each of the condition constants that we defined above, we're using the <span style="font-family: "courier new" , "courier" , monospace;">_.constant()</span> function in <span style="font-family: "courier new" , "courier" , monospace;">_.cond()</span>. This creates a function that just returns the argument that is passed to it. As you can see, <span style="font-family: "courier new" , "courier" , monospace;">console.log('Condition 2')</span> is called because the function returned by <span style="font-family: "courier new" , "courier" , monospace;">_.constant(condition2)</span> returns true.<br />
<br />
It's easy to add new pairs to <span style="font-family: "courier new" , "courier" , monospace;">_.cond()</span> as the need arises. You can have 20 different execution paths, and it's just as easy to maintain as 2 paths.<br />
<br />
In this example, we're using static values as our conditions. This means that <span style="font-family: "courier new" , "courier" , monospace;">doStuff()</span> will always follow the same path, which kind of defeats the purpose of this type of code. Instead, we want the path chosen by <span style="font-family: "courier new" , "courier" , monospace;">_.cond()</span> to reflect the current state of the app:<br />
<br />
<pre style="background: #f9f9f9; color: #080808;"><span style="color: #a71d5d; font-style: italic;">const</span> app <span style="color: #794938;">=</span> {
condition1: <span style="color: #811f24; font-weight: 700;">false</span>,
condition2: <span style="color: #811f24; font-weight: 700;">false</span>,
condition3: <span style="color: #811f24; font-weight: 700;">true</span>
};
</pre>
<br />
Instead of using <span style="font-family: "courier new" , "courier" , monospace;">_.const()</span>, we'll have to somehow pass the app into each evaluator function in <span style="font-family: "courier new" , "courier" , monospace;">_.cond()</span>:<br />
<br />
<pre style="background: #f9f9f9; color: #080808;"><span style="color: #a71d5d; font-style: italic;">const</span> doStuff <span style="color: #794938;">=</span> _.cond([
[_.property(<span style="color: #0b6125;">'condition1'</span>), () <span style="color: #794938;">=</span><span style="color: #794938;">></span> <span style="color: #bf4f24;">console</span><span style="color: #693a17;">.log</span>(<span style="color: #0b6125;">'Condition 1'</span>)],
[_.property(<span style="color: #0b6125;">'condition2'</span>), () <span style="color: #794938;">=</span><span style="color: #794938;">></span> <span style="color: #bf4f24;">console</span><span style="color: #693a17;">.log</span>(<span style="color: #0b6125;">'Condition 2'</span>)],
[_.property(<span style="color: #0b6125;">'condition3'</span>), () <span style="color: #794938;">=</span><span style="color: #794938;">></span> <span style="color: #bf4f24;">console</span><span style="color: #693a17;">.log</span>(<span style="color: #0b6125;">'Condition 3'</span>)]
]);
</pre>
<br />
The <span style="font-family: "courier new" , "courier" , monospace;">_.property()</span> function creates a new function that returns the given property value of an argument. This is where the <span style="font-family: "courier new" , "courier" , monospace;">_.cond()</span> approach really shines: we can pass arguments to the function that it creates. Here, we want to pass it the <span style="font-family: "courier new" , "courier" , monospace;">app</span> object so that we can process its state:<br />
<br />
<pre style="background: #f9f9f9; color: #080808;">doStuff(app);
<span style="color: #5a525f; font-style: italic;">// -> Condition 3</span>
app.condition1 <span style="color: #794938;">=</span> <span style="color: #811f24; font-weight: 700;">true</span>;
app.condition3 <span style="color: #794938;">=</span> <span style="color: #811f24; font-weight: 700;">false</span>;
doStuff(app);
<span style="color: #5a525f; font-style: italic;">// -> Condition 1</span>
</pre>
<br />
When <span style="font-family: "courier new" , "courier" , monospace;">doStuff()</span> is called the first time, the <span style="font-family: "courier new" , "courier" , monospace;">console.log('Condition 3')</span> path is executed. Then, we change the state of <span style="font-family: "courier new" , "courier" , monospace;">app</span> so that <span style="font-family: "courier new" , "courier" , monospace;">condition1</span> is true and <span style="font-family: "courier new" , "courier" , monospace;">condition3</span> is false. When <span style="font-family: "courier new" , "courier" , monospace;">doStuff()</span> is called again with <span style="font-family: "courier new" , "courier" , monospace;">app</span> as the argument, the <span style="font-family: "courier new" , "courier" , monospace;">console.log('Condition 1')</span> path is executed.<br />
<br />
So far, we've been composing functions that use <span style="font-family: "courier new" , "courier" , monospace;">console.log()</span> to print values. If you write smaller functions that return values instead of simply printing them, you can combine them to build more complex logic. Think of this as an alternative to implementing nested <span style="font-family: "courier new" , "courier" , monospace;">if</span> statements.<br />
<br />
As an example, suppose we have the following two functions:<br />
<br />
<pre style="background: #f9f9f9; color: #080808;"><span style="color: #a71d5d; font-style: italic;">const</span> cond1 <span style="color: #794938;">=</span> _.cond([
[_.partial(_.eq, <span style="color: #811f24; font-weight: 700;">1</span>), _.constant(<span style="color: #0b6125;">'got 1'</span>)],
[_.partial(_.eq, <span style="color: #811f24; font-weight: 700;">2</span>), _.constant(<span style="color: #0b6125;">'got 2'</span>)]
]);
<span style="color: #a71d5d; font-style: italic;">const</span> cond2 <span style="color: #794938;">=</span> _.cond([
[_.partial(_.eq, <span style="color: #0b6125;">'one'</span>), _.constant(<span style="color: #0b6125;">'got one'</span>)],
[_.partial(_.eq, <span style="color: #0b6125;">'two'</span>), _.constant(<span style="color: #0b6125;">'got two'</span>)]
]);
</pre>
<br />
These functions themselves follow the same implementation approach, using <span style="font-family: "courier new" , "courier" , monospace;">_.cond()</span>. For example, <span style="font-family: "courier new" , "courier" , monospace;">cond1()</span> will return the string <span style="font-family: "courier new" , "courier" , monospace;">'got 1'</span> or <span style="font-family: "courier new" , "courier" , monospace;">'got 2'</span>, depending on the number supplied as an argument. Likewise, <span style="font-family: "courier new" , "courier" , monospace;">cond2()</span> will return <span style="font-family: "courier new" , "courier" , monospace;">'got one'</span> or <span style="font-family: "courier new" , "courier" , monospace;">'got two'</span>, depending on the string argument value.<br />
<br />
While we can use both of these functions on their own, we can also use them to compose another function. For example, we could write an <span style="font-family: "courier new" , "courier" , monospace;">if</span> statement that would determine which one of these functions to call:<br />
<br />
<pre style="background: #f9f9f9; color: #080808;"><span style="color: #794938;">if</span> (_.<span style="color: #693a17;">isFinite</span>(val)) {
cond1(val);
} <span style="color: #794938;">else</span> <span style="color: #794938;">if</span> (_.isString(val)) {
cond2(val);
}
</pre>
<br />
Remember, this approach isn't very portable. To make it portable, in the sense that we don't have to write the same <span style="font-family: "courier new" , "courier" , monospace;">if</span> statement all over the place, we could wrap the whole thing in a function. Or, we could just use <span style="font-family: "courier new" , "courier" , monospace;">_.cond()</span> to compose it:<br />
<br />
<pre style="background: #f9f9f9; color: #080808;"><span style="color: #a71d5d; font-style: italic;">const</span> cond3 <span style="color: #794938;">=</span> _.cond([
[_.isFinite, cond1],
[_.isString, cond2]
]);
cond3(<span style="color: #811f24; font-weight: 700;">1</span>);
<span style="color: #5a525f; font-style: italic;">// -> "got 1"</span>
cond3(<span style="color: #811f24; font-weight: 700;">2</span>);
<span style="color: #5a525f; font-style: italic;">// -> "got 2"</span>
cond3(<span style="color: #0b6125;">'one'</span>);
<span style="color: #5a525f; font-style: italic;">// -> "got one"</span>
cond3(<span style="color: #0b6125;">'two'</span>);
<span style="color: #5a525f; font-style: italic;">// -> "got two"</span>
</pre>
<br />
Using <span style="font-family: "courier new" , "courier" , monospace;">_.cond()</span>, you can compose complex logic by reusing existing functions. This means that you can keep using these smaller functions where they're needed, and you can use them as pieces of larger functions.Adam Boduchhttp://www.blogger.com/profile/00484502507931628726noreply@blogger.com0tag:blogger.com,1999:blog-3531969847869413627.post-90358101985720193542017-05-29T10:08:00.000-04:002017-05-29T10:08:59.399-04:00Learning jQuery, Fifth EditionI'm pleased to announce the <a href="http://a.co/g4teKzs">availability</a> of <a href="https://www.packtpub.com/web-development/learning-jquery-3x-fifth-edition">Learning jQuery 3</a>. This is the fifth edition of the book, and given its track record, I didn't want to diverge from what has worked so well over all these years.<br />
<br />
<a name='more'></a><br />
The major updates are including changes in this edition include bringing the reader up to speed with jQuery 3, and utilizing new JavaScript language features. More has changed in the JavaScript language than jQuery since the fourth edition of this book. So in addition to using the most recent version of the library, you get to see how it looks in the context of modern JavaScript development. I think it looks pretty good.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-NnK22qKjNpo/WSwq8785_qI/AAAAAAAAK78/9sJLZ0_s0SEwext9BbVhacP64QKntGdawCLcB/s1600/B05297.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="373" data-original-width="302" height="320" src="https://1.bp.blogspot.com/-NnK22qKjNpo/WSwq8785_qI/AAAAAAAAK78/9sJLZ0_s0SEwext9BbVhacP64QKntGdawCLcB/s320/B05297.jpg" width="259" /></a></div>
<br />Adam Boduchhttp://www.blogger.com/profile/00484502507931628726noreply@blogger.com0tag:blogger.com,1999:blog-3531969847869413627.post-66716912191549782402017-03-01T10:12:00.000-05:002017-03-01T10:15:05.749-05:00React and React NativeI'm pleased to announce that my latest book, <a href="https://www.packtpub.com/web-development/react-and-react-native">React and React Native</a> is now <a href="https://www.amazon.com/React-Native-Adam-Boduch/dp/1786465655">available</a>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-EqhLtVFqZCY/WLbjDtTWr8I/AAAAAAAAKqg/W1YTVMDH97oIvBfZyrxwwgtnLc17NcBnwCLcB/s1600/5687.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://1.bp.blogspot.com/-EqhLtVFqZCY/WLbjDtTWr8I/AAAAAAAAKqg/W1YTVMDH97oIvBfZyrxwwgtnLc17NcBnwCLcB/s320/5687.jpg" width="259" /></a></div>
<br />
<a name='more'></a><br />
This is by far, the most time I've spent working on a single title. That's because it's like two books in one. However, I don't see React and React Native as two technologies to learn indepently of one another. It's best to learn them both at the same time.<br />
<br />
I've structured this book into three parts: React, React Native, and React Architecture. The overarching theme is that React is a thin rendering abstraction that sits on top of a target device. Keeping this in mind while learning React will ultimately lead to better code, in my opinion. I hope I've done this idea justice.Adam Boduchhttp://www.blogger.com/profile/00484502507931628726noreply@blogger.com0tag:blogger.com,1999:blog-3531969847869413627.post-12662071045530506102016-05-17T16:13:00.000-04:002016-05-17T16:13:21.133-04:00Flux Architecture<p><a href="https://facebook.github.io/flux/">Flux</a> is quickly becoming the standard architecture for building large-scale applications. It's the topic of my latest book, <a href="https://www.packtpub.com/web-development/flux-architecture">Flux Architecture</a>, available on <a href="http://www.amazon.com/Flux-Architecture-Adam-Boduch/dp/1786465817/">Amazon</a>.</p>
<a name='more'></a>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-DdsQGXm9zJk/VxTi5LmWy8I/AAAAAAAAJJk/lOaYqcnr-F4uuh6EMvk66ceRm6Mgl-4TgCLcB/s1600/flux-architecture.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://1.bp.blogspot.com/-DdsQGXm9zJk/VxTi5LmWy8I/AAAAAAAAJJk/lOaYqcnr-F4uuh6EMvk66ceRm6Mgl-4TgCLcB/s320/flux-architecture.jpg" width="259" /></a></div>
<p>When a first started learning Flux, about a year ago, I was confused. I was so used to using frameworks that prescribe the exact way that something should be implemented. It took me a while to realize that Flux is just a set of principles — there is no framework. Well, that's not entirely true, there's plenty of Flux libraries out there now. What I really like is that they're all variations on the same Flux principles. Facebook made the call to release Flux as a set of documentation, a reference implementation for a dispatcher component, and a handful of examples. The rest is up to us to figure out, because we all have our own implementation idiosyncrasies.</p>
<p>What I set out to accomplishing with this book was to help others through the same Flux learning process that I had experienced. The content of the book is my interpretation of Flux, I hope it will prove helpful for a few large-scale JavaScript projects out there.</p>Adam Boduchhttp://www.blogger.com/profile/00484502507931628726noreply@blogger.com0tag:blogger.com,1999:blog-3531969847869413627.post-3524026402133560972015-12-14T16:12:00.000-05:002015-12-14T16:12:04.173-05:00JavaScript ConcurrencyI'm pleased to announce my latest book — <strong>JavaScript Concurrency</strong> — from <a href="https://www.packtpub.com/web-development/javascript-concurrency">Packt Publishing</a> and available on <a href="http://www.amazon.com/JavaScript-Concurrency-Adam-Boduch/dp/1785889230">Amazon</a>. This is unique book in that it's more than just a basic rundown of all the concurrency features available to our JavaScript code. Instead, the book uses features like promises, generators, and web workers, as teaching tools for thinking concurrently. There's no shortage of concurrency books out there that teach us how to think in terms of concurrency. This one is specific to JavaScript, and the theme aim is to show you how to write JavaScript code that's concurrent by default, instead of a bolt-on capability. Here's an overview of the chapters:
<a name='more'></a>
<ol>
<li><strong>Why JavaScript Concurrency?</strong> JavaScript isn't what comes to mind when we think about concurrent programming languages. Yet, there's a ton of valid use cases for concurrency in JavaScript, and in recent versions of the language, we can actually write concurrent code.</li>
<li><strong>The JavaScript Execution Model:</strong> What's actually happening in the browser when we're making an API request, or when we're scheduling a function call using <code>setTimeout()</code>? The nature of JavaScript engines has a strong influence over the kind of concurrent code we can write.</li>
<li><strong>Synchronizing with Promises:</strong> Promises are the key to enabling concurrency by default in JavaScript code. Whether we're synchronizing network requests, web worker data, or both, we can use promises to hide this messy synchronization logic.</li>
<li><strong>Lazy Evaluation with Generators:</strong> Generators are used to conserve on CPU and memory by <em>not</em> doing things — being lazy in other words. We use generators to execute different pieces of code concurrently, to cooperatively find the most efficient approach.</li>
<li><strong>Working with Workers:</strong> Web workers are how we get true parallelism into our applications. JavaScript code does a lot of work in the browser, compared to 10 years ago — it needs all the help it can get from the CPU.</li>
<li><strong>Practical Parallelism:</strong> Using concurrency to solve the right kinds of problems. It boils down to writing code that's concurrent by default — this is very difficult if we try to parallelize every problem.</li>
<li><strong>Abstracting Concurrency:</strong> The best way to write concurrent code by default is to not have to write concurrent code at all. When our concurrency abstractions are consistent, the actual problem of concurrency fades into the background, allowing us to focus on code that matters — delivering features.</li>
<li><strong>Evented IO with NodeJS:</strong> The IO event loop in NodeJS is how we write concurrent JavaScript code for the back-end. It's essential to understand how this mechanism works in a web environment where there's lots of IO.</li>
<li><strong>Advanced NodeJS Concurrency:</strong> Node isn't limited to an IO event loop as it's only means of concurrency. Process clusters and micro-services also just two of the advanced approaches to concurrency with Node.</li>
<li><strong>Building a Concurrent Application:</strong> The only way to proficiency with any programming technique is to use it to build applications. Nowhere is this more true than with understanding the implications of concurrency in a JavaScript application.</li>
</ol>
<div class="separator" style="clear: both; text-align: center;"><a href="https://www.packtpub.com/web-development/javascript-concurrency" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://d255esdrn735hr.cloudfront.net/sites/default/files/imagecache/ppv4_main_book_cover/B05133_MockupCover_Normal_.jpg" /></a></div>Adam Boduchhttp://www.blogger.com/profile/00484502507931628726noreply@blogger.com0tag:blogger.com,1999:blog-3531969847869413627.post-3783302254932271062015-07-24T09:39:00.000-04:002015-07-24T09:39:01.845-04:00Efficient counting with lodash<p>Counting with lodash is easy. A lot of the time, an array is returned, so I just need to read the <code>length</code> property. If I'm working with a chain, I can simply use the <code>size()</code> function. What I like about <code>size()</code> is that it works with anything — strings, arrays, and objects. However, using <code>length</code> or <code>size()</code> isn't always the most efficient answer.</p>
<a name='more'></a>
<p>Consider the following pattern:</p>
<div class="highlight"><pre><span class="nx">_</span><span class="p">(</span><span class="nx">hugeCollection</span><span class="p">)</span>
<span class="p">.</span><span class="nx">filter</span><span class="p">({</span> <span class="nx">enabled</span><span class="o">:</span> <span class="kc">true</span> <span class="p">})</span>
<span class="p">.</span><span class="nx">size</span><span class="p">();</span>
</pre></div>
<p>Here we have a rather large collection, and we're using the <code>filter()</code> function to retrieve only the items we need. This builds a new collection, and we call <code>size()</code> on it. Apart from working with many types of values, <code>size()</code> is kind of limiting here. Why should I have to build a new collection I never use? It's the <em>count</em> we're interested in, and nothing more.</p>
<p>Let's see if we can fix this situation with a mixin:</p>
<div class="highlight"><pre><span class="nx">_</span><span class="p">.</span><span class="nx">mixin</span><span class="p">({</span>
<span class="nx">count</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">collection</span><span class="p">,</span> <span class="nx">predicate</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">predicate</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">collection</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span>
<span class="p">}</span>
<span class="kd">var</span> <span class="nx">callback</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">callback</span><span class="p">(</span><span class="nx">predicate</span><span class="p">);</span>
<span class="k">return</span> <span class="nx">_</span><span class="p">.</span><span class="nx">reduce</span><span class="p">(</span><span class="nx">collection</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">result</span><span class="p">,</span> <span class="nx">item</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">callback</span><span class="p">(</span><span class="nx">item</span><span class="p">)</span> <span class="o">?</span> <span class="nx">result</span> <span class="o">+</span> <span class="mi">1</span> <span class="o">:</span> <span class="nx">result</span><span class="p">;</span>
<span class="p">},</span> <span class="mi">0</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">},</span> <span class="p">{</span> <span class="nx">chain</span><span class="o">:</span> <span class="kc">false</span> <span class="p">});</span>
</pre></div>
<p>This is a simple <code>count()</code> mixin, which does essentially the same thing as <code>size()</code>, it's <em>how</em> it does it that's different. The idea is to reduce the collection to a count. It does by calling <code>reduce()</code>, and incrementing the count each item the predicate passes. It's actually following the filter pattern, only when a match is found, the count is incremented instead of adding the item to the new collection.</p>
<p>Let's see how this thing works, shall we?</p>
<div class="highlight"><pre><span class="kd">var</span> <span class="nx">collection</span> <span class="o">=</span> <span class="p">[</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span> <span class="p">];</span>
<span class="nx">_</span><span class="p">.</span><span class="nx">count</span><span class="p">(</span><span class="nx">collection</span><span class="p">);</span>
<span class="c1">// → 3</span>
</pre></div>
<p>We're just getting the length of the collection here, since there's no filtering happening. We could just read <code>collection.length</code> instead, and that's actually what our mixin is doing. When there's no <code>predicate</code> provided, it just returns the length of the collection, and avoids iterating over it.</p>
<p>Let's try adding some basic filtering capabilities.</p>
<div class="highlight"><pre><span class="nx">_</span><span class="p">.</span><span class="nx">count</span><span class="p">(</span><span class="nx">collection</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">item</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">item</span> <span class="o">></span> <span class="mi">1</span><span class="p">;</span>
<span class="p">});</span>
<span class="c1">// → 2</span>
<span class="nx">_</span><span class="p">.</span><span class="nx">count</span><span class="p">(</span><span class="nx">collection</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">item</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">item</span> <span class="o"><</span> <span class="mi">3</span><span class="p">;</span>
<span class="p">});</span>
<span class="c1">// → 2</span>
</pre></div>
<p>Now we're getting somewhere. Despite this being a trivially-small collection, we can see that we didn't have to create a new collection of length 2, only to use the <code>length</code> property. This optimization matters when we're working with large collections, because it avoids allocating large amounts of memory and the subsequent CPU cycles to garbage collect it.</p>
<p>Let's try a different kind of filter.</p>
<div class="highlight"><pre><span class="nx">_</span><span class="p">.</span><span class="nx">count</span><span class="p">(</span><span class="nx">collection</span><span class="p">,</span> <span class="nx">_</span><span class="p">.</span><span class="nx">partial</span><span class="p">(</span><span class="nx">_</span><span class="p">.</span><span class="nx">isEqual</span><span class="p">,</span> <span class="mi">2</span><span class="p">));</span>
</pre></div>
<p>Here we're aiming for some more specific criteria — the item must be <em>exactly</em> <code>2</code>. But do we really need to make our own callback function for that, or can we use a short-hand?</p>
<div class="highlight"><pre><span class="kd">var</span> <span class="nx">collection</span> <span class="o">=</span> <span class="p">[</span>
<span class="p">{</span> <span class="nx">enabled</span><span class="o">:</span> <span class="kc">true</span> <span class="p">},</span>
<span class="p">{</span> <span class="nx">enabled</span><span class="o">:</span> <span class="kc">false</span> <span class="p">},</span>
<span class="p">{</span> <span class="nx">enabled</span><span class="o">:</span> <span class="kc">true</span> <span class="p">},</span>
<span class="p">{</span> <span class="nx">enabled</span><span class="o">:</span> <span class="kc">false</span> <span class="p">}</span>
<span class="p">];</span>
<span class="nx">_</span><span class="p">.</span><span class="nx">count</span><span class="p">(</span><span class="nx">collection</span><span class="p">,</span> <span class="s1">'enabled'</span><span class="p">);</span>
<span class="c1">// → 2</span>
<span class="nx">_</span><span class="p">.</span><span class="nx">count</span><span class="p">(</span><span class="nx">collection</span><span class="p">,</span> <span class="p">{</span> <span class="nx">enabled</span><span class="o">:</span> <span class="kc">false</span> <span class="p">});</span>
<span class="c1">// → 2</span>
</pre></div>
<p>There's two shorthands. The first looks for items with a <em>thruthy</em> <code>enabled</code> property. The second shorthand looks for items where the <code>enabled</code> property is <code>false</code>. The reason these shorthands are possible is because our mixin is using the <code>callback()</code> function to turn the passed-in <code>predicate</code> into a callable function, even when strings or objects are passed.</p>
Adam Boduchhttp://www.blogger.com/profile/00484502507931628726noreply@blogger.com0tag:blogger.com,1999:blog-3531969847869413627.post-13993244473398324242015-06-26T12:23:00.000-04:002015-06-26T12:23:22.028-04:00JavaScript at Scale<p>My latest book, <a href="https://www.packtpub.com/web-development/javascript-scale">JavaScript at Scale</a> is available for pre-order now at Packt Publishing, and at <a href="http://www.amazon.com/JavaScript-at-Scale-Adam-Boduch/dp/1785282158/">Amazon</a>. It'll be fully published in July 2015.</p>
<p>The JavaScript ecosystem is filled to the brim, to the point of overflowing actually, with libraries and frameworks. In this mix, there's some truly remarkable technology. In fact, it's hard to make decisions, given all the overlapping functionality and capabilities. What I've found over the past couple of years is that the architectural considerations get lost in all this choice. That is to say, that we may not be selecting the tool that's best for the front-end architecture we've set out to build. The choice of front-end technology is chosen more so on the generic capabilities of the framework. While TODO applications are a great springboard, to familiarize ourselves with the nature of the technology, that can only take us so far.</p>
<a name='more'></a>
<p>JavaScript at Scale is a book about the influencers of scale in front-end applications. It aims to address the various scenarios in which our applications need to scale. It covers the <i>why</i> of JavaScript scaling, in other words. This is important information to have at our disposal when making architectural decisions, or when selecting a piece of technology to use in our application. With it, we can make informed choices about the scalability of our code, because code for one application is going to have different scaling characteristics than another application.</p>
<p>Frameworks and libraries are great, as they solve a lot of problems for us. Including scalability, but only in <i>narrow scopes</i>. It's time to start thinking about scalable JavaScript <i>applications as a whole</i>, rather than just scalable components.</p>
<p>Big thanks to <a href="http://augustmarcello.com">August Marcello III</a> for the fantastic technical editing work.</p>
Adam Boduchhttp://www.blogger.com/profile/00484502507931628726noreply@blogger.com0tag:blogger.com,1999:blog-3531969847869413627.post-73661034329285276782015-03-10T09:08:00.000-04:002015-03-10T09:08:04.814-04:00Fixed argument counts with lodash ary()<p>When using functions as callbacks to lodash collection functions, we have to be careful to get the arguments right. This is because functions like <a href="https://lodash.com/docs#map">map()</a> actually pass more than just the current collection item as the first argument, which is all we need in the majority of cases. It also passes the current index, and the collection itself. Using callback functions that only make use of the first argument is easy. They just work. But if you want to use a function that takes more than just the current item as arguments, then weird things can happen.</p>
<a name='more'></a>
<p>The most common scenario for having callback functions that accept multiple arguments is when we compose functions using the lodash higher-order function tools. For example, let's say we have the following collection:</p>
<div class="highlight"><pre><span class="kd">var</span> <span class="nx">collection</span> <span class="o">=</span> <span class="p">[</span>
<span class="p">[</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span> <span class="p">],</span>
<span class="p">[</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span> <span class="p">],</span>
<span class="p">[</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span> <span class="p">]</span>
<span class="p">];</span>
</pre></div>
<p>Now, let's compose a callback function using <a href="https://lodash.com/docs#partialRight">partialRight()</a>, and use it to <code>map()</code> our collection:</p>
<div class="highlight"><pre><span class="nx">_</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span><span class="nx">collection</span><span class="p">,</span> <span class="nx">_</span><span class="p">.</span><span class="nx">partialRight</span><span class="p">(</span><span class="nx">_</span><span class="p">.</span><span class="nx">at</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">2</span><span class="p">));</span>
<span class="c1">// →</span>
<span class="c1">// [</span>
<span class="c1">// [ 1, 2, 2, 2, 1, 3 ],</span>
<span class="c1">// [ 2, 2, 2, 2, 1, 3 ],</span>
<span class="c1">// [ 3, 2, 2, 2, 1, 3 ]</span>
<span class="c1">// ] </span>
</pre></div>
<p>Yikes, that's definitely not what we had in mind. The issue, is that our partial function is expecting three arguments — the first two are already applied. We just want the current collection item applied as the first argument. But instead, we get three unexpected arguments, hence the wacky output. Let's use the <a href="https://lodash.com/docs#ary">ary()</a> function to fix the number of arguments provided to our callback:</p>
<div class="highlight"><pre><span class="nx">_</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span><span class="nx">collection</span><span class="p">,</span> <span class="nx">_</span><span class="p">.</span><span class="nx">ary</span><span class="p">(</span><span class="nx">_</span><span class="p">.</span><span class="nx">partialRight</span><span class="p">(</span><span class="nx">_</span><span class="p">.</span><span class="nx">at</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">2</span><span class="p">),</span> <span class="mi">1</span><span class="p">));</span>
<span class="c1">// →</span>
<span class="c1">// [</span>
<span class="c1">// [ 1, 3 ],</span>
<span class="c1">// [ 1, 3 ],</span>
<span class="c1">// [ 1, 3 ]</span>
<span class="c1">// ]</span>
</pre></div>
<p>That's more like it. By wrapping our callback function using <code>ary()</code>, we've specified that only one argument get's through to the callback function, in this case, it's the current collection item. The <code>ary()</code> function is relatively new. So the technique I used in <a href="https://www.packtpub.com/web-development/lo-dash-essentials">Lo-Dash Essentials</a> involves using <a href="https://lodash.com/docs#flowRight">compose()</a> and <a href="https://lodash.com/docs#identity">identity()</a> to achieve the same result:</p>
<div class="highlight"><pre><span class="nx">_</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span><span class="nx">collection</span><span class="p">,</span>
<span class="nx">_</span><span class="p">.</span><span class="nx">compose</span><span class="p">(</span><span class="nx">_</span><span class="p">.</span><span class="nx">partialRight</span><span class="p">(</span><span class="nx">_</span><span class="p">.</span><span class="nx">at</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">2</span><span class="p">),</span> <span class="nx">_</span><span class="p">.</span><span class="nx">identity</span><span class="p">));</span>
</pre></div>
<p>The <code>identity()</code> function just returns the first argument that's passed to it. So this is a valid technique for getting only the first argument. The <code>ary()</code> function makes this more explicit, and adds the ability to specify exact argument counts.</p>Adam Boduchhttp://www.blogger.com/profile/00484502507931628726noreply@blogger.com0tag:blogger.com,1999:blog-3531969847869413627.post-37034463448295430132015-03-06T13:25:00.000-05:002015-03-06T13:25:32.125-05:00Planting values in lodash wrappers<p>Wrapping values in lodash let's us compose chains of functionality. There's two reasons to do this. The first is that the resulting code is a lot more compact and readable, especially if each chained call is on it's own line. The second reason, now that lazy evaluation is supported in lodash, is efficiency. Some chains won't iterate over the entire collection if it doesn't have to. Now there's a third reason — the <a href="https://lodash.com/docs#prototype-plant">plant()</a> function. This function was made available after <a href="https://www.packtpub.com/web-development/lo-dash-essentials">Lo-Dash Essentials</a> was published, so I'll talk about it here.</p>
<a name='more'></a>
<p>As our lodash code grows, we'll start to notice lot's of wrappers with chained function calls. Many of which are similar. Before <code>plant()</code>, wrappers weren't reusable with other values. With the introduction of <code>plant()</code>, we can start reusing our wrappers in interesting ways. Let's make a generic function that plants new values into wrappers.</p>
<div class="highlight"><pre><span class="kd">function</span> <span class="nx">plantValue</span><span class="p">(</span><span class="nx">wrapper</span><span class="p">,</span> <span class="nx">value</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">_</span><span class="p">.</span><span class="nx">isUndefined</span><span class="p">(</span><span class="nx">value</span><span class="p">))</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">wrapper</span><span class="p">;</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">wrapper</span><span class="p">.</span><span class="nx">plant</span><span class="p">(</span><span class="nx">value</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
<p>The <code>plantValue()</code> function takes two arguments. The first is a lodash wrapper. The second is an optional value, if provided, it is <i>planted</i> into the wrapper. This actually creates a new wrapper, so there's no side-effects on the wrapper argument. Let's make some functions that use <code>plantValue()</code> now.</p>
<div class="highlight"><pre><span class="kd">function</span> <span class="nx">odds</span><span class="p">(</span><span class="nx">wrapper</span><span class="p">,</span> <span class="nx">value</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">plantValue</span><span class="p">(</span><span class="nx">wrapper</span><span class="p">.</span><span class="nx">filter</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">item</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">item</span> <span class="o">%</span> <span class="mi">2</span><span class="p">;</span>
<span class="p">}),</span> <span class="nx">value</span><span class="p">);</span>
<span class="p">}</span>
<span class="kd">function</span> <span class="nx">evens</span><span class="p">(</span><span class="nx">wrapper</span><span class="p">,</span> <span class="nx">value</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">plantValue</span><span class="p">(</span><span class="nx">wrapper</span><span class="p">.</span><span class="nx">reject</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">item</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">item</span> <span class="o">%</span> <span class="mi">2</span><span class="p">;</span>
<span class="p">}),</span> <span class="nx">value</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
<p>The <code>odds()</code> and the <code>evens()</code> functions take the same arguments as <code>plantValue()</code>. The first is a lodash <code>wrapper</code>, the second being an optional <code>value</code>. We're using <code>filter()</code> and <code>reject()</code> in these functions to get the odd and even numbers from the wrapper, respectively. The value is just passed through to <code>plantValue()</code>. This means that, for example, we can call <code>evens()</code> with a wrapper, or a wrapper and a value. And this is where the reusable wrapper comes in handy. Let's see how this works.</p>
<div class="highlight"><pre><span class="kd">var</span> <span class="nx">collection</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">shuffle</span><span class="p">(</span><span class="nx">_</span><span class="p">.</span><span class="nx">range</span><span class="p">(</span><span class="mi">100</span><span class="p">));</span>
<span class="kd">var</span> <span class="nx">limitWrapper</span> <span class="o">=</span> <span class="nx">_</span><span class="p">([])</span>
<span class="p">.</span><span class="nx">sortBy</span><span class="p">()</span>
<span class="p">.</span><span class="nx">dropRightWhile</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">item</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">item</span> <span class="o">></span> <span class="mi">50</span><span class="p">;</span>
<span class="p">});</span>
<span class="nx">odds</span><span class="p">(</span><span class="nx">limitWrapper</span><span class="p">,</span> <span class="nx">collection</span><span class="p">).</span><span class="nx">value</span><span class="p">();</span>
<span class="c1">// → [1, 3, 5, 7, 9, 11, 13, 15, 17, 19,</span>
<span class="c1">// 21, 23, 25, 27, 29, 31, 33, 35, 37,</span>
<span class="c1">// 39, 41, 43, 45, 47, 49]</span>
<span class="nx">evens</span><span class="p">(</span><span class="nx">limitWrapper</span><span class="p">,</span> <span class="nx">collection</span><span class="p">).</span><span class="nx">value</span><span class="p">();</span>
<span class="c1">// → [0, 2, 4, 6, 8, 10, 12, 14, 16, 18,</span>
<span class="c1">// 20, 22, 24, 26, 28, 30, 32, 34, 36,</span>
<span class="c1">// 38, 40, 42, 44, 46, 48, 50]</span>
</pre></div>
<p>The <code>limitWrapper</code> is a reusable wrapper we want to apply in several contexts. It sorts the wrapped collection, and takes anything that's under <code>50</code>. We've passed this wrapper to our <code>odds()</code> and <code>evens()</code> invocations. In the results, we can see that the arrays are filtered accordingly, but they're also sorted, and don't contain anything larger than <code>50</code>. The <code>limitWrapper</code> was initially wrapped with an empty array, because we don't have any intention of ever calling <code>value()</code> on <code>limitWrapper</code> directly. Instead, we want to copy the chained function calls — <code>sortBy()</code> and <code>dropRightWhile()</code> — into a new wrapper, with a new value.</p>
<p>Let's see if we can use <code>plantValue()</code> with functions that aren't chainable, like <code>reduce()</code>.</p>
<div class="highlight"><pre><span class="kd">function</span> <span class="nx">sum</span><span class="p">(</span><span class="nx">wrapper</span><span class="p">,</span> <span class="nx">value</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">plantValue</span><span class="p">(</span><span class="nx">wrapper</span><span class="p">,</span> <span class="nx">value</span><span class="p">)</span>
<span class="p">.</span><span class="nx">reduce</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">result</span><span class="p">,</span> <span class="nx">item</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">result</span> <span class="o">+</span> <span class="nx">item</span><span class="p">;</span>
<span class="p">});</span>
<span class="p">}</span>
</pre></div>
Once again, the arguments expected by <code>sum()</code> are a wrapper, followed by an optional value to plant. What's done differently here is that we're calling <code>plantValue()</code> and <i>then</i> calling reduce on the returned wrapper. This is so that our <code>sum()</code> function can return an unwrapped value. The <code>odds()</code> and <code>evens()</code> functions, on the other hand, return wrappers themselves. Which means that we can use these functions to create reusable wrappers.
<div class="highlight"><pre><span class="kd">var</span> <span class="nx">oddsWrapper</span> <span class="o">=</span> <span class="nx">odds</span><span class="p">(</span><span class="nx">limitWrapper</span><span class="p">);</span>
<span class="kd">var</span> <span class="nx">evensWrapper</span> <span class="o">=</span> <span class="nx">evens</span><span class="p">(</span><span class="nx">limitWrapper</span><span class="p">);</span>
<span class="nx">sum</span><span class="p">(</span><span class="nx">oddsWrapper</span><span class="p">,</span> <span class="nx">collection</span><span class="p">);</span>
<span class="c1">// → 625</span>
<span class="nx">sum</span><span class="p">(</span><span class="nx">evensWrapper</span><span class="p">,</span> <span class="nx">collection</span><span class="p">);</span>
<span class="c1">// → 650</span>
</pre></div>
<p>Now we have two more reusable wrappers — <code>oddsWrapper</code> and <code>evensWrapper</code>. These were created by their respective <code>odds()</code> and <code>evens()</code> functions. They each have the <code>limitWrapper</code> embedded as well, because that's what <code>odds()</code> and <code>evens()</code> were called with as their first arguments. If we didn't want this limiting behavior in the <code>oddsWrapper</code>, for instance, we could just pass an empty wrapper instead — <code>_([])</code>. The <code>sum()</code> function can now use the resuable <code>oddsWrapper</code> and <code>evensWrapper</code> instances, planting new values when called.</p>Adam Boduchhttp://www.blogger.com/profile/00484502507931628726noreply@blogger.com0tag:blogger.com,1999:blog-3531969847869413627.post-43017699048404941742015-01-26T16:30:00.000-05:002015-01-27T10:31:19.142-05:00Lo-Dash EssentialsI'm pleased to announce my latest book, <a href="https://www.packtpub.com/web-development/lo-dash-essentials">Lo-Dash Essentials</a>, available now from Packt Publishing. It covers everything you need to get started using Lo-Dash in your projects, as well as some newer features introduced in the 3.0 release.
<div class="separator" style="clear: both; text-align: center;"><a href="https://dz13w8afd47il.cloudfront.net/sites/default/files/imagecache/ppv4_main_book_cover/3867_8330OS_Lo-Dash%20Essentials_Cover.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://dz13w8afd47il.cloudfront.net/sites/default/files/imagecache/ppv4_main_book_cover/3867_8330OS_Lo-Dash%20Essentials_Cover.jpg" /></a></div>
Here's a rough outline of what you'll find in the book:
<ol>
<li><strong>Collections and arrays:</strong> working with collections and arrays
<li><strong>Objects:</strong> working with objects
<li><strong>Functions:</strong> functional programming tools
<li><strong>MapReduce:</strong> mapping and reducing is fundamental to applicative/functional programming in Lo-Dash
<li><strong>Chained function calls:</strong> write elegant, compact code
<li><strong>Application components:</strong> glue functions together that realize larger behavior
<li><strong>Other libraries:</strong> Lo-Dash working alongside other libraries
<li><strong>Internals and performance:</strong> some guiding principles on performance, and how how to get the most of it
</ol>Adam Boduchhttp://www.blogger.com/profile/00484502507931628726noreply@blogger.com0tag:blogger.com,1999:blog-3531969847869413627.post-64970630219375536582014-12-15T14:28:00.000-05:002014-12-15T14:28:01.496-05:00Marionette: Layout Views For Applications<p>Marionette <code>Application</code> instances are kind of like layout views. You can give them regions, and use these regions to show smaller views. There's one important difference, between a layout view an an application. With the latter, there's generally only one. Layout views on the other hand, generally exist in larger numbers. Another difference is with where they get their markup from. The application works with that's already in the DOM while a layout view works with a template that it renders.</p>
<a name='more'></a>
<p>The regions we give to the application instance are the main components of the layout. Things, like header, content, and so on. There's probably not very many regions on a given application. Of course, that all depends on how similar each page of the application is — if they're all the same, then the application might define several regions. Regardless, the application is expecting certain elements to exist in the DOM, depending on how it's regions are configured.</p>
<p>This can be a challenge, since whatever the server returns as the page content, is what the application instance has to work with. Layout views have the advantage of templates. For example, it we don't like the look of a given layout view, we can swap out the template for another with a different design. Or we can swap out the layout view for a different view altogether — the choice is ours. <code>Application</code> instances don't have such freedoms and there are times where this can be useful.</p>
<p>Let's make a basic application and some regions to illustrate the limitation. Here's the markup on the page served to the user, and what our application has to work with:</p>
<div class="highlight"><pre><span class="nt"><head></span>
<span class="nt"><template</span> <span class="na">id=</span><span class="s">"header-template"</span><span class="nt">></span>Header<span class="nt"></template></span>
<span class="nt"><template</span> <span class="na">id=</span><span class="s">"content-template"</span><span class="nt">></span>Content<span class="nt"></template></span>
<span class="nt"><template</span> <span class="na">id=</span><span class="s">"footer-template"</span><span class="nt">></span>Footer<span class="nt"></template></span>
<span class="nt"></head></span>
<span class="nt"><body></span>
<span class="nt"><div</span> <span class="na">class=</span><span class="s">"main"</span><span class="nt">></span>
<span class="nt"><div</span> <span class="na">class=</span><span class="s">"header"</span><span class="nt">></div></span>
<span class="nt"><div</span> <span class="na">class=</span><span class="s">"content"</span><span class="nt">></div></span>
<span class="nt"><div</span> <span class="na">class=</span><span class="s">"footer"</span><span class="nt">></div></span>
<span class="nt"></div></span>
<span class="nt"></body></span>
</pre></div>
<p>As you can see, there's three natural regions for this content — <em>header</em>, <em>content</em>, and <em>footer</em>. You'll also notice there's three templates defined in the header we can use to render the content for these regions:</p>
<div class="highlight"><pre><span class="kd">var</span> <span class="nx">MyApp</span> <span class="o">=</span> <span class="nx">Marionette</span><span class="p">.</span><span class="nx">Application</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span>
<span class="nx">regions</span><span class="o">:</span> <span class="p">{</span>
<span class="nx">header</span><span class="o">:</span> <span class="s1">'.header'</span><span class="p">,</span>
<span class="nx">content</span><span class="o">:</span> <span class="s1">'.content'</span><span class="p">,</span>
<span class="nx">footer</span><span class="o">:</span> <span class="s1">'.footer'</span>
<span class="p">}</span>
<span class="p">});</span>
<span class="kd">var</span> <span class="nx">app</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">MyApp</span><span class="p">();</span>
<span class="nx">app</span><span class="p">.</span><span class="nx">header</span><span class="p">.</span><span class="nx">show</span><span class="p">(</span><span class="k">new</span> <span class="nx">Marionette</span><span class="p">.</span><span class="nx">ItemView</span><span class="p">({</span>
<span class="nx">template</span><span class="o">:</span> <span class="s1">'#header-template'</span>
<span class="p">}));</span>
<span class="nx">app</span><span class="p">.</span><span class="nx">content</span><span class="p">.</span><span class="nx">show</span><span class="p">(</span><span class="k">new</span> <span class="nx">Marionette</span><span class="p">.</span><span class="nx">ItemView</span><span class="p">({</span>
<span class="nx">template</span><span class="o">:</span> <span class="s1">'#content-template'</span>
<span class="p">}));</span>
<span class="nx">app</span><span class="p">.</span><span class="nx">footer</span><span class="p">.</span><span class="nx">show</span><span class="p">(</span><span class="k">new</span> <span class="nx">Marionette</span><span class="p">.</span><span class="nx">ItemView</span><span class="p">({</span>
<span class="nx">template</span><span class="o">:</span> <span class="s1">'#footer-template'</span>
<span class="p">}));</span>
</pre></div>
<p>Nice and simple, we've sliced our page content into regions, and filled those regions with content. Notice that the application behaves a lot like a layout view. We can add regions, and show views in them later on. That's because like a layout view, an <code>Application</code> is instantiated with a <em>region manager</em>, something that takes care of instantiating new regions and placing them into the DOM. What the application is missing is the ability to render a template, and use that as the available region management markup.</p>
<p>This poses a problem because the application is now tightly-coupled to the page content, and how it's structured. Most of the time, this works, because we have total control over the page content, and when/how it changes. But in the event that we don't, or in the event that changing the page content is tricky, it's better to render a template.</p>
<p>It's also better to have all your content rendered by the same template engine. If the rest of your layout views and item views are using Underscore or Handlebars templates, you might as well render the page content using the same tool. Here's a slight modification to our code that allows for this:</p>
<div class="highlight"><pre><span class="kd">var</span> <span class="nx">MyApp</span> <span class="o">=</span> <span class="nx">Marionette</span><span class="p">.</span><span class="nx">Application</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span>
<span class="nx">getRegionManager</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">layout</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">getOption</span><span class="p">(</span><span class="s1">'layout'</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">layout</span><span class="p">)</span> <span class="p">{</span>
<span class="k">new</span> <span class="nx">Marionette</span><span class="p">.</span><span class="nx">Region</span><span class="p">({</span>
<span class="nx">el</span><span class="o">:</span> <span class="s1">'body'</span>
<span class="p">}).</span><span class="nx">show</span><span class="p">(</span><span class="nx">layout</span><span class="p">);</span>
<span class="k">return</span> <span class="nx">layout</span><span class="p">.</span><span class="nx">regionManager</span><span class="p">;</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="k">return</span> <span class="k">new</span> <span class="nx">Marionette</span><span class="p">.</span><span class="nx">RegionManager</span><span class="p">();</span>
<span class="p">}</span>
<span class="p">},</span>
<span class="nx">regions</span><span class="o">:</span> <span class="p">{</span>
<span class="nx">header</span><span class="o">:</span> <span class="s1">'.header'</span><span class="p">,</span>
<span class="nx">content</span><span class="o">:</span> <span class="s1">'.content'</span><span class="p">,</span>
<span class="nx">footer</span><span class="o">:</span> <span class="s1">'.footer'</span>
<span class="p">}</span>
<span class="p">});</span>
<span class="kd">var</span> <span class="nx">layout</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Marionette</span><span class="p">.</span><span class="nx">LayoutView</span><span class="p">({</span>
<span class="nx">className</span><span class="o">:</span> <span class="s1">'main new'</span><span class="p">,</span>
<span class="nx">template</span><span class="o">:</span> <span class="s1">'#new-layout-template'</span>
<span class="p">});</span>
<span class="kd">var</span> <span class="nx">app</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">MyApp</span><span class="p">({</span> <span class="nx">layout</span><span class="o">:</span> <span class="nx">layout</span> <span class="p">});</span>
</pre></div>
<p><code>Application</code> calls the <code>getRegionManager()</code> method to instantiate the region manager. By default, this method returns a new instance of the <code>RegionManager</code> class, and is easy to override. Our implementation of <code>getRegionManager()</code> looks of a <code>layout</code> option. If it's there, it means the caller specified a layout view they want to use for the application. We show the layout view in a new region who's element is the document body. Now, we can return the <code>layout.regionManager</code> property.</p>
<p>You can see that the <code>#new-layout-template</code> template is used to render the body, and we're no longer coupled to whatever the server returns. We simply pass in this new <code>layout</code> view as an option to our application. The rest of the code that populates the various regions remains unchanged, because <code>app.content</code> actually points to <code>layout.content</code>. Same with the other regions.</p>Adam Boduchhttp://www.blogger.com/profile/00484502507931628726noreply@blogger.com0tag:blogger.com,1999:blog-3531969847869413627.post-45999477505975310002014-12-11T14:38:00.000-05:002014-12-11T14:39:19.385-05:00Lo-Dash: Partials and References<p>The <code>partial()</code> function in Lo-Dash is used to compose higher-order functions, with argument values partially applied. So for example, let's say we have a function that accepts a string argument, like <code>console.log()</code>. We can compose a new function that when called, doesn't need to supply a string argument — it'll use the argument value it was composed with. This is especially powerful in contexts where we don't necessarily have control over how the function is called. As is the case with callback functions. Primitive types, like strings and numbers work well as partial arguments. Things like arrays and objects work fine too, if they're passed to <code>partial()</code> as a literal. If a <i>reference</i> is passed as a partial argument, unexpected things start to happen.</p>
<a name='more'></a>
<div class="highlight"><pre><span class="kd">var</span> <span class="nx">app</span> <span class="o">=</span> <span class="p">{</span>
<span class="nx">settings</span><span class="o">:</span> <span class="p">{</span>
<span class="nx">version</span><span class="o">:</span> <span class="mi">1</span>
<span class="p">}</span>
<span class="p">};</span>
<span class="kd">var</span> <span class="nx">version</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">partial</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">settings</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">settings</span><span class="p">.</span><span class="nx">version</span><span class="p">;</span>
<span class="p">},</span> <span class="nx">app</span><span class="p">.</span><span class="nx">settings</span><span class="p">);</span>
</pre></div>
<p>The <code>version()</code> function we've just composed using <code>partial()</code> has a reference passed to it — <code>app.settings</code>. The function itself just returns <code>settings.version</code>. Which means, of course, that <code>version()</code> relies on this reference always being there. Let's put this partial function to the test:</p>
<div class="highlight"><pre><span class="nx">console</span><span class="p">.</span><span class="nx">assert</span><span class="p">(</span><span class="nx">version</span><span class="p">()</span> <span class="o">===</span> <span class="mi">1</span><span class="p">,</span> <span class="s1">'version is 1'</span><span class="p">);</span>
<span class="c1">// → true</span>
<span class="nx">app</span><span class="p">.</span><span class="nx">settings</span><span class="p">.</span><span class="nx">version</span> <span class="o">=</span> <span class="mf">2.0</span><span class="p">;</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">assert</span><span class="p">(</span><span class="nx">version</span><span class="p">()</span> <span class="o">===</span> <span class="mi">2</span><span class="p">,</span> <span class="s1">'version is 2'</span><span class="p">);</span>
<span class="c1">// → true</span>
<span class="nx">app</span><span class="p">.</span><span class="nx">settings</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">extend</span><span class="p">(</span><span class="nx">app</span><span class="p">.</span><span class="nx">settings</span><span class="p">,</span> <span class="p">{</span> <span class="nx">version</span><span class="o">:</span> <span class="mi">3</span> <span class="p">});</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">assert</span><span class="p">(</span><span class="nx">version</span><span class="p">()</span> <span class="o">===</span> <span class="mi">3</span><span class="p">,</span> <span class="s1">'version is 3'</span><span class="p">);</span>
<span class="c1">// → true</span>
<span class="nx">app</span><span class="p">.</span><span class="nx">settings</span> <span class="o">=</span> <span class="p">{</span> <span class="nx">version</span><span class="o">:</span> <span class="mi">4</span> <span class="p">};</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">assert</span><span class="p">(</span><span class="nx">version</span><span class="p">()</span> <span class="o">===</span> <span class="mi">4</span><span class="p">,</span> <span class="s1">'version is 4'</span><span class="p">);</span>
<span class="c1">// → "Assertion failed: version is 4"</span>
</pre></div>
<p>The first assertion checks that the <code>version()</code> function returns the initial value of <code>settings.version</code>. Next, we change the <code>app.settings.version</code> value to <code>2</code>. Since our partial function is referencing the settings object, the next assertion passes, because when it's called, it looks up the new value. Next, we use the <code>extend()</code> function to assign a new object to <code>app.settings</code> — or so it would seem. Notice that the first argument to <code>extend()</code> is the same object that's referenced by <code>value()</code>. This means that we're not overriding this reference, and the assertion passes.</p>
<p>This last statement assigns a new object literal to <code>app.settings</code>. This is enough to kill the reference in the <code>value()</code> partial, as we can see by the failed assertion. It's still referencing the old object. This can lead to very subtle bugs with your partial functions. The assignment statement doesn't look like it would be problematic. Maybe we can construct the referenced property in such a way that it's immune to reference issues:</p>
<div class="highlight"><pre><span class="kd">var</span> <span class="nx">app</span> <span class="o">=</span> <span class="p">{};</span>
<span class="nb">Object</span><span class="p">.</span><span class="nx">defineProperty</span><span class="p">(</span><span class="nx">app</span><span class="p">,</span> <span class="s1">'settings'</span><span class="p">,</span> <span class="p">{</span>
<span class="nx">set</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">value</span><span class="p">)</span> <span class="p">{</span>
<span class="k">this</span><span class="p">.</span><span class="nx">_settings</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">isPlainObject</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">_settings</span><span class="p">)</span> <span class="o">?</span>
<span class="nx">_</span><span class="p">.</span><span class="nx">extend</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">_settings</span><span class="p">,</span> <span class="nx">value</span><span class="p">)</span> <span class="o">:</span> <span class="nx">value</span><span class="p">;</span>
<span class="p">},</span>
<span class="nx">get</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">_</span><span class="p">.</span><span class="nx">isPlainObject</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">_settings</span><span class="p">)</span> <span class="o">?</span>
<span class="k">this</span><span class="p">.</span><span class="nx">_settings</span> <span class="o">:</span> <span class="k">this</span><span class="p">.</span><span class="nx">_settings</span> <span class="o">=</span> <span class="p">{};</span>
<span class="p">}</span>
<span class="p">});</span>
<span class="kd">var</span> <span class="nx">version</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">partial</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">settings</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">settings</span><span class="p">.</span><span class="nx">version</span><span class="p">;</span>
<span class="p">},</span> <span class="nx">app</span><span class="p">.</span><span class="nx">settings</span><span class="p">);</span>
</pre></div>
<p>Here we're manually defining the settings property of our app object using <code>Object.defineProperty()</code>. This let's us implement what happens when the property is assigned a value, and when the property value is accessed. The idea being, we hide the real settings object in a hidden <code>_settings</code> property. When the property is set, we check whether <code>_settings</code> is already an object or not. If so, we can just override existing values with new ones. This keeps the <code>_settings</code> reference in tact.</p>
<p>When the property is read, we simply return the <code>_settings</code> reference. We also need to make sure that the reference already exists before returning it. If it doesn't, we assign an empty object to <code>_settings</code> and return that. Let's put this new approach to the test:</p>
<div class="highlight"><pre><span class="nx">app</span><span class="p">.</span><span class="nx">settings</span> <span class="o">=</span> <span class="p">{</span> <span class="nx">version</span><span class="o">:</span> <span class="mi">1</span> <span class="p">};</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">assert</span><span class="p">(</span><span class="nx">version</span><span class="p">()</span> <span class="o">===</span> <span class="mi">1</span><span class="p">,</span> <span class="s1">'version is 1'</span><span class="p">);</span>
<span class="c1">// → true</span>
<span class="nx">app</span><span class="p">.</span><span class="nx">settings</span> <span class="o">=</span> <span class="p">{</span> <span class="nx">version</span><span class="o">:</span> <span class="mi">2</span> <span class="p">};</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">assert</span><span class="p">(</span><span class="nx">version</span><span class="p">()</span> <span class="o">===</span> <span class="mi">2</span><span class="p">,</span> <span class="s1">'version is 2'</span><span class="p">);</span>
<span class="c1">// → true</span>
</pre></div>
<p>That's better — assigning brand new object literals to <code>app.settings</code> doesn't break our <code>version()</code> partial function. Let's now see if we can achieve similar results with references to arrays:</p>
<div class="highlight"><pre><span class="kd">var</span> <span class="nx">app</span> <span class="o">=</span> <span class="p">{};</span>
<span class="nb">Object</span><span class="p">.</span><span class="nx">defineProperty</span><span class="p">(</span><span class="nx">app</span><span class="p">,</span> <span class="s1">'users'</span><span class="p">,</span> <span class="p">{</span>
<span class="nx">set</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">value</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">_</span><span class="p">.</span><span class="nx">isArray</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">_users</span><span class="p">))</span> <span class="p">{</span>
<span class="k">this</span><span class="p">.</span><span class="nx">_users</span><span class="p">.</span><span class="nx">length</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="k">this</span><span class="p">.</span><span class="nx">_users</span><span class="p">.</span><span class="nx">push</span><span class="p">.</span><span class="nx">apply</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">_users</span><span class="p">,</span> <span class="nx">value</span><span class="p">);</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="k">this</span><span class="p">.</span><span class="nx">_users</span> <span class="o">=</span> <span class="nx">value</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">},</span>
<span class="nx">get</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">_</span><span class="p">.</span><span class="nx">isArray</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">_users</span><span class="p">)</span> <span class="o">?</span>
<span class="k">this</span><span class="p">.</span><span class="nx">_users</span> <span class="o">:</span> <span class="k">this</span><span class="p">.</span><span class="nx">_users</span> <span class="o">=</span> <span class="p">[];</span>
<span class="p">}</span>
<span class="p">});</span>
<span class="kd">var</span> <span class="nx">first</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">partial</span><span class="p">(</span><span class="nx">_</span><span class="p">.</span><span class="nx">first</span><span class="p">,</span> <span class="nx">app</span><span class="p">.</span><span class="nx">users</span><span class="p">),</span>
<span class="nx">last</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">partial</span><span class="p">(</span><span class="nx">_</span><span class="p">.</span><span class="nx">last</span><span class="p">,</span> <span class="nx">app</span><span class="p">.</span><span class="nx">users</span><span class="p">);</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">'Testing array setter/getter'</span><span class="p">);</span>
<span class="nx">app</span><span class="p">.</span><span class="nx">users</span> <span class="o">=</span> <span class="p">[</span> <span class="s1">'user1'</span><span class="p">,</span> <span class="s1">'user2'</span> <span class="p">];</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">assert</span><span class="p">(</span><span class="nx">first</span><span class="p">()</span> <span class="o">===</span> <span class="s1">'user1'</span><span class="p">,</span> <span class="s1">'first is "user1"'</span><span class="p">);</span>
<span class="c1">// → true</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">assert</span><span class="p">(</span><span class="nx">last</span><span class="p">()</span> <span class="o">===</span> <span class="s1">'user2'</span><span class="p">,</span> <span class="s1">'last is "user2"'</span><span class="p">);</span>
<span class="c1">// → true</span>
<span class="nx">app</span><span class="p">.</span><span class="nx">users</span> <span class="o">=</span> <span class="p">[</span> <span class="s1">'user3'</span><span class="p">,</span> <span class="s1">'user4'</span> <span class="p">];</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">assert</span><span class="p">(</span><span class="nx">first</span><span class="p">()</span> <span class="o">===</span> <span class="s1">'user3'</span><span class="p">,</span> <span class="s1">'first is "user3"'</span><span class="p">);</span>
<span class="c1">// → true</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">assert</span><span class="p">(</span><span class="nx">last</span><span class="p">()</span> <span class="o">===</span> <span class="s1">'user4'</span><span class="p">,</span> <span class="s1">'last is "user4"'</span><span class="p">);</span>
<span class="c1">// → true</span>
</pre></div>
<p>This approach is similar to the one taken with objects. The only real difference is that instead of using <code>extend()</code> to assign new values, we're simply resetting the array length to <code>0</code> and pushing the new array onto the existing <code>_users</code> array. The technique is the same — keep the reference in tact for partials that may be using it.</p>Adam Boduchhttp://www.blogger.com/profile/00484502507931628726noreply@blogger.com0tag:blogger.com,1999:blog-3531969847869413627.post-66784430362419594302014-12-09T20:14:00.000-05:002014-12-09T20:14:30.069-05:00Marionette: Simple Text Views For Regions<p>Layout views in Marionette are great, and I think they should be used wherever possible. Any given page should be divided into regions — it's just a good habit to have. There are times when regions are a pain, however, because all you want to render is some simple text. Most of the time, regions will show more complex views that do a fair amount of work. They have templates, they have a model or collection as context, and so on. The challenge is being able to swap out something complex with something simple.</p>
<a name='more'></a>
<p>The approach I've come up with involves defining a generic text view. It's still a view, despite the fact we're only using it to display some simple text, but it's lightweight nonetheless. With something like this in place, I'm less discouraged by regions when I want to do something as pedestrian as render some text in a DOM node. And I get to keep my Marionette patterns in-tact.</p>
<p>Let's create a simple application and layout view so we have some regions to work with:</p>
<div class="highlight"><pre><span class="kd">var</span> <span class="nx">layout</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Marionette</span><span class="p">.</span><span class="nx">LayoutView</span><span class="p">({</span>
<span class="nx">template</span><span class="o">:</span> <span class="nx">_</span><span class="p">.</span><span class="nx">template</span><span class="p">(</span><span class="s1">'<p></p><p></p>'</span><span class="p">),</span>
<span class="nx">regions</span><span class="o">:</span> <span class="p">{</span> <span class="nx">first</span><span class="o">:</span> <span class="s1">'p:first'</span><span class="p">,</span> <span class="nx">last</span><span class="o">:</span> <span class="s1">'p:last'</span> <span class="p">}</span>
<span class="p">});</span>
<span class="kd">var</span> <span class="nx">application</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Marionette</span><span class="p">.</span><span class="nx">Application</span><span class="p">({</span>
<span class="nx">regions</span><span class="o">:</span> <span class="p">{</span> <span class="nx">main</span><span class="o">:</span> <span class="s1">'body'</span> <span class="p">}</span>
<span class="p">});</span>
<span class="nx">application</span><span class="p">.</span><span class="nx">main</span><span class="p">.</span><span class="nx">show</span><span class="p">(</span><span class="nx">layout</span><span class="p">);</span>
</pre></div>
<p>Now there's two regions that are empty <code><p/></code> elements — <code>first</code> and <code>last</code>. Let's now take a look at how we would define a generic text view that will take some text we want displayed, and render it:</p>
<div class="highlight"><pre><span class="kd">var</span> <span class="nx">TextView</span> <span class="o">=</span> <span class="nx">Marionette</span><span class="p">.</span><span class="nx">ItemView</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span>
<span class="nx">initialize</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="k">this</span><span class="p">.</span><span class="nx">template</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">wrap</span><span class="p">(</span>
<span class="k">this</span><span class="p">.</span><span class="nx">getOption</span><span class="p">(</span><span class="s1">'text'</span><span class="p">),</span>
<span class="nx">_</span><span class="p">.</span><span class="nx">identity</span>
<span class="p">);</span>
<span class="p">}</span>
<span class="p">});</span>
<span class="nx">layout</span><span class="p">.</span><span class="nx">first</span><span class="p">.</span><span class="nx">show</span><span class="p">(</span><span class="k">new</span> <span class="nx">TextView</span><span class="p">({</span> <span class="nx">text</span><span class="o">:</span> <span class="s1">'hello'</span> <span class="p">}));</span>
<span class="nx">layout</span><span class="p">.</span><span class="nx">last</span><span class="p">.</span><span class="nx">show</span><span class="p">(</span><span class="k">new</span> <span class="nx">TextView</span><span class="p">({</span> <span class="nx">text</span><span class="o">:</span> <span class="s1">'world'</span> <span class="p">}));</span>
</pre></div>
<p>Now we have a <code>TextView</code> view that accepts a <code>text</code> option, and this is what's rendered. The idea is that instead of passing in a <code>template</code> option, in the view constructor, we give it our own template function. I'm using some Lo-Dash tools here to help construct it. Essentially, we're wrapping the supplied <code>text</code> option in the <code>identity()</code> function — which just returns whatever value is passed to it. And that's it, our two paragraph regions are populated with their respective text — "hello" and "world".</p>Adam Boduchhttp://www.blogger.com/profile/00484502507931628726noreply@blogger.com0tag:blogger.com,1999:blog-3531969847869413627.post-49307133607411772472014-12-05T18:02:00.000-05:002014-12-05T18:02:53.584-05:00How Asynchronous JavaScript Promises Work<p>The <code>Promise</code> object in the proposed ECMAScript 6 specification makes performing asynchronous operations easier. Not necessarily Ajax requests, but local function calls. These functions themselves may or may not depend on an external resource, but the key to promises is that the API looks and behaves the same. Promises, out of the box, are asynchronous. Let's illustrate the idea with some code:</p>
<a name='more'></a>
<div class="highlight"><pre><span class="k">new</span> <span class="nx">Promise</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">resolve</span><span class="p">,</span> <span class="nx">reject</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">'native'</span><span class="p">,</span> <span class="s1">'working'</span><span class="p">);</span>
<span class="nx">resolve</span><span class="p">();</span>
<span class="p">}).</span><span class="nx">then</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">'native'</span><span class="p">,</span> <span class="s1">'done'</span><span class="p">);</span>
<span class="p">});</span>
<span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">'jquery'</span><span class="p">,</span> <span class="s1">'working'</span><span class="p">);</span>
<span class="k">return</span> <span class="nx">$</span><span class="p">.</span><span class="nx">Deferred</span><span class="p">().</span><span class="nx">resolve</span><span class="p">().</span><span class="nx">promise</span><span class="p">();</span>
<span class="p">})().</span><span class="nx">then</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">'jquery'</span><span class="p">,</span> <span class="s1">'done'</span><span class="p">);</span>
<span class="p">});</span>
</pre></div>
<p>The first promise is a native <code>Promise</code> — not all browsers support this yet. The second promise uses the jQuery implementation. Both experiments log the same thing, but the order of the output is what's interesting:</p>
<pre>
native working
jquery working
jquery done
native done
</pre>
<p>You can clearly see that while the jQuery approach is synchronous, the native approach isn't — it's resolve callback is called <em>after</em> all the jQuery code executes. What's going on here? JavaScript code executes synchronously through what's called a <strong>job queue</strong>. The JavaScript engine puts pieces of JavaScript code in this queue, and executes them in <em>FIFO</em> order.</p>
However, resolution callbacks have their own <strong>promise queue</strong>. And it's up to the engine's implementation to decide which queue the next job comes from. As you can see from the output above, the job queue executes:
<ul>
<li><code>console.log('native', 'working')</code></li>
<li><code>console.log('jquery', 'working')</code></li>
<li><code>console.log('jquery', 'done')</code></li>
</ul>
There's obviously more code executed here, but these are the relevant parts concerning the output. The promise queue executes:
<ul>
<li><code>console.log('native', 'done')</code></li>
</ul>
You can see that the engine interweaves between the two queues as it picks up new jobs to run. What's interesting about this is that it negates the need to hack the JavaSctipt execution context using <code>setTimeout()</code>. You'd normally do this when you need to divide things up, long-running code that freezes the UI.Adam Boduchhttp://www.blogger.com/profile/00484502507931628726noreply@blogger.com0tag:blogger.com,1999:blog-3531969847869413627.post-73429704016544209242014-12-04T15:47:00.000-05:002014-12-04T15:47:21.727-05:00Lo-Dash: Using the result() function<p>The <code>result()</code> function is a handy way to look up object properties. If the property happens to be a function, <code>result()</code> will invoke it for us and return the result. Taken at face value, it doesn't seem like there's much to <code>result()</code>. On the contrary, it's a powerful tool. The basic usage looks like this:</p>
<div class="highlight"><pre><span class="kd">var</span> <span class="nx">object</span> <span class="o">=</span> <span class="p">{</span> <span class="nx">name</span><span class="o">:</span> <span class="s1">'Lo-Dash'</span> <span class="p">};</span>
<span class="nx">_</span><span class="p">.</span><span class="nx">result</span><span class="p">(</span><span class="nx">object</span><span class="p">,</span> <span class="s1">'name'</span><span class="p">);</span>
<span class="c1">// → "Lo-Dash"</span>
</pre></div>
<a name='more'></a>
<p>We probably could have just accessed the name property using the standard notation, <code>object.name</code>. But if what if the property doesn't exist?</p>
<div class="highlight"><pre><span class="nx">_</span><span class="p">.</span><span class="nx">result</span><span class="p">(</span><span class="nx">object</span><span class="p">,</span> <span class="s1">'enabled'</span><span class="p">);</span>
<span class="c1">// → undefined</span>
</pre></div>
<p>We get the same result we would have using the standard property access notation. Maybe <code>undefined</code> isn't the most desirable outcome if the property doesn't exist. What if the code that's looking up these values is performing a strict comparison?</p>
<div class="highlight"><pre><span class="nx">_</span><span class="p">.</span><span class="nx">result</span><span class="p">(</span><span class="nx">object</span><span class="p">,</span> <span class="s1">'enabled'</span><span class="p">)</span> <span class="o">===</span> <span class="kc">false</span><span class="p">;</span>
<span class="c1">// → false</span>
</pre></div>
<p>Above, <code>undefined</code> is not the default we want. If the <code>enabled</code> property isn't defined, we want it explicitly set to <code>false</code>. As with the standard property access notation, we can use a logical <i>or</i> condition to provide a default value:</p>
<div class="highlight"><pre><span class="nx">_</span><span class="p">.</span><span class="nx">result</span><span class="p">(</span><span class="nx">object</span><span class="p">,</span> <span class="s1">'enabled'</span><span class="p">)</span> <span class="o">||</span> <span class="kc">false</span> <span class="o">===</span> <span class="kc">false</span><span class="p">;</span>
<span class="c1">// → true</span>
</pre></div>
<p>The problem with this approach is that even when the <code>enabled</code> property is there, if it's <code>false</code>, we're still going to get the <code>false</code> literal in our <i>or</i> condition. It gets the job done, but doesn't feel right. Starting with Lo-Dash 3.0, there's a third argument we can pass to <code>result()</code>. This is the default value returned when the property is <code>undefined</code>.</p>
<div class="highlight"><pre><span class="nx">_</span><span class="p">.</span><span class="nx">result</span><span class="p">(</span><span class="nx">object</span><span class="p">,</span> <span class="s1">'enabled'</span><span class="p">,</span> <span class="kc">false</span><span class="p">)</span> <span class="o">===</span> <span class="kc">false</span><span class="p">;</span>
<span class="c1">// → true</span>
</pre></div>
<p>This approach feels a lot cleaner. Let's see how <code>result()</code> works with properties that are functions now.</p>
<div class="highlight"><pre><span class="kd">var</span> <span class="nx">object</span> <span class="o">=</span> <span class="p">{</span>
<span class="nx">name</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">first</span> <span class="o">+</span> <span class="s1">' '</span> <span class="o">+</span> <span class="k">this</span><span class="p">.</span><span class="nx">last</span><span class="p">;</span>
<span class="p">},</span>
<span class="nx">first</span><span class="o">:</span> <span class="s1">'Chris'</span><span class="p">,</span>
<span class="nx">last</span><span class="o">:</span> <span class="s1">'Luna'</span>
<span class="p">};</span>
<span class="nx">_</span><span class="p">.</span><span class="nx">result</span><span class="p">(</span><span class="nx">object</span><span class="p">,</span> <span class="s1">'name'</span><span class="p">);</span>
<span class="c1">// → "Chris Luna"</span>
</pre></div>
<p>What I really like about <code>result()</code> is that I can substitute this object with another one who's <code>name</code> property is a string. Once <code>result()</code> is in place, it seldom needs to change. Especially now that we can provide a default value as an argument. What about accessing prototypical functions?</p>
<div class="highlight"><pre><span class="kd">function</span> <span class="nx">Person</span><span class="p">(){}</span>
<span class="nx">Person</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">name</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">first</span> <span class="o">+</span> <span class="s1">' '</span> <span class="o">+</span> <span class="k">this</span><span class="p">.</span><span class="nx">last</span><span class="p">;</span>
<span class="p">}</span>
<span class="kd">var</span> <span class="nx">object</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Person</span><span class="p">();</span>
<span class="nx">object</span><span class="p">.</span><span class="nx">first</span> <span class="o">=</span> <span class="s1">'Hugo'</span><span class="p">;</span>
<span class="nx">object</span><span class="p">.</span><span class="nx">last</span> <span class="o">=</span> <span class="s1">'Sherman'</span><span class="p">;</span>
<span class="nx">_</span><span class="p">.</span><span class="nx">result</span><span class="p">(</span><span class="nx">object</span><span class="p">,</span> <span class="s1">'name'</span><span class="p">);</span>
<span class="c1">// → "Hugo Sherman"</span>
</pre></div>
<p>This works because <code>result()</code> looks up properties using standard property access notation, and doesn't check if the property is an <i>own</i> property. And because of this, we're able to <code>result()</code> to look up array items too:</p>
<div class="highlight"><pre><span class="kd">var</span> <span class="nx">array</span> <span class="o">=</span> <span class="p">[</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span> <span class="p">];</span>
<span class="nx">_</span><span class="p">.</span><span class="nx">result</span><span class="p">(</span><span class="nx">array</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
<span class="c1">// → 1</span>
</pre></div>
<p>With Lo-Dash 3.0, we can use this approach and provide a default value to use when an invalid index is specified.</p>
<div class="highlight"><pre><span class="nx">_</span><span class="p">.</span><span class="nx">result</span><span class="p">([],</span> <span class="nx">array</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
<span class="c1">// → 0</span>
</pre></div>
<p>Since <code>result()</code> is a function, we can utilize it in places other than where we need property access. For example, as a partial:</p>
<div class="highlight"><pre><span class="kd">var</span> <span class="nx">fifo</span> <span class="o">=</span> <span class="p">[],</span>
<span class="nx">put</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">bind</span><span class="p">(</span><span class="nx">fifo</span><span class="p">.</span><span class="nx">push</span><span class="p">,</span> <span class="nx">fifo</span><span class="p">),</span>
<span class="nx">get</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">partial</span><span class="p">(</span><span class="nx">_</span><span class="p">.</span><span class="nx">result</span><span class="p">,</span> <span class="nx">fifo</span><span class="p">,</span> <span class="s1">'shift'</span><span class="p">));</span>
<span class="nx">put</span><span class="p">(</span><span class="s1">'a'</span><span class="p">);</span>
<span class="c1">// → [ "a" ]</span>
<span class="nx">get</span><span class="p">();</span>
<span class="c1">// → "a"</span>
<span class="nx">fifo</span><span class="p">;</span>
<span class="c1">// → []</span>
</pre></div>
<p>The <code>put()</code> function is bound to <code>fifo</code> as the context. So is <code>get()</code>, because it's partially-applied to the <code>result()</code> function as an argument. As you can see there are plenty of interesting use cases for the <code>result()</code> function, small as they may be.</p>Adam Boduchhttp://www.blogger.com/profile/00484502507931628726noreply@blogger.com0tag:blogger.com,1999:blog-3531969847869413627.post-28811023174213600522014-07-08T16:20:00.000-04:002014-07-08T16:20:44.728-04:00Simpler Lodash Templates<p>I used to use Lodash <code>template()</code> until I give up due to the verbosity of the interpolation delimiters used. They're a pain, especially when it's a simple string I want to build. Stylistically, I don't want to resort to string concatenation in my code, but, it turned out to be the better option. You can use Lodash for simple string-building scenarios such as these — it just requires a little tweaking.</p>
<a name='more'></a>
<p>There's a bunch of options, in addition to the template data itself, that you can pass to <code>template()</code>. This can potentially alter the way the template is interpreted and rendered. For example, here's a basic string interpolation function that uses <code>template()</code>.</p>
<div class="highlight"><pre><span class="kd">function</span> <span class="nx">s</span><span class="p">(</span> <span class="nx">text</span><span class="p">,</span> <span class="nx">data</span> <span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">_</span><span class="p">.</span><span class="nx">template</span><span class="p">(</span> <span class="nx">text</span><span class="p">,</span> <span class="nx">data</span><span class="p">,</span> <span class="p">{</span>
<span class="nx">interpolate</span><span class="o">:</span> <span class="sr">/\{\{([\s\S]+?)\}\}/g</span>
<span class="p">});</span>
<span class="p">}</span>
<span class="nx">s</span><span class="p">(</span> <span class="s1">'hello, {{greeting}}'</span><span class="p">,</span> <span class="p">{</span> <span class="nx">greeting</span><span class="o">:</span> <span class="s1">'world'</span> <span class="p">}</span> <span class="p">);</span>
</pre></div>
<p>Here we've created a simple function called <code>s()</code>. It's potentially confusing name stands for string, but the trade-off is that it's tiny, and potentially used everywhere. This function basically wraps a call to <code>template()</code>. The main change we're introducing is to the template syntax — <code>{{name}}</code> — the new simpler way to specify variables. The object containing the substitution data is passed as usual. We can just return the result, since passing in the substitution data renders the string and returns it, as opposed to compiling and returning a function.</p>Adam Boduchhttp://www.blogger.com/profile/00484502507931628726noreply@blogger.com0tag:blogger.com,1999:blog-3531969847869413627.post-29257236429442251882014-07-08T12:14:00.000-04:002014-07-08T12:14:15.057-04:00jQuery UI: Sortable 3D CSS<p>The jQuery UI sortable widget allows the user to pick an item up, and drop it in another location. It's kinda like the draggable widget and in fact, uses the draggable widget to implement the draggable behaviour. A key difference, however, is that sortable will shuffle the other items around as the item is dragged, and after it's dropped. It re-sorts the items. The only style changes applied to the item that's being moved is it's position. We can use some fancy 3D CSS to make the item stand out even more when it's being dragged.</p>
<a name='more'></a>
<div class="separator" style="clear: both; text-align: center;"><a href="http://1.bp.blogspot.com/-uAAVK3klNJY/U7wQ24CLWlI/AAAAAAAAAvs/-ui2Jhg1Yqo/s1600/sortable-3d-css.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-uAAVK3klNJY/U7wQ24CLWlI/AAAAAAAAAvs/-ui2Jhg1Yqo/s320/sortable-3d-css.png" /></a></div>
<p>You can see that once you start dragging an item, it grows in size, which helps it stand out as the item that's currently being sorted. Once dropped, it shrinks back to it's normal size. And it uses CSS transitions for smooth growing and shrinking. Here's the <a href="http://jsfiddle.net/adamboduch/eB32d/">example</a>, and here's the event handlers used to add and remove our grow class from the item.</p>
<div class="highlight"><pre><span class="nx">$</span><span class="p">(</span> <span class="s1">'ul'</span> <span class="p">).</span><span class="nx">sortable</span><span class="p">({</span>
<span class="nx">start</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span> <span class="nx">e</span><span class="p">,</span> <span class="nx">ui</span> <span class="p">)</span> <span class="p">{</span>
<span class="nx">ui</span><span class="p">.</span><span class="nx">helper</span><span class="p">.</span><span class="nx">addClass</span><span class="p">(</span> <span class="s1">'grow'</span> <span class="p">)</span>
<span class="p">},</span>
<span class="nx">stop</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span> <span class="nx">e</span><span class="p">,</span> <span class="nx">ui</span> <span class="p">)</span> <span class="p">{</span>
<span class="nx">setTimeout</span><span class="p">(</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="nx">ui</span><span class="p">.</span><span class="nx">item</span><span class="p">.</span><span class="nx">removeClass</span><span class="p">(</span> <span class="s1">'grow'</span> <span class="p">);</span>
<span class="p">},</span> <span class="mi">1</span> <span class="p">);</span>
<span class="p">}</span>
<span class="p">});</span>
</pre></div>
<p>Note the <code>setTimeout()</code> call in the <code>stop</code> handler. I think the item isn't actually part of the DOM when this event is triggered. Without it, the transition doesn't work as expected. Here's what the CSS looks like.</p>
<div class="highlight"><pre><span class="nt">ul</span> <span class="nt">li</span> <span class="p">{</span>
<span class="n">transition</span><span class="o">:</span> <span class="o">-</span><span class="n">webkit</span><span class="o">-</span><span class="n">transform</span> <span class="n">ease</span><span class="o">-</span><span class="n">out</span> <span class="m">0.3s</span><span class="p">;</span>
<span class="o">-</span><span class="n">webkit</span><span class="o">-</span><span class="n">transform</span><span class="o">-</span><span class="n">origin</span><span class="o">:</span> <span class="m">50</span><span class="o">%</span> <span class="m">50</span><span class="o">%</span><span class="p">;</span>
<span class="p">}</span>
<span class="nt">ul</span> <span class="nt">li</span><span class="nc">.grow</span> <span class="p">{</span>
<span class="o">-</span><span class="n">webkit</span><span class="o">-</span><span class="n">transform</span><span class="o">:</span> <span class="n">perspective</span><span class="p">(</span><span class="m">800px</span><span class="p">)</span> <span class="n">translateZ</span><span class="p">(</span><span class="m">90px</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>Adam Boduchhttp://www.blogger.com/profile/00484502507931628726noreply@blogger.com0tag:blogger.com,1999:blog-3531969847869413627.post-52261597078681233082014-07-07T15:57:00.000-04:002014-07-07T15:59:16.332-04:00How Change Events Are Triggered In Backbone<p>I was having trouble understanding the various states that a given Backbone model, and all it's attributes, might be in. Specifically, how does an attribute change, and trigger the <code>change</code> event for that attribute. The <code>change</code> event isn't triggered when the model is first created, which makes sense because the model had to previous state. In other works, creating the model also creates a state machine for the model attributes. However, this can be confusing if you're adding a new attribute to a model.</p>
<a name='more'></a>
<p>Here's a really simple example that illustrates the various initial states for model attributes and how they're changed.</p>
<div class="highlight"><pre><span class="kd">var</span> <span class="nx">MyModel</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Model</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span>
<span class="nx">defaults</span><span class="o">:</span> <span class="p">{</span>
<span class="nx">b</span><span class="o">:</span> <span class="mi">2</span>
<span class="p">}</span>
<span class="p">}),</span>
<span class="nx">model</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">MyModel</span><span class="p">(</span> <span class="p">{</span> <span class="nx">a</span><span class="o">:</span> <span class="mi">1</span> <span class="p">}</span> <span class="p">);</span>
<span class="nx">Backbone</span><span class="p">.</span><span class="nx">listenTo</span><span class="p">(</span> <span class="nx">model</span><span class="p">,</span> <span class="s1">'change'</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span> <span class="nx">m</span> <span class="p">)</span> <span class="p">{</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span> <span class="nx">m</span><span class="p">.</span><span class="nx">changed</span> <span class="p">);</span>
<span class="p">});</span>
<span class="nx">model</span><span class="p">.</span><span class="nx">set</span><span class="p">(</span> <span class="p">{</span> <span class="nx">a</span><span class="o">:</span> <span class="mi">2</span> <span class="p">}</span> <span class="p">);</span>
<span class="nx">model</span><span class="p">.</span><span class="nx">set</span><span class="p">(</span> <span class="p">{</span> <span class="nx">b</span><span class="o">:</span> <span class="mi">3</span> <span class="p">}</span> <span class="p">);</span>
<span class="nx">model</span><span class="p">.</span><span class="nx">set</span><span class="p">(</span> <span class="p">{</span> <span class="nx">d</span><span class="o">:</span> <span class="mi">4</span> <span class="p">}</span> <span class="p">);</span>
</pre></div>
<p>The initial value of the <code>a</code> attribute is <code>1</code>. This gets passed in through the model constructor. And it changes to <code>2</code> later on, triggering a <code>change</code> event. The initial value of the <code>b</code> attribute is <code>2</code>, coming from the <code>defaults</code> object. This changes to <code>3</code> later on triggering a <code>change</code> event. Finally, we add the <code>d</code> attribute with a value of <code>4</code> — also triggering a <code>change</code> event. This last operation triggers a change event because the attribute value goes from <code>undefined</code> to <code>4</code>.</p>
<p>So there's three separate types of attribute value transitions to consider with Backbone models. From initial value, from default value, and from <code>undefined</code>.</p>Adam Boduchhttp://www.blogger.com/profile/00484502507931628726noreply@blogger.com0tag:blogger.com,1999:blog-3531969847869413627.post-67992883785150737662014-07-07T12:05:00.000-04:002014-07-07T12:05:06.777-04:00jQuery UI: Selectmenu Placeholder Text<p>Input elements have a <code>placeholder</code> attribute, which does a decent job at telling the user exactly what's expected. What I really like about using this attribute is that there's no additional space required — it appears inside the widget, when there's no text. Hence the name. So, I tried to do something similar with the jQuery UI selectmenu widget.</p>
<a name='more'></a>
<p>By default, the selectmenu displays the text of the selected option, which makes sense, since this is how you know which option is selected. What about when the widget is first created? If there's no option selected, that's when I want to display the placeholder text for the selectmenu. So the first step is figuring out when there's nothing selected — which is actually trickier than it sounds. With the <code>:selected</code> pseudo-selector, there's always a selected option. Implicitly, it's the first option — if there's no <code>selected</code> attribute specified on any of the options.</p>
<p>This is exactly what we're after — we want to display the placeholder text if the select markup doesn't explicitly have a <code>selected</code> attribute in any of it's options. Here's an example of how to override the default implementation of the selectmenu to add a placeholder option.</p>
<div class="highlight"><pre><span class="nx">$</span><span class="p">.</span><span class="nx">widget</span><span class="p">(</span> <span class="s1">'app.selectmenu'</span><span class="p">,</span> <span class="nx">$</span><span class="p">.</span><span class="nx">ui</span><span class="p">.</span><span class="nx">selectmenu</span><span class="p">,</span> <span class="p">{</span>
<span class="nx">_drawButton</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="k">this</span><span class="p">.</span><span class="nx">_super</span><span class="p">();</span>
<span class="kd">var</span> <span class="nx">selected</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">element</span>
<span class="p">.</span><span class="nx">find</span><span class="p">(</span> <span class="s1">'[selected]'</span> <span class="p">)</span>
<span class="p">.</span><span class="nx">length</span><span class="p">,</span>
<span class="nx">placeholder</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">options</span><span class="p">.</span><span class="nx">placeholder</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span> <span class="o">!</span><span class="nx">selected</span> <span class="o">&&</span> <span class="nx">placeholder</span> <span class="p">)</span> <span class="p">{</span>
<span class="k">this</span><span class="p">.</span><span class="nx">buttonText</span><span class="p">.</span><span class="nx">text</span><span class="p">(</span> <span class="nx">placeholder</span> <span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">});</span>
<span class="nx">$</span><span class="p">(</span> <span class="s1">'[name="speed"]'</span> <span class="p">).</span><span class="nx">selectmenu</span><span class="p">({</span>
<span class="nx">placeholder</span><span class="o">:</span> <span class="s1">'Select a speed'</span>
<span class="p">});</span>
</pre></div>
<p>And here's what the resulting selectmenu looks like before an option is selected.</p>
<div class="separator" style="clear: both; text-align: center;"><a href="http://2.bp.blogspot.com/-rQFSy9XXrzc/U7rEJ5Z_K2I/AAAAAAAAAvc/vRuINHBpvyA/s1600/adding-placeholder-text-to-selectmenu.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-rQFSy9XXrzc/U7rEJ5Z_K2I/AAAAAAAAAvc/vRuINHBpvyA/s320/adding-placeholder-text-to-selectmenu.png" /></a></div>Adam Boduchhttp://www.blogger.com/profile/00484502507931628726noreply@blogger.com0tag:blogger.com,1999:blog-3531969847869413627.post-114960573324338862014-07-07T08:52:00.000-04:002014-07-07T08:52:27.066-04:00Connecting Sliders To Number Inputs<p>The <code>input</code> element can be configured to accept numbers. When this happens, the input is just like a regular text input, expect now it's rendered with spinner buttons — used to increment or decrement values. Further constraints can be placed on number inputs, like the minimum and maximum allowed values. This let's us do interesting things, like connect the number input to a jQuery UI slider widget.</p>
<a name='more'></a>
<p>Sliders, used in this context, are meant to assist the user in filling out the number input. The spinner buttons on the number input aren't exactly obvious, slider should fill in this gap. For example, the user has the choice of manually typing the number, as they would any other text input, or by using the slider.</p>
<div class="separator" style="clear: both; text-align: center;"><a href="http://4.bp.blogspot.com/-W8D_kKjeXcc/U7qVBQXSpHI/AAAAAAAAAvM/rpVEuL302No/s1600/connecting-sliders-to-number-inputs.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-W8D_kKjeXcc/U7qVBQXSpHI/AAAAAAAAAvM/rpVEuL302No/s320/connecting-sliders-to-number-inputs.png" /></a></div>
<p>It goes without saying, that as the user types, the slider should reflect the current input value and as the user slides, the input should reflect the current slider value. Here's some <a href="http://jsfiddle.net/adamboduch/LftCR/">code</a>.</p>
<div class="highlight"><pre><span class="kd">var</span> <span class="nx">$input</span> <span class="o">=</span> <span class="nx">$</span><span class="p">(</span> <span class="s1">'[name="percent"]'</span> <span class="p">).</span><span class="nx">on</span><span class="p">({</span>
<span class="nx">input</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span> <span class="nx">e</span> <span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">$input</span> <span class="o">=</span> <span class="nx">$</span><span class="p">(</span> <span class="nx">e</span><span class="p">.</span><span class="nx">currentTarget</span> <span class="p">);</span>
<span class="nx">$input</span><span class="p">.</span><span class="nx">next</span><span class="p">()</span>
<span class="p">.</span><span class="nx">slider</span><span class="p">(</span> <span class="s1">'value'</span><span class="p">,</span> <span class="nx">$input</span><span class="p">.</span><span class="nx">val</span><span class="p">()</span> <span class="p">);</span>
<span class="p">}</span>
<span class="p">});</span>
<span class="nx">$</span><span class="p">(</span> <span class="s1">'<div/>'</span> <span class="p">).</span><span class="nx">insertAfter</span><span class="p">(</span> <span class="nx">$input</span> <span class="p">)</span>
<span class="p">.</span><span class="nx">slider</span><span class="p">({</span>
<span class="nx">min</span><span class="o">:</span> <span class="o">+</span><span class="nx">$input</span><span class="p">.</span><span class="nx">prop</span><span class="p">(</span> <span class="s1">'min'</span> <span class="p">),</span>
<span class="nx">max</span><span class="o">:</span> <span class="o">+</span><span class="nx">$input</span><span class="p">.</span><span class="nx">prop</span><span class="p">(</span> <span class="s1">'max'</span> <span class="p">),</span>
<span class="nx">stop</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span> <span class="nx">e</span><span class="p">,</span> <span class="nx">ui</span> <span class="p">)</span> <span class="p">{</span>
<span class="nx">$input</span><span class="p">.</span><span class="nx">val</span><span class="p">(</span> <span class="nx">ui</span><span class="p">.</span><span class="nx">value</span> <span class="p">);</span>
<span class="p">}</span>
<span class="p">});</span>
</pre></div>
<p>The first thing this code does is setup a handler for the <code>input</code> event on the <code>percent</code> element. This event triggers whenever the input changes. So, in other words, as the user types. All the handler itself has to do is find the slider widget — the next sibling — and update the value.</p>
<p>Next is the slider code, where we make use of the fact that the input we're connecting to is a number input. The <code>min</code> and <code>max</code> properties are passed to the slider configuration as it's <code>min</code> and <code>max</code> allowable values. So there's a one-to-one correspondence there, in addition to just the value. The <code>stop</code> event handler updates the input whenever the user stops sliding.</p>Adam Boduchhttp://www.blogger.com/profile/00484502507931628726noreply@blogger.com0tag:blogger.com,1999:blog-3531969847869413627.post-24537936590139113262014-07-04T16:05:00.001-04:002014-07-04T16:05:54.928-04:00Caching Autocomplete Responses Using Lodash<p>I've taken a few approaches to caching responses in the jQuery UI autocomplete widget. A response, in autocomplete parlance, is the data that's displayed when the user is typing in the text input. Each keystroke is a request for data — the response is something the autocomplete must generate by filtering some data source. The filtering operations can be done locally, or remotely. Either way, we stand to benefit from caching these responses.</p>
<a name='more'></a>
<p>All my previous attempts at caching autocomplete responses had their shortcomings. For example, it was difficult to implement a caching mechanism that worked equally well for both local and remote data sources. This new approach I'm using isn't without it's faults. It utilizes the Lodash library, which isn't necessarily a good thing if you're not already using it. Here's the <a href="http://jsfiddle.net/adamboduch/6zhqr/">example</a> I came up with.</p>
<div class="highlight"><pre><span class="nx">$</span><span class="p">.</span><span class="nx">widget</span><span class="p">(</span> <span class="s1">'app.autocomplete'</span><span class="p">,</span> <span class="nx">$</span><span class="p">.</span><span class="nx">ui</span><span class="p">.</span><span class="nx">autocomplete</span><span class="p">,</span> <span class="p">{</span>
<span class="nx">terms</span><span class="o">:</span> <span class="p">{},</span>
<span class="nx">_initSource</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="k">this</span><span class="p">.</span><span class="nx">_super</span><span class="p">();</span>
<span class="k">this</span><span class="p">.</span><span class="nx">source</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">wrap</span><span class="p">(</span> <span class="k">this</span><span class="p">.</span><span class="nx">source</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">cache</span> <span class="p">);</span>
<span class="p">},</span>
<span class="nx">cache</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span> <span class="nx">source</span><span class="p">,</span> <span class="nx">req</span><span class="p">,</span> <span class="nx">res</span> <span class="p">)</span> <span class="p">{</span>
<span class="nx">_</span><span class="p">.</span><span class="nx">has</span><span class="p">(</span> <span class="k">this</span><span class="p">.</span><span class="nx">terms</span><span class="p">,</span> <span class="nx">req</span><span class="p">.</span><span class="nx">term</span> <span class="p">)</span> <span class="o">?</span>
<span class="nx">res</span><span class="p">(</span> <span class="k">this</span><span class="p">.</span><span class="nx">terms</span><span class="p">[</span> <span class="nx">req</span><span class="p">.</span><span class="nx">term</span> <span class="p">]</span> <span class="p">)</span> <span class="o">:</span>
<span class="nx">source</span><span class="p">(</span> <span class="nx">req</span><span class="p">,</span> <span class="nx">res</span> <span class="p">);</span>
<span class="p">},</span>
<span class="nx">__response</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span> <span class="nx">content</span> <span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span> <span class="o">!</span><span class="nx">_</span><span class="p">.</span><span class="nx">has</span><span class="p">(</span> <span class="k">this</span><span class="p">.</span><span class="nx">terms</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">term</span> <span class="p">)</span> <span class="p">)</span> <span class="p">{</span>
<span class="k">this</span><span class="p">.</span><span class="nx">terms</span><span class="p">[</span> <span class="k">this</span><span class="p">.</span><span class="nx">term</span> <span class="p">]</span> <span class="o">=</span> <span class="nx">content</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">this</span><span class="p">.</span><span class="nx">_super</span><span class="p">(</span> <span class="nx">content</span> <span class="p">);</span>
<span class="p">}</span>
<span class="p">});</span>
</pre></div>
<p>In this simple extension of the autocomplete widget, we're overriding a couple methods, and providing a new one. In addition to the new <code>terms</code> property, serving as the cache itself. The <code>_initSource()</code> method is private, and called automatically by the widget to make sure there's a data source that's ready to use. We call the original implementation so that the <code>source()</code> method can be setup. Then we use <code>wrap()</code> to wrap the <code>cache()</code> method around <code>source()</code>. This is where we check for the existence of a cache key.</p>
<p>Next, we have the <code>cache()</code> method itself, which is wrapped around the <code>source()</code> method. It uses the <code>has()</code> to check for the existence of a key, and if it finds one, it can call the response directly, using the cached value. Otherwise, we have to call the <code>source()</code> implementation.</p>
<p>Lastly, the <code>__response()</code> method is always called, no matter what the autocomplete source looks like — array, remove, whatever. So this is a good spot to actually cache the response values based on the current search term. The whole approach works equally well for any data source and Lodash makes easy work of it.</p>Adam Boduchhttp://www.blogger.com/profile/00484502507931628726noreply@blogger.com0tag:blogger.com,1999:blog-3531969847869413627.post-11875542954550184012014-07-04T13:20:00.000-04:002014-07-04T13:20:54.229-04:00Ensure Backbone View Is In The DOM<p>A nice aspect of Backbone views is that they're guaranteed to have an element. This takes place before the view constructor is called. Even if you don't supply any element details, such as the tag name, the element id — there will always be a <code>div</code> element. However, one thing you have to always remember is the add the element to the DOM. While the view ensures the element gets created, it doesn't ensure that the element is attached to the DOM. This is actually a good thing, because you don't always want to be forced to be working on an element that's in the DOM.</p>
<a name='more'></a>
<p>But, sometimes, it's handy to be able to just add the element to the DOM. That way, it gets inserted as part of the view creating process and doesn't require an extra step. Less chance for weird errors that arise from the element not being in the DOM when it's supposed to be. Here's an example that shows you how to override the <code>_ensureElement()</code> view method. Note that this is a private method, and doesn't need to be invoked manually — it's called for us, before the view constructor.</p>
<div class="highlight"><pre><span class="k">new</span> <span class="p">(</span><span class="nx">Backbone</span><span class="p">.</span><span class="nx">View</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span>
<span class="nx">parent</span><span class="o">:</span> <span class="s1">'body'</span><span class="p">,</span>
<span class="nx">_ensureElement</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="nx">Backbone</span><span class="p">.</span><span class="nx">View</span><span class="p">.</span><span class="nx">prototype</span>
<span class="p">.</span><span class="nx">_ensureElement</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span> <span class="k">this</span> <span class="p">);</span>
<span class="k">if</span> <span class="p">(</span> <span class="k">this</span><span class="p">.</span><span class="nx">parent</span> <span class="p">)</span> <span class="p">{</span>
<span class="k">this</span><span class="p">.</span><span class="nx">$el</span><span class="p">.</span><span class="nx">appendTo</span><span class="p">(</span>
<span class="nx">$</span><span class="p">(</span> <span class="k">this</span><span class="p">.</span><span class="nx">parent</span> <span class="p">)</span> <span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}))();</span>
</pre></div>
<p>We've added a new option to the view here called <code>parent</code>. This is either a jQuery object or an element, or a selector. Standard stuff. We check for this option in our implementation of <code>_ensureElement()</code>. If <code>parent</code> is there, we append the created element to it.</p>Adam Boduchhttp://www.blogger.com/profile/00484502507931628726noreply@blogger.com0tag:blogger.com,1999:blog-3531969847869413627.post-25332040369004054802014-07-03T23:08:00.000-04:002014-07-03T23:08:12.082-04:00Lodash: Descending Sorted Index<p>The <code>sortedIndex()</code> function available in Lodash performs a binary search on an array to tell you where you can insert the new element in question, and maintain the sort order. Which implies, of course, that the array is already sorted. This function helps you keep it that way. The benefit to keeping and array sorted is that often, you're going to want to present the values of that array in sorted order. So you could, do it just-in-time, by sorting the array when it's about to be displayed. But this has efficiency problems.</p>
<a name='more'></a>
<p>Doing a binary search to locate the best spot for the new element isn't a cost-prohibitive computation. Especially when the trade-off means not having to sort the array over and over again. What would be nice, is if the <code>sortedIndex()</code> function could somehow work on arrays that are sorted in descending order. By default, the function expects the sort order to be ascending. I've had plenty of cases where a descending array is needed, and I don't want to sort, then reverse the order each time.</p>
<p>The <code>sortedIndex()</code> function excepts a callback function that performs the comparison. All we have to do is return the negative value, to get the sorted index for descending order, as this <a href="http://jsfiddle.net/adamboduch/W5dfP/">example</a> demonstrates.</p>
<div class="highlight"><pre><span class="kd">var</span> <span class="nx">data</span> <span class="o">=</span> <span class="p">[</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">1</span> <span class="p">],</span>
<span class="nx">value</span> <span class="o">=</span> <span class="mi">4</span><span class="p">,</span>
<span class="nx">index</span><span class="p">;</span>
<span class="nx">index</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">sortedIndex</span><span class="p">(</span> <span class="nx">data</span><span class="p">,</span> <span class="nx">value</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span> <span class="nx">i</span> <span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="o">-</span><span class="nx">i</span><span class="p">;</span>
<span class="p">});</span>
<span class="nx">data</span><span class="p">.</span><span class="nx">splice</span><span class="p">(</span> <span class="nx">index</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">value</span> <span class="p">);</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span> <span class="nx">data</span> <span class="p">);</span>
</pre></div>Adam Boduchhttp://www.blogger.com/profile/00484502507931628726noreply@blogger.com0tag:blogger.com,1999:blog-3531969847869413627.post-28508115185076132262014-07-03T11:50:00.000-04:002014-07-03T11:58:27.813-04:00jQuery: Closest Is Better Than Parent<p>We know that jQuery is the de-facto DOM traversal tool on the web. Part of what makes this works so well with jQuery is it's chaining ability. You can chain just about everything you need to do as a single statement, without sacrificing readability. There are some scenarios where chaining these traversal operations doesn't work so well. Like when trying to traverse up through the DOM using <code>parent()</code>.</p>
<a name='more'></a>
<p>Let's say you had a DOM structure that looks something like this.</p>
<div class="highlight"><pre><span class="nt"><div</span> <span class="na">data-foo=</span><span class="s">"bar"</span><span class="nt">></span>
<span class="nt"><p></span>Please <span class="nt"><a</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span>click<span class="nt"></a></p></span>
<span class="nt"></div></span>
</pre></div>
<p>When the link is clicked, we need access to the <code>foo</code> data attribute. So the naive solution might be to do something like this.</p>
<div class="highlight"><pre><span class="nx">$</span><span class="p">(</span> <span class="s1">'a'</span> <span class="p">).</span><span class="nx">on</span><span class="p">(</span> <span class="s1">'click'</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span> <span class="nx">e</span> <span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">foo</span> <span class="o">=</span> <span class="nx">$</span><span class="p">(</span> <span class="nx">e</span><span class="p">.</span><span class="nx">currentTarget</span> <span class="p">)</span>
<span class="p">.</span><span class="nx">parent</span><span class="p">()</span>
<span class="p">.</span><span class="nx">parent</span><span class="p">()</span>
<span class="p">.</span><span class="nx">data</span><span class="p">(</span> <span class="s1">'foo'</span> <span class="p">);</span>
<span class="p">});</span>
</pre></div>
<p>The problem with chaining <code>parent()</code> calls together, is that it's a fixed structure inside of our callback handler. Not only is it verbose code, it's also vulnerable changes in the DOM. Let's say that we've decided to remove the <code>p</code> element from our markup.</p>
<div class="highlight"><pre><span class="nt"><div</span> <span class="na">data-foo=</span><span class="s">"bar"</span><span class="nt">></span>
Please <span class="nt"><a</span> <span class="na">href=</span><span class="s">"#"</span><span class="nt">></span>click<span class="nt"></a></span>
<span class="nt"></div></span>
</pre></div>
<p>All of the sudden, our approach that chained together the <code>parent()</code> calls no longer works. The better approach is to use <code>closest()</code>.</p>
<div class="highlight"><pre><span class="nx">$</span><span class="p">(</span> <span class="s1">'a'</span> <span class="p">).</span><span class="nx">on</span><span class="p">(</span> <span class="s1">'click'</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span> <span class="nx">e</span> <span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">foo</span> <span class="o">=</span> <span class="nx">$</span><span class="p">(</span> <span class="nx">e</span><span class="p">.</span><span class="nx">currentTarget</span> <span class="p">)</span>
<span class="p">.</span><span class="nx">closest</span><span class="p">(</span> <span class="s1">'div'</span> <span class="p">)</span>
<span class="p">.</span><span class="nx">data</span><span class="p">(</span> <span class="s1">'foo'</span> <span class="p">);</span>
<span class="p">});</span>
</pre></div>
<p>The not only is the <code>closest()</code> approach immune to changes, within reason, to the DOM structure, but it's also efficient and easy to read. As soon as it finds an element, it stops looking, which is ideally suited to the majority of use cases like this.</p>Adam Boduchhttp://www.blogger.com/profile/00484502507931628726noreply@blogger.com0