<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Hank Yates]]></title><description><![CDATA[Programmer, Runner, Soccer Player, Musician, Seattle ✈ New Orleans]]></description><link>http://blog.hankyates.com/</link><generator>Ghost v0.4.1-rc1</generator><lastBuildDate>Sat, 18 Apr 2026 02:54:35 GMT</lastBuildDate><atom:link href="http://blog.hankyates.com/rss/" rel="self" type="application/rss+xml"/><author><![CDATA[Hank Yates]]></author><ttl>60</ttl><item><title><![CDATA[Stream Recap | CSS, Chartist.js, RxJs, lodash]]></title><description><![CDATA[<iframe width="560" height="315" src='https://www.youtube.com/embed/rv5DUaA5Nh4'  frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>

<p>Had a predominately designed focused stream. Really struggled with color selection. It's getting better though. I had a hard stop at an hour for the evening but still managed to make decent progress. I'm looking forward to bringing in more state management via redux eventually and really breaking the Observables and state up into manageable chunks. </p>

<p>One thing I also need to sort out is learning how/when events are emitted when combining observables. It appeared that <code>zip</code> seemed to act as and AND gate that only emited after a new value from each stream was emitted. This wasn't the desired behavior I was looking for so I might have to seek some alternatives for collapsing Observable values. </p>]]></description><link>http://blog.hankyates.com/stream-recap-css-chartist-js-rxjs-lodash/</link><guid isPermaLink="false">fe484462-10f7-4375-abb6-23aab237bb26</guid><dc:creator><![CDATA[Hank Yates]]></dc:creator><pubDate>Thu, 06 Sep 2018 20:13:42 GMT</pubDate></item><item><title><![CDATA[Stream Recap | Bootstrap v4, Chartist.js and some light wireframing/design]]></title><description><![CDATA[<iframe width="560" height="315" src='https://www.youtube.com/embed/ruywrP2i8_Y'  frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>

<p>I decided to shelve the machine learning bit while I went back and read up more on the fundamentals. I feel like I wasn't able to train a model because of some basic concept I was missing. </p>

<p>In light of that, I decided to try and put a bit of polish on the project and start stretching some design muscles. I figured an hour would be enough time but it ended up taking more. Which is no big deal, but always a good exercise to anaylyze why things took longer than you thought they would. In this instance I ended up getting hung out on how to store the UI state. I wanted something that wasn't hackey, but couldn't think of an elegant solution without bringing a full blown library in. Which just reinforces my feelings that state is hard, and it should be treated with respect. </p>]]></description><link>http://blog.hankyates.com/stream-recap-bootstrap-v4-chartist-js-and-some-light-wireframingdesign/</link><guid isPermaLink="false">08df0003-a29c-4093-b4b7-7be20ce10bc2</guid><dc:creator><![CDATA[Hank Yates]]></dc:creator><pubDate>Thu, 30 Aug 2018 21:07:18 GMT</pubDate></item><item><title><![CDATA[Stream Recap | Machine Learning, Tensorflow.js, Linear Regression, Gradient Descent]]></title><description><![CDATA[<iframe width="560" height="315" src='https://www.youtube.com/embed/IMTW_BR8QxQ'  frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>

<p>Had a wonderful time streaming this time around. Though I didn't achieve my goal of being able to predict future values with a Linear Regression, I learned a TON.</p>

<p>I decided to check out Tensorflow.js. I was really happy with it! I have previously used Apache Spark so I'm not unfamiliar with big data frameworks. Tensorflow was just simple and to the point. There didn't seem to be alot of fluff in the API and I really appreciate that style of directness.</p>

<p>I wasn't able to accomplish my goal because frankly I have the wrong approach. Training a Tensorflow model seems to be a use case of having a complicated model and a long training time. Since I'm trying to train a model in "realtime" I basically tripped over Gradient Descent/Learning Rates. </p>

<p>So what next? I am going to try to have each subsequent training pick up where the last training left off. My hope here is that even though the first set of values will have a woefully inaccurate model, eventually we will hit a steady state and be able to train a new model quickly enough(I've picked &lt; 1s for no particular reason).</p>

<p>If this approach doesn't work then I'm going to look into training the model Async and have the latest value take the latest model that is trained. </p>

<p>This could be an interesting enough approach in it's own right as it would be nice to have longer training times for the model whenever there is a gap in stream values. I might end up trying this approach reguardless.</p>]]></description><link>http://blog.hankyates.com/stream-recap-machine-learning-tensorflow-js-linear-regression-gradient-descent/</link><guid isPermaLink="false">da3c7537-6718-45b0-8321-4d52d73f5ba2</guid><dc:creator><![CDATA[Hank Yates]]></dc:creator><pubDate>Sat, 25 Aug 2018 04:17:33 GMT</pubDate></item><item><title><![CDATA[Stream Recap | RxJs Scan, Trapezoid Rule]]></title><description><![CDATA[<iframe width="560" height="315" src='https://www.youtube.com/embed/D0qV023tjSE'  frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>

<p>Another Tuesday another successful stream! I did a little prep work that I mention below for this one and it was nice having notes to follow to keep things organized. However the more I am working through my analysis the more I am questioning my approach. I think next week I am going to build a live chart of the values to get a sense of where I am and where I should god. Then after that ... Linear Regressions!</p>

<p>I got a little excited about the idea and ended up doing an impromptu stream ... that didn't go very well but was extremely instructive:</p>

<iframe width="560" height="315" src='https://www.youtube.com/embed/YmH7a98Oewg'  frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>

<p>I spent quite a bit of time trying to create a 'last 10 values' stream. I went through several approaches and ended up with using <code>scan</code>. Originally I tried <code>bufferCount</code> however buffer only emited 'last 10' values for every 10 values. This wouldn't work as I wanted to emit a new 'last 10' for each new value. Then I attempted to use <code>window</code> which almost seemed to work. I was looking to create an <code>Observable&lt;Observable&lt;Array&lt;Number&gt;&gt;&gt;</code> and window provided a <code>Observable&lt;Observable&lt;T&gt;&gt;</code> output, but shamefully I couldn't get the behavior I was looking for.</p>

<p>Having thoroughly overthought the problem, a google search suggested <code>scan</code> and I thought 'sure why not'. It ended up doing the trick quite nicely. </p>

<p>Pay attention to what are Operators and what are Observables. Especially when using <code>mergeMap/concatMap/switchMap</code>. I regularly was getting my types wrong on my inputs and outputs.</p>]]></description><link>http://blog.hankyates.com/stream-recap-rxjs-scan-trapezoid-rule/</link><guid isPermaLink="false">c6372663-cc0f-45e1-abec-1e55a3044b99</guid><dc:creator><![CDATA[Hank Yates]]></dc:creator><pubDate>Wed, 08 Aug 2018 02:44:54 GMT</pubDate></item><item><title><![CDATA[Stream Recap | Websocket + RXJS]]></title><description><![CDATA[<iframe width="560" height="315" src='https://www.youtube.com/embed/qJ4hOjWnSR8'  frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>

<p>Code: <a href='https://github.com/hankyates/websocket-stream/tree/2018-07-31-post-stream' >https://github.com/hankyates/websocket-stream/tree/2018-07-31-post-stream</a></p>

<p>I am trying a new thing. I am going to try and live stream coding sessions of when I am learning new things. My hope is that maybe people will engage or find these musings useful. I know that there are many programmers that I wish I could just see how they work or approach things.</p>

<p>I set out with a pretty simple and achievable goal. Just to get an Observable stream from a websocket. Most of the evening was spent getting stumped by finding a decent API and figuring out where things were in the rxjs namespace.  At the end I was able to setup two different streams that filtered based on different values which was my goal.</p>

<p>I am really excited about the next phase which will be acting on these values in some sort of meaningful way. </p>]]></description><link>http://blog.hankyates.com/websocket-rxjs-live-coding-recap/</link><guid isPermaLink="false">7ea8ea7f-9212-4852-bd46-5a2f765a89cf</guid><dc:creator><![CDATA[Hank Yates]]></dc:creator><pubDate>Wed, 01 Aug 2018 03:53:59 GMT</pubDate></item><item><title><![CDATA[BRFSS Map]]></title><description><![CDATA[<p>**Update Jan 2020**</p>

<p>This was backed by ElasticSearch and I stopped paying for my cluster(they're expensive). So the data no longer works for the POC below.</p>

<p>Proof of concept: <a href='http://brfss-map.hankyates.com/' >http://brfss-map.hankyates.com/</a> <br />
Code: <a href='https://github.com/hankyates/louisiana-map' >https://github.com/hankyates/louisiana-map</a></p>

<p>As an exercise I wanted to build a Chloropleth map. Well I didn't exactly start at wanting to build a chloropleth map. It started as a simple question, which Parishes in Louisiana could use more resources in improving the overall health of their population? I wanted to see which parishes had the most smokers. Which had the most drinkers. Which had the most people who smoked AND drank.</p>

<p>The CDC runs a telephone survey called the <a href='https://www.cdc.gov/brfss/index.html' >Behavioral Risk Factor Surveillance System</a> and publishes the results of the data. After quite a bit of normalization of the data (which could be it's own blog post), I managed to mash up a <a href='http://brfss-map.hankyates.com/' >quick proof of concept</a>. </p>

<p>It's clunky. I think the data is wrong. The javascript is completely unmaintainable, but I shipped something. That alone is enough to celebrate and announce.</p>

<p>-Hank</p>]]></description><link>http://blog.hankyates.com/brfss-map/</link><guid isPermaLink="false">03af7d40-e6be-437c-8b54-caa9abbeab49</guid><dc:creator><![CDATA[Hank Yates]]></dc:creator><pubDate>Tue, 24 Jul 2018 22:53:30 GMT</pubDate></item><item><title><![CDATA[Playing around with Elm]]></title><description><![CDATA[<p>This is a quick exploration into Elm hosted at: <br />
<a href='https://hankyates.github.io/code-share/' >https://hankyates.github.io/code-share/</a>.
I just made a quick little code sharing site that pulls from githubs gist api.</p>

<h2 id="myimpressionsonelm">My Impressions on Elm</h2>

<h3 id="pros">Pros</h3>

<ul>
<li>No runtime errors.</li>
<li>Not alot of boilerplate.</li>
<li>Strong types.</li>
</ul>

<h3 id="cons">Cons</h3>

<ul>
<li>Not newbie friendly at all.</li>
<li>Docs can be out of date and confusing (Signals, Effects)</li>
<li>Simple Debugging is difficult.</li>
</ul>

<p>A big selling point on Elm is 'no runtime errors' and this was true and amazing. If it compiled it worked. The tradeoff is that instead of debugging errors in dev tools, you spent more time figuring out what the compiler error was trying to tell you. The compilers errors are helpful though.  </p>

<p>There wasn't a need for linting either. The types kept you in line and made sure you weren't doing anything silly. I really enjoyed writing signatures for my functions and then figuring out the implementation later. It makes designing nice API's easier.  </p>

<p>Simple debugging was way too difficult. My Json Decoder wasn't working properly, and I had no real way of knowing that was where the problem was, because there is no simple way to <code>console.error</code> error messages when they occur. I eventually got it all wired up, but if I were a newbie coming in, I don't think I would have been able to get past this problem. Googling questions and error messages didnt always yield great results either. For figuring out how to Json Decode a JS Object into a List, I found an old blog post using out of date Elm API's. I eventually got what I needed from it, but considerable updates to the blog code needed to be made.</p>

<p>All in all though I really loved working with Elm and I think it's great for lightweight projects! I still think it doesn't quite have the community support or ecosystem to try and bring it in for a major project at work. </p>]]></description><link>http://blog.hankyates.com/whatever/</link><guid isPermaLink="false">51a2f1af-561a-4543-983a-84d650ce7904</guid><dc:creator><![CDATA[Hank Yates]]></dc:creator><pubDate>Sun, 21 Aug 2016 23:25:40 GMT</pubDate></item><item><title><![CDATA[More stuff on Currying and Promises]]></title><description><![CDATA[<p>I know my last post was on currying but this is tool that has confounded me for a long time and I'm finally coming around to understanding what are appropriate use cases for it. </p>

<p>The problem with currying is I understand the concept. I understand what it is doing and what problems it solves. But where does one actually use it in real world code. I've been on the lookout at work and trying to shoehorn it in wherever possible but it hasn't quite fit until recently. </p>

<pre><code>function sendRequest(res, template, context) {  
  if (!res.finished) {
      res.send(template(context)));
  }
}
</code></pre>

<p>This was the first chunk of code where the light finally turned on for me. </p>

<p>I love having the params passed in to this function. It makes this function pure and easy to write a unit test against. The problem was that it needed to be used in differents contexts where we only have 1 or 2 of the arguments. THIS is where currying comes in handy. Here is some context. This code is a serverside expressjs app.</p>

<p>Here is the work we do to get out index.html from the filesystem:  </p>

<pre><code>fs.readFile('index.html', 'utf-8', (err, file) =&gt; {  
  var template = _.template(indexHtml);
  // template is available
});
</code></pre>

<p>Here is a service call we make to fetch articles for our page:  </p>

<pre><code>articleService.getLatestArticles()  
  .then((context) =&gt; {
    //context is available
  }).catch(e =&gt; {console.error(e)})
</code></pre>

<p>Here is our express route:  </p>

<pre><code>app.get('/articles', (req, res) =&gt; {  
  //req is available
});
</code></pre>

<p>All of this might be overwhelming and ... it is. This is alot of context to juggle. Luckily we have a couple tricks to clean it up. First lets make a Promise for the filesystem read</p>

<pre><code>function getIndex() {  
  return new Promise(resolve, reject){
    fs.readFile('index.html', 'utf-8', (err, file) =&gt; {
        if (err) {reject(err)}
          resolve(file);
    });
  }
}
</code></pre>

<p>Now lets use Promise#all so we fire off our calls at the same time but and resolve once both are complete.</p>

<pre><code>var serviceCalls = [  
  articleService.getLatestArticles(),
  getIndex()
];

Promise.all(serviceCalls)  
  .then(([context, index]) =&gt; {
      // Now we have both our context and index.
  }).catch(e =&gt; {console.error(e)})
</code></pre>

<p>It's important to understand that these service calls are fetching their data at the same time and we only resolve once both have been completed. The following code executes one call after another which is much slower:</p>

<pre><code>  articleService.getLatestArticles()
      .then(getIndex)
    .then(([context, index]) =&gt; {
        // context is `undefined` unless you plumb it through.
        // This is a sloppy pattern. Try to avoid using it and use Promise#all wherever you can.
    });
</code></pre>

<p>Anyways... So now we have our data and we need to send it back to the client. Let's put it all together:</p>

<pre><code>function sendRequest(res, template, context) {  
  if (!res.finished) {
      res.send(template(context)));
  }
}

app.get('/articles', (req, res) =&gt; {  
  var serviceCalls = [
    articleService.getLatestArticles,
    getIndex
  ];

  Promise.all(serviceCalls)
    .then(([context, index]) =&gt; {
      sendRequest(res, _.template(index), context);
    }).catch(e =&gt; {console.error(e)})

});
</code></pre>

<p>This code works fine, so where does currying come in? It doesn't really solve any problems in this code but now that we understand the above problem lets play with currying a bit.</p>

<pre><code>function sendRequestNotCurried(res, template, context) {  
  if (!res.finished) {
      res.send(template(context)));
  }
}

var sendRequest = _.curry(sendRequestNotCurried);

app.get('/articles', (req, res) =&gt; {  
  // Now that we have our req. Let's make a helper so we don't have to worry about it anymore.
  var wantsTemplateAndContext = sendRequest(req);
  var serviceCalls = [
    articleService.getLatestArticles,
    getIndex
  ];

  // Promise.all rejects all promises if one fails. We are using Q#allSettled so we can still send back an imcomplete page to the client without sending a 500 error.
  Q.allSettled(serviceCalls)
    .then(([contextResult, indexResult]) =&gt; {
        var index = indexResult.value;
        // Ignoring error handling for if the index.html fetch fails, let's create a function that can send a response to the client that takes different contexts.
        var wantsContext = wantsTemplateAndContext(index);
        var context;
        if (contextResult.state === 'fulfilled') {
          context = contextResult.value;
        } else {
          context = {errorMessage: 'Oops!'};
        }
        //Now we send out response back to the client. All arguments are satisfied now and `sendRequestNotCurried` will be called.
        wantsContext(context);
    });

});
</code></pre>

<p>This wasn't the greatest example of a good spot to use currying. The reason why I used it though is that in a real application, passing a function around to different parts of the program that just want a single argument is very useful. Currying is great for making functions that take many arguments easier to reason about. Also it makes the functions easier to test. </p>]]></description><link>http://blog.hankyates.com/more-stuff-on-currying/</link><guid isPermaLink="false">a21b273e-2f2f-4cc2-9ad5-7e205e8a6e7a</guid><dc:creator><![CDATA[Hank Yates]]></dc:creator><pubDate>Sun, 06 Dec 2015 00:41:33 GMT</pubDate></item><item><title><![CDATA[Poorman&#x27;s curry]]></title><description><![CDATA[<p>Before you interject and say we should be using promises, We know.</p>

<p>I've always heard Currying described as "A function that returns a function until all of its arguments are satisfied." It's commonly used to make utility functions. The classic example is always some adder function that has you'd never see in actual code. Below is an example of a very simple Curry that we used to help keep all of our verbs on our service class consistent. </p>

<pre><code>var verb = v =&gt; function(options) {  
  var {command, data, successCallback, failCallback, timeout} = options;
  this.request({
    verb: v,
    command: command,
    data: data,
    successCallback: successCallback,
    failCallback: failCallback,
    timeout: timeout
  });
};

class Service {  
  get: verb('GET');
  put: verb('PUT');
  post: verb('POST');
  delete: verb('DELETE');
  request(options) {
    //$.ajax or http or superagent calls made here
  }
}
</code></pre>

<p>The confusing part of the above code that made my head hurt at first is <code>v =&gt; function(options) {</code>. At first glance you think it's just another anonymous function. It's not though. Arrow functions have an implicit return so this actually returns a function defition.</p>]]></description><link>http://blog.hankyates.com/poormans-curry/</link><guid isPermaLink="false">5f579d79-ee05-46aa-9b0e-db9887a1e1c7</guid><dc:creator><![CDATA[Hank Yates]]></dc:creator><pubDate>Thu, 02 Apr 2015 18:23:26 GMT</pubDate></item><item><title><![CDATA[Invest in EcmaScript 6]]></title><description><![CDATA[<p>(This post is a response to <a href='http://www.breck-mckye.com/blog/2014/12/the-state-of-javascript-in-2015/' >The State of JavaScript in 2015</a>)</p>

<p>It's no secret that the JavaScript ecosystem has a high level churn. New libraries and frameworks coming out and pushing the boundaries is a good thing. The primary complaint seems to be the level of noise is too high. It's overwhelming for new comers who just want to build a damn app.</p>

<p>And that's fine.</p>

<p>The fundamental problem isn't the noise, it's investing in the noise. You won't get passed up if you don't pay attention to the noise. You will get passed up if you don't filter the noise, and focus on what is actually important and invest in that.</p>

<p>EcmaScript 6(ES6) is the future of JavaScript. Any library or framework you will use 5 years from now will be built on top of it. Coding in ES6 is significantly different from ES5. There are a ton of new features to learn, and you'll do yourself a favor by being ahead of the curve whenever libraries and frameworks start adopting new patterns that make use of the new features.</p>

<p>Don't get overwhelmed and use all the new features at once. Start with some of the simple features like <a href='http://www.nczonline.net/blog/2012/08/01/a-critical-review-of-ecmascript-6-quasi-literals/' >template literals</a> and <a href='http://tc39wiki.calculist.org/es6/arrow-functions/' >arrow functions</a>. Learn when it's appropriate to use them and when it's not. I've been using <a href='https://github.com/google/traceur-compiler' >Tracuer</a> (an ES6 transpiler) in production for six months and I still haven't used <a href='https://github.com/google/traceur-compiler/wiki/LanguageFeatures' #generators">Generators</a> or <a href='https://github.com/google/traceur-compiler/wiki/LanguageFeatures' #promises">Promises</a>. WeakMaps and <a href='https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set' >Sets</a> made their first appearance just this week.</p>

<p>Check out the <a href='https://github.com/paulmillr/es6-shim/' >es6 shim</a> and try including it in your next project. </p>

<p>Questions? Comments? Hit me up on <a href='https://twitter.com/hankyates' >Twitter</a>!</p>]]></description><link>http://blog.hankyates.com/invest-in-es6/</link><guid isPermaLink="false">2bc00ca7-8a46-4eff-ad53-8fa5150973eb</guid><dc:creator><![CDATA[Hank Yates]]></dc:creator><pubDate>Tue, 02 Dec 2014 08:13:03 GMT</pubDate></item><item><title><![CDATA[React renderComponentToString use cases]]></title><description><![CDATA[<p>Recently I was presented with a pretty cool challenge. Create a photo gallery from a macro inside of an article that looks like this: <code>[Gallery:1234,4567,7890]</code>. The numbers being MediaIds. Obviously this is a RegExp problem and I'll spare you that part of the implementation, but once we have our ids and images we obviously want instatiate a React component but how do we get it inline with the rest of the article content?</p>

<p>This is where <code>renderComponentToString</code> comes to the rescue: </p>

<pre><code>replaceMacro: (htmlStr) =&gt; {  
  var galleryRegex = /\[Gallery:\s?([\s\d,])\]/i;
  var ids = htmlStr.match(htmlStr)[1].split(',').map((id) =&gt; parseInt(id, 10));
  var renderedGallery = React.renderComponentToString(&lt;ImageGallery imageIds=ids/&gt;);
  return htmlStr.replace(galleryRegex, renderedGallery)
};
</code></pre>

<p>I don't know if the event handlers get bound in this case. We use a jQuery gallery which get initialized after the gallery is in the DOM, So I suspect that might be saving us from having the events not getting bound. </p>

<p>The React documentation reccomends using <code>renderComponentToString</code> on the server probably for SEO purposes, however as you can see it can be handy in different use cases than that!</p>]]></description><link>http://blog.hankyates.com/react-rendercomponenttostring-use-cases/</link><guid isPermaLink="false">f972e27d-f95a-4007-a124-a4dd8a4f84ab</guid><dc:creator><![CDATA[Hank Yates]]></dc:creator><pubDate>Mon, 12 May 2014 03:30:26 GMT</pubDate></item><item><title><![CDATA[Teaching Javascript is hard]]></title><description><![CDATA[<p>This can probably be boiled down to "Teaching is Hard," but I think Javascript does have it's own set of unique challenges. Do you cover frontend or backend? Do you teach native implementations of tools or go ahead and just teach jQuery? Is teaching Grunt going to be out of date by the time your students get out into the real world? </p>

<p>The answer to all these questions is "Yes."</p>

<p>I think it's impossible not to overwhelm Javascript students, because Javascript is overwhelming. At the CodeFellows Javascript Foundations II night course I've been teaching the last couple of weeks I threw a difficult homework assignment at my students. Everyone, including myself, paniced. I left the class feeling anxious that I might have gone "too hard." Then the Pull Requests started coming in and ... They looked great! I threw 4/5 new concepts at the class and it took some time for the students to understand in their own way, but at the end of the day most of the class had working code.</p>

<p>Overall the experience was definitely challenging and rewarding for both the students and myself. Often times with programming it's easy to look at everything you don't know. Looking at what we covered in the short four week course, It was clear that we had moved through a ton of material and seeing the journey from start to end was amazing!</p>]]></description><link>http://blog.hankyates.com/teaching-javascript-is-hard/</link><guid isPermaLink="false">d7fec8d0-8fdb-46ca-831f-a78b3394db99</guid><dc:creator><![CDATA[Hank Yates]]></dc:creator><pubDate>Fri, 09 May 2014 05:56:54 GMT</pubDate></item><item><title><![CDATA[React is amazing]]></title><description><![CDATA[<p>I've been using React for a bout a month now. I have to say it is probably the best peice of code I've enjoyed since Backbone. After using Typescript+Angular and hating ever moment of it. Working with React has been a breath of fresh air.</p>

<p>Not to say that React doesn't have it's weaknesses. I'm not a huge fan of precompiling and all the headaches that come along with it. I think that's just the way the world is though on the Front End right now and you just have to deal with it. React isn't nearly as enjoyable without <a href='http://facebook.github.io/react/docs/jsx-in-depth.html' >JSX</a>. </p>

<p>The main advantage of React is that it is simple.  </p>

<pre><code>/** @jsx React.DOM */

var LikeButton = React.createClass({  
  getInitialState: function() {
    return {liked: false};
  },
  handleClick: function(event) {
    this.setState({liked: !this.state.liked});
  },
  // render is the only required method
  render: function() {
    var text = this.state.liked ? 'like' : 'unlike';
    return (
      &lt;p className='{this.props.color}' onClick={this.handleClick}&gt;
        You {text} this. Click to toggle.
      &lt;/p&gt;
    );
  }
});

// This is one way to bind your component to the dom. 
// It's more common to include other components within a component though. 
React.renderComponent(  
  &lt;LikeButton /&gt;,
  document.getElementById('example')
);
</code></pre>

<p>Your components have properties and state. Everything else you can handle on your own with your own tools. The React website makes mention that they essentially just want to be the V in the MVC. I think that attitude of being small and modular is what makes React so wonderful. </p>

<p>We have been able to do some pretty cool stuff with react using <a href='https://github.com/tmpvar/jsdom' >JSDom</a> and <a href='https://github.com/substack/node-browserify' >Browserify</a>. I hope I get to write more about it soon. I'm specifically trying to figure out an effective way to unit test React components. If you have some advice, hit me up on twitter please!</p>]]></description><link>http://blog.hankyates.com/react-is-amazing/</link><guid isPermaLink="false">16ba09c4-7336-4261-bca0-9c0b9863e472</guid><dc:creator><![CDATA[Hank Yates]]></dc:creator><pubDate>Wed, 02 Apr 2014 08:12:52 GMT</pubDate></item><item><title><![CDATA[Website prototype]]></title><description><![CDATA[<p>I've been working a little on my website lately. Finally have a working prototype that has helped me figure out some of the challenges I'm going to face and need to solve. </p>

<p><img src='https://dl.dropboxusercontent.com/u/2555196/website/prototype.png'  alt="https://dl.dropboxusercontent.com/u/2555196/website/prototype.png" /></p>

<p>First issue is how do I make the text readable on top of an image? I'm using <code>blur</code> in my prototype but I still think its unreadable. I tinkered with adding a <code>text-stroke</code> to the heading, but I still want it to be readable for older browsers without css3 features. I'm last resorting to adding an <code>opacity</code> layer in front of the image. Too much <code>opacity</code> on a page can really hurt performance, especially with as many css3 transitions as I plan to have. I've also tinkered with adjusting the grayscale, but that didn't help readability either. Have a suggestion or an article? Hit me up on <a href='http://twitter.com/hankyates' >Twitter</a>!</p>

<p>The second issue is the responsive layout. I would like to have the cards expand to the center of the page. The problem is when you increase the width of an element it always takes up the space to the right. I'm exploring having a negative <code>margin-left</code> to offset but negative margins are always a code smell so hopefully I can avoid that!</p>

<p>Also pen and paper for layout design is the best!</p>

<p><img src='https://pbs.twimg.com/media/Bg4C7SjCcAAXKqz.jpg'  alt="" /></p>]]></description><link>http://blog.hankyates.com/website-prototype/</link><guid isPermaLink="false">c116cdf5-ef3c-4087-b8c2-8b19290af17b</guid><dc:creator><![CDATA[Hank Yates]]></dc:creator><pubDate>Thu, 27 Feb 2014 05:09:21 GMT</pubDate></item><item><title><![CDATA[That time I deleted master on purpose...]]></title><description><![CDATA[<p><code>git push origin :master</code> is a pretty scary command to run. Let me explain though. I decided to use a static site generator called <a href='http://assemble.io/' >Assemble</a>. The Grunt plugins are all tailored to releasing the compiled static site from a sub-folder of the project to the branch <code>gh-pages</code>. This is perfect if you are using <a href='http://assemble.io/' >Github Pages</a> for a project but what about if you are using it for your organization? The key difference here is that Github looks at the <code>master</code> branch for an organization instead. </p>

<p>So the solution here was to do some branch gymnastics. </p>

<ul>
<li><code>git checkout -b build</code></li>
<li>Using the fantastic <a href='https://github.com/tschaub/grunt-gh-pages' >grunt-gh-pages</a> plugin we tell it to use <code>master</code> instead:</li>
</ul>

<pre><code class="javascript">     'gh-pages': {
        options: {
          base: 'site',
          branch: 'master'
        },
        src: ['**']
      }
</code></pre>

<p>but we get errors:</p>

<pre><code>hank@hank1:~/sites/hankyates.github.io$ grunt gh-pages  
Running "gh-pages:src" (gh-pages) task  
Cloning git@github.com:hankyates/hankyates.github.io.git into .grunt/grunt-gh-pages/gh-pages/src  
Cleaning  
Fetching origin  
Checking out origin/master  
Removing files  
Copying files  
Adding all  
Committing  
Pushing  
Warning: To git@github.com:hankyates/hankyates.github.io.git  
 ! [rejected]        master -&gt; master (non-fast-forward)
error: failed to push some refs to 'git@github.com:hankyates/hankyates.github.io.git'  
To prevent you from losing history, non-fast-forward updates were rejected  
Merge the remote changes (e.g. 'git pull') before pushing again.  See the  
'Note about fast-forwards' section of 'git push --help' for details.  
 Use --force to continue.
</code></pre>

<p>Oh no! git doesn't like that we are trying to push an orphaned branch with no history to a branch with history. Normally this is a good thing. Git has prevented us from clobbering our history, but we still have our history and our code but it's on the <code>build</code> branch instead now. </p>

<p>It's at this point we run the super dangerous command <code>git push origin :master</code> which deletes the master branch on github. Note that the grunt plugin clones the repository to a temporary folder, copies the compiled static site, commits, and pushes to <code>master</code>. So we still have a copy of <code>master</code> locally and can push it back if need be.</p>

<p>After running <code>grunt gh-pages</code> our site is is compiled and pushed to Github. A nice trick is to set the default branch on Github to <code>build</code>.</p>]]></description><link>http://blog.hankyates.com/that-time-i-deleted-master-on-purpose-and-it-worked/</link><guid isPermaLink="false">f3f31b2f-1e81-40ac-966e-6669e721b29d</guid><dc:creator><![CDATA[Hank Yates]]></dc:creator><pubDate>Thu, 13 Feb 2014 22:14:43 GMT</pubDate></item></channel></rss>