<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Matt&#039;s work blog</title>
	<atom:link href="http://mattfrear.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://mattfrear.com</link>
	<description>.NET development from London.</description>
	<lastBuildDate>Sat, 18 May 2013 07:31:01 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='mattfrear.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://1.gravatar.com/blavatar/947c1ebe9baa6b4763ba4971108706ea?s=96&#038;d=http%3A%2F%2Fs2.wp.com%2Fi%2Fbuttonw-com.png</url>
		<title>Matt&#039;s work blog</title>
		<link>http://mattfrear.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://mattfrear.com/osd.xml" title="Matt&#039;s work blog" />
	<atom:link rel='hub' href='http://mattfrear.com/?pushpress=hub'/>
		<item>
		<title>RavenDB &#8211; Input string was not in a correct format</title>
		<link>http://mattfrear.com/2013/04/30/ravendb-formatexception/</link>
		<comments>http://mattfrear.com/2013/04/30/ravendb-formatexception/#comments</comments>
		<pubDate>Tue, 30 Apr 2013 22:08:46 +0000</pubDate>
		<dc:creator>mattfrear</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[ravendb]]></category>

		<guid isPermaLink="false">http://mattfrear.com/?p=686</guid>
		<description><![CDATA[In a RavenDB ASP.NET MVC app I was recently working on, I was constantly seeing good ol&#8217; System.FormatException &#8211; &#8220;Input string was not in a correct format&#8221;. My entities all use ints for their Ids. After a while I noticed (via the RavenDB Management Console) that my entities had Ids like &#8220;tab/123&#8243;, but previously the <a href="http://mattfrear.com/2013/04/30/ravendb-formatexception/" class="excerpt-more-link">[&#8230;]</a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mattfrear.com&#038;blog=12300335&#038;post=686&#038;subd=mattfrear&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>In a RavenDB ASP.NET MVC app I was recently working on, I was constantly seeing good ol&#8217; System.FormatException &#8211; &#8220;Input string was not in a correct format&#8221;.</p>
<p>My entities all use ints for their Ids.</p>
<p>After a while I noticed (via the RavenDB Management Console) that my entities had Ids like &#8220;tab/123&#8243;, but previously the Ids were like &#8220;tab-123&#8243;.</p>
<p>The problem turned out to be that I had accidentally removed this line while doing some refactoring:</p>
<pre class="brush: csharp; title: ; notranslate">

documentStore.Conventions.IdentityPartsSeparator = &quot;-&quot;;

</pre>
<p>Once I put that back in I stopped seeing the System.FormatException and all was right in the world.</p>
<p>&nbsp;</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mattfrear.wordpress.com/686/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mattfrear.wordpress.com/686/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mattfrear.com&#038;blog=12300335&#038;post=686&#038;subd=mattfrear&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://mattfrear.com/2013/04/30/ravendb-formatexception/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/5da3065d9a83a23a90c18a5e7d20b180?s=96&#38;d=http%3A%2F%2F2.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">mattfrear</media:title>
		</media:content>
	</item>
		<item>
		<title>Retrieve child items with an integer ID in a many-to-many with RavenDB</title>
		<link>http://mattfrear.com/2013/04/03/retrieve-child-items-with-an-integer-id-in-a-many-to-many-with-ravendb/</link>
		<comments>http://mattfrear.com/2013/04/03/retrieve-child-items-with-an-integer-id-in-a-many-to-many-with-ravendb/#comments</comments>
		<pubDate>Wed, 03 Apr 2013 21:42:10 +0000</pubDate>
		<dc:creator>mattfrear</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[ravendb]]></category>

		<guid isPermaLink="false">http://mattfrear.com/?p=679</guid>
		<description><![CDATA[I have a many to many relationship, like so When I load a Movie, I also want to load all of the Actors associated with that Movie. This can be done using Raven&#8217;s Load&#60;T&#62;(IEnumerable&#60;System.ValueType&#62; ids) method, and casting the int[] to an array of ValueType, like so:<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mattfrear.com&#038;blog=12300335&#038;post=679&#038;subd=mattfrear&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>I have a many to many relationship, like so</p>
<pre class="brush: csharp; title: ; notranslate">
public class Movie
{
   public int Id { get; set; }
   public string Title { get; set; }
   public int[] ActorIds { get; set; }
   // etc
}

public class Actor
{
   public int Id { get; set; }
   public int Name { get; set; }
   // etc
}
</pre>
<p>When I load a Movie, I also want to load all of the Actors associated with that Movie.</p>
<p>This can be done using Raven&#8217;s Load&lt;T&gt;(IEnumerable&lt;System.ValueType&gt; ids) method, and casting the int[] to an array of ValueType, like so:</p>
<pre class="brush: csharp; title: ; notranslate">
var movie = RavenSession.Load&lt;Movie&gt;(movieId);
var actorIds = movie.TabIds.Cast&lt;System.ValueType&gt;();

var actors = RavenSession.Load&lt;Actor&gt;(actorIds).OrderBy(x =&gt; x.Name);
</pre>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mattfrear.wordpress.com/679/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mattfrear.wordpress.com/679/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mattfrear.com&#038;blog=12300335&#038;post=679&#038;subd=mattfrear&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://mattfrear.com/2013/04/03/retrieve-child-items-with-an-integer-id-in-a-many-to-many-with-ravendb/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/5da3065d9a83a23a90c18a5e7d20b180?s=96&#38;d=http%3A%2F%2F2.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">mattfrear</media:title>
		</media:content>
	</item>
		<item>
		<title>Upgrade a Macbook with Boot Camp from Windows 7 to Windows 8 Pro</title>
		<link>http://mattfrear.com/2012/11/06/upgrade-a-macbook-with-boot-camp-from-windows-7-to-windows-8-pro/</link>
		<comments>http://mattfrear.com/2012/11/06/upgrade-a-macbook-with-boot-camp-from-windows-7-to-windows-8-pro/#comments</comments>
		<pubDate>Tue, 06 Nov 2012 09:47:59 +0000</pubDate>
		<dc:creator>mattfrear</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[windows8]]></category>

		<guid isPermaLink="false">http://mattfrear.com/?p=674</guid>
		<description><![CDATA[I have a mid-2011 Macbook Air running both OSX Lion and Windows 7 using Boot Camp. Over the weekend I upgraded it to Windows 8 by doing the download only installation. The process was quite simple and it worked fine. Here&#8217;s the steps: Boot into Windows 7 Go to http://windows.microsoft.com/en-GB/windows/download-shop and click &#8220;Buy Windows 8&#8243;. Download the installer <a href="http://mattfrear.com/2012/11/06/upgrade-a-macbook-with-boot-camp-from-windows-7-to-windows-8-pro/" class="excerpt-more-link">[&#8230;]</a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mattfrear.com&#038;blog=12300335&#038;post=674&#038;subd=mattfrear&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>I have a mid-2011 Macbook Air running both OSX Lion and Windows 7 using Boot Camp.</p>
<p>Over the weekend I upgraded it to Windows 8 by doing the download only installation. The process was quite simple and it worked fine. Here&#8217;s the steps:</p>
<ol>
<li>Boot into Windows 7</li>
<li>Go to <a href="http://windows.microsoft.com/en-GB/windows/download-shop">http://windows.microsoft.com/en-GB/windows/download-shop</a> and click &#8220;Buy Windows 8&#8243;. Download the installer and start it up.</li>
<li>Pay! The installer will ask for you billing details, credit card / debit card / Paypal details etc. At £25 I thought it was a cheap enough upgrade, especially since I would be going from Windows 7 Home Premium to Windows 8 Pro which means I&#8217;d get Remote Desktop etc.</li>
<li>Wait half an hour while the installer downloads the OS.</li>
<li>Once the install starts, it will ask you if you want to
<ol>
<li>Keep all your programs and your personal info and settings</li>
<li>Keep your personal settings only</li>
<li>Keep nothing. I went for this option as I always like to start fresh.</li>
</ol>
</li>
<li>Now I had a few problems. The install demanded that I have 20Gb free on my C: and I only had about 5 Gb free. I had to stop the installation to free up some disk space. I did this by:
<ol>
<li>Running Disk Cleanup</li>
<li>Disabled Virtual memory, which shrunk the pagefile.sys from 4Gb to 0Gb.</li>
<li>Disabled hibernate, which removed the 4Gb hiberfile.sys</li>
<li>Deleted c:\Windows\TrustedInstaller folder &#8211; but that was a mistake, because then I couldn&#8217;t uninstall any programs to free up the necessary space!</li>
<li>Since I was choosing to keep nothing on C: anyway I deleted folders willy-nilly from C:\Program Files and C:\Program Files (x86)</li>
</ol>
</li>
<li>After that I was able to continue the installation which took another 20 mins or so. It rebooted 3 or 4 times, during which  I had to hold down the Mac&#8217;s option key at boot and choose the Windows partition.</li>
<li>All done! Windows 8 works fine.</li>
</ol>
<p>Once it was installed I did a couple of clean-up tasks.</p>
<ol>
<li>My C: was almost full again, because the install had backed up everything in the C:\Windows.old folder. So I ran Disk Cleanup again and clicked the &#8220;Clean up system files&#8221; button to remove those.</li>
<li>I no longer had Apple&#8217;s Boot Camp drivers installed in Windows, so I had boot into OSX, start the Boot Camp helper and copied the Boot Camp drivers to a USB memory stick. Then rebooted into Windows and installed those drivers. Worth doing so that the Mac&#8217;s hotkeys (volume up/down, screen brightness etc) would work.</li>
</ol>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mattfrear.wordpress.com/674/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mattfrear.wordpress.com/674/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mattfrear.com&#038;blog=12300335&#038;post=674&#038;subd=mattfrear&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://mattfrear.com/2012/11/06/upgrade-a-macbook-with-boot-camp-from-windows-7-to-windows-8-pro/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/5da3065d9a83a23a90c18a5e7d20b180?s=96&#38;d=http%3A%2F%2F2.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">mattfrear</media:title>
		</media:content>
	</item>
		<item>
		<title>Regular expression replace in Visual Studio</title>
		<link>http://mattfrear.com/2012/09/05/regular-expression-replace-in-visual-studio/</link>
		<comments>http://mattfrear.com/2012/09/05/regular-expression-replace-in-visual-studio/#comments</comments>
		<pubDate>Wed, 05 Sep 2012 08:14:51 +0000</pubDate>
		<dc:creator>mattfrear</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[visual studio]]></category>

		<guid isPermaLink="false">http://mattfrear.com/?p=669</guid>
		<description><![CDATA[I can never remember how to do replaces in Visual Studio using regular expressions, so here&#8217;s a quick example. I&#8217;ve got 30 classes that implement BasePage. I want to change this: to this: The regex should find: and replace with:<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mattfrear.com&#038;blog=12300335&#038;post=669&#038;subd=mattfrear&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>I can never remember how to do replaces in Visual Studio using regular expressions, so here&#8217;s a quick example.</p>
<p>I&#8217;ve got 30 classes that implement BasePage. I want to change this:</p>
<pre class="brush: csharp; title: ; notranslate">
public class VariationsPage : BasePage
</pre>
<p>to this:</p>
<pre class="brush: csharp; title: ; notranslate">
public class VariationsPage : BasePage&lt;VariationsPage&gt;
</pre>
<p>The regex should find:</p>
<pre class="brush: plain; title: ; notranslate">
public class {.*} \: BasePage
</pre>
<p>and replace with:</p>
<pre class="brush: plain; title: ; notranslate">
public class \1 \: BasePage&lt;\1&gt;
</pre>
<p><a href="http://mattfrear.files.wordpress.com/2012/09/regex.jpg"><img src="http://mattfrear.files.wordpress.com/2012/09/regex.jpg?w=500" alt="" title="regex"   class="aligncenter size-full wp-image-670" /></a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mattfrear.wordpress.com/669/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mattfrear.wordpress.com/669/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mattfrear.com&#038;blog=12300335&#038;post=669&#038;subd=mattfrear&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://mattfrear.com/2012/09/05/regular-expression-replace-in-visual-studio/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/5da3065d9a83a23a90c18a5e7d20b180?s=96&#38;d=http%3A%2F%2F2.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">mattfrear</media:title>
		</media:content>

		<media:content url="http://mattfrear.files.wordpress.com/2012/09/regex.jpg" medium="image">
			<media:title type="html">regex</media:title>
		</media:content>
	</item>
		<item>
		<title>Meteor todos sample &#8211; add buttons to move items up and down</title>
		<link>http://mattfrear.com/2012/09/01/meteor-todos-part-3/</link>
		<comments>http://mattfrear.com/2012/09/01/meteor-todos-part-3/#comments</comments>
		<pubDate>Sat, 01 Sep 2012 15:29:16 +0000</pubDate>
		<dc:creator>mattfrear</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[meteorjs]]></category>

		<guid isPermaLink="false">http://mattfrear.com/?p=661</guid>
		<description><![CDATA[This is the sixth in a x part series about Meteor for beginners. Part One &#8211; Leaderboard: Add a button to change sort order Part Two &#8211; Leaderboard: Add a button to randomise players&#8217; scores Part Three &#8211; Leaderboard: Add and remove scientists from the leaderboard Part Four &#8211; Todos: Make urls friendly Part Five <a href="http://mattfrear.com/2012/09/01/meteor-todos-part-3/" class="excerpt-more-link">[&#8230;]</a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mattfrear.com&#038;blog=12300335&#038;post=661&#038;subd=mattfrear&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>This is the sixth in a x part series about <a href="http://meteor.com">Meteor</a> for beginners.</p>
<ul>
<li><a href="http://mattfrear.com/2012/08/29/enhancing-the-meteor-leaderboard-sample/" title="Enhancing the Meteor leaderboard sample">Part One &#8211; Leaderboard: Add a button to change sort order</a></li>
<li><a href="http://mattfrear.com/2012/08/30/meteor-leaderboard-part-2/" title="Meteor leaderboard sample exercise two">Part Two &#8211; Leaderboard: Add a button to randomise players&#8217; scores</a></li>
<li><a href="http://mattfrear.com/2012/08/31/meteor-leaderboard-part-3/" title="Meteor leaderboard sample exercise three">Part Three &#8211; Leaderboard: Add and remove scientists from the leaderboard</a></li>
<li><a href="http://mattfrear.com/2012/08/31/meteor-todos-part-1/" title="Meteor todos sample – friendly URLs">Part Four &#8211; Todos: Make urls friendly</a></li>
<li><a href="http://mattfrear.com/2012/08/31/meteor-todos-part-2/" title="Meteor todos sample – remove all items">Part Five &#8211; Todos: Add a button to remove all items</a></li>
<li>Part Six &#8211; Todos: Add buttons to move items up and down</li>
</ul>
<p>Let&#8217;s add the buttons to the UI first. I&#8217;ve decided to put them next to the delete button, so I will copy the html and css for the &#8220;destroy&#8221; class so that the UI is consistant.</p>
<pre class="brush: xml; highlight: [8,9]; title: ; notranslate">
&lt;template name=&quot;todo_item&quot;&gt;
  &lt;li class=&quot;todo {{done_class}}&quot;&gt;
    {{#if editing}}
      &lt;div class=&quot;edit&quot;&gt;
        &lt;input id=&quot;todo-input&quot; type=&quot;text&quot; value=&quot;{{text}}&quot; /&gt;
      &lt;/div&gt;
    {{else}}
      &lt;div class=&quot;move-up&quot;&gt;&lt;/div&gt;
      &lt;div class=&quot;move-down&quot;&gt;&lt;/div&gt;
      &lt;div class=&quot;destroy&quot;&gt;&lt;/div&gt;
      ...
</pre>
<pre class="brush: css; collapse: true; highlight: [4,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,31,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53]; light: false; title: ; toolbar: true; notranslate">
#item-list .todo .destroy {
    cursor: pointer;
    position: absolute;
    margin-left: 50px;
    left: 5px;
    top: 15px;
    height: 20px;
    width: 20px;
}

#item-list .todo .move-up {
    cursor: pointer;
    position: absolute;
    left: 5px;
    top: 15px;
    height: 20px;
    width: 20px;
}

#item-list .todo .move-down {
    cursor: pointer;
    position: absolute;
    margin-left: 25px;
    left: 5px;
    top: 15px;
    height: 20px;
    width: 20px;
}

#item-list .todo .display, #item-list .todo .edit {
    margin-left: 80px;
    height: 100%;
    width: auto;
    float: left;
    padding-top: 18px;
    line-height: 1;
}

#item-list .todo:hover .move-up {
    background: url('/arrowup.png') no-repeat 0 0;
}

#item-list .todo .move-up:hover {
    background-position: 0 -20px;
}

#item-list .todo:hover .move-down {
    background: url('/arrowdown.png') no-repeat 0 0;
}

#item-list .todo .move-down:hover {
    background-position: 0 -20px;
}
</pre>
<p>PS. I spent longer making the up down arrow icons in an image editor than writing the code for this post!</p>
<p>Items in each todo list are currently sorted by their timestamp:</p>
<pre class="brush: jscript; title: ; notranslate">
Template.todos.todos = function () {

  ...

  return Todos.find(sel, {sort: {timestamp: 1}});
};
</pre>
<p>I will continue to use the timestamp to control the sort order. When the up button is clicked, set the current item&#8217;s timestamp to be 1ms less than the item above it.</p>
<pre class="brush: jscript; title: ; notranslate">
Template.todo_item.events = {
  ...

  'click .move-up': function() {
    var todos = Template.todos.todos().fetch();
    var currentItemIndex = todoRanking(this, todos);

    if (currentItemIndex &gt; 0) {
      var todoAboveMe = todos[currentItemIndex - 1];
      Todos.update(this._id, {$set: {timestamp: todoAboveMe.timestamp - 1}});
    }
  }
</pre>
<pre class="brush: plain; title: ; notranslate">
var todoRanking = function(todoItem, todoArray) {
  var ids = todoArray.map(function (todo) { return todo._id; });
  return ids.indexOf(todoItem._id);
};
</pre>
<p>We can do something similar to move an item down.</p>
<pre class="brush: jscript; title: ; notranslate">
  'click .move-down': function() {
    var todos = Template.todos.todos().fetch();
    var currentItemIndex = todoRanking(this, todos);

    if (currentItemIndex &lt; todos.length -1) {
      var todoBelowMe = todos[currentItemIndex + 1];
      Todos.update(this._id, {$set: {timestamp: todoBelowMe.timestamp + 1}});
    }
  }
</pre>
<p><a href="http://mattfrear.files.wordpress.com/2012/09/screen-shot-2012-09-01-at-16-21-19.png"><img src="http://mattfrear.files.wordpress.com/2012/09/screen-shot-2012-09-01-at-16-21-19.png?w=500&#038;h=296" alt="" title="Screen Shot 2012-09-01 at 16.21.19" width="500" height="296" class="aligncenter size-full wp-image-666" /></a></p>
<p>See the code on <a href="https://github.com/mattfrear/meteor-todos">github</a>.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mattfrear.wordpress.com/661/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mattfrear.wordpress.com/661/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mattfrear.com&#038;blog=12300335&#038;post=661&#038;subd=mattfrear&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://mattfrear.com/2012/09/01/meteor-todos-part-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/5da3065d9a83a23a90c18a5e7d20b180?s=96&#38;d=http%3A%2F%2F2.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">mattfrear</media:title>
		</media:content>

		<media:content url="http://mattfrear.files.wordpress.com/2012/09/screen-shot-2012-09-01-at-16-21-19.png" medium="image">
			<media:title type="html">Screen Shot 2012-09-01 at 16.21.19</media:title>
		</media:content>
	</item>
		<item>
		<title>Meteor todos sample &#8211; remove all items</title>
		<link>http://mattfrear.com/2012/08/31/meteor-todos-part-2/</link>
		<comments>http://mattfrear.com/2012/08/31/meteor-todos-part-2/#comments</comments>
		<pubDate>Fri, 31 Aug 2012 20:16:27 +0000</pubDate>
		<dc:creator>mattfrear</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[meteorjs]]></category>

		<guid isPermaLink="false">http://mattfrear.com/?p=656</guid>
		<description><![CDATA[This is the fifth in a x part series about Meteor for beginners. Part One &#8211; Leaderboard: Add a button to change sort order Part Two &#8211; Leaderboard: Add a button to randomise players&#8217; scores Part Three &#8211; Leaderboard: Add and remove scientists from the leaderboard Part Four &#8211; Todos: Make urls friendly Part Five <a href="http://mattfrear.com/2012/08/31/meteor-todos-part-2/" class="excerpt-more-link">[&#8230;]</a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mattfrear.com&#038;blog=12300335&#038;post=656&#038;subd=mattfrear&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>This is the fifth in a x part series about <a href="http://meteor.com">Meteor</a> for beginners.</p>
<ul>
<li><a href="http://mattfrear.com/2012/08/29/enhancing-the-meteor-leaderboard-sample/" title="Enhancing the Meteor leaderboard sample">Part One &#8211; Leaderboard: Add a button to change sort order</a></li>
<li><a href="http://mattfrear.com/2012/08/30/meteor-leaderboard-part-2/" title="Meteor leaderboard sample exercise two">Part Two &#8211; Leaderboard: Add a button to randomise players&#8217; scores</a></li>
<li><a href="http://mattfrear.com/2012/08/31/meteor-leaderboard-part-3/" title="Meteor leaderboard sample exercise three">Part Three &#8211; Leaderboard: Add and remove scientists from the leaderboard</a></li>
<li><a href="http://mattfrear.com/2012/08/31/meteor-todos-part-1/" title="Meteor todos sample – friendly URLs">Part Four &#8211; Todos: Make urls friendly</a></li>
<li>Part Five &#8211; Todos: Add a button to remove all items (this post)</li>
</ul>
<h4>Exercise 2: Add a Remove all items button</h4>
<p>As usual, let&#8217;s add the button to the html first. I&#8217;m gonna stick it in the top frame next to the list of tags cos I can&#8217;t think of anywhere better to put it.</p>
<pre class="brush: xml; highlight: [9,10,11]; title: ; notranslate">
&lt;template name=&quot;tag_filter&quot;&gt;
  &lt;div id=&quot;tag-filter&quot; class=&quot;tag-list&quot;&gt;
    &lt;div class=&quot;label&quot;&gt;Show:&lt;/div&gt;
    {{#each tags}}
      &lt;div class=&quot;tag {{selected}}&quot;&gt;
        {{tag_text}} &lt;span class=&quot;count&quot;&gt;({{count}})&lt;/span&gt;
      &lt;/div&gt;
    {{/each}}
    &lt;div class=&quot;label&quot;&gt;
        &lt;input type=&quot;button&quot; class=&quot;clear-items&quot; value=&quot;Clear all items&quot; /&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/template&gt;
</pre>
<p>And now the code to handle the button click event:</p>
<pre class="brush: jscript; highlight: [8,9,10,11,12,13,14,15]; title: ; notranslate">

Template.tag_filter.events = {
  'mousedown .tag': function () {
    if (Session.equals('tag_filter', this.tag))
      Session.set('tag_filter', null);
    else
      Session.set('tag_filter', this.tag);
  },
  'click .clear-items': function() {
    if (confirm('Are you sure you want to remove all todo items from the current list? This action cannot be undone.')) {
      var list_id = Session.get('list_id');
      if (!list_id)
        return;

      Todos.remove({list_id: list_id});
    }
  }
};
</pre>
<p>Easy!<br />
<a href="http://mattfrear.files.wordpress.com/2012/08/screen-shot-2012-08-31-at-21-12-54.png"><img src="http://mattfrear.files.wordpress.com/2012/08/screen-shot-2012-08-31-at-21-12-54.png?w=500&#038;h=393" alt="" title="Screen Shot 2012-08-31 at 21.12.54" width="500" height="393" class="aligncenter size-full wp-image-657" /></a></p>
<p>See the code on <a href="https://github.com/mattfrear/meteor-todos">github</a>.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mattfrear.wordpress.com/656/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mattfrear.wordpress.com/656/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mattfrear.com&#038;blog=12300335&#038;post=656&#038;subd=mattfrear&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://mattfrear.com/2012/08/31/meteor-todos-part-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/5da3065d9a83a23a90c18a5e7d20b180?s=96&#38;d=http%3A%2F%2F2.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">mattfrear</media:title>
		</media:content>

		<media:content url="http://mattfrear.files.wordpress.com/2012/08/screen-shot-2012-08-31-at-21-12-54.png" medium="image">
			<media:title type="html">Screen Shot 2012-08-31 at 21.12.54</media:title>
		</media:content>
	</item>
		<item>
		<title>Meteor todos sample &#8211; friendly URLs</title>
		<link>http://mattfrear.com/2012/08/31/meteor-todos-part-1/</link>
		<comments>http://mattfrear.com/2012/08/31/meteor-todos-part-1/#comments</comments>
		<pubDate>Fri, 31 Aug 2012 19:55:03 +0000</pubDate>
		<dc:creator>mattfrear</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[meteorjs]]></category>

		<guid isPermaLink="false">http://mattfrear.com/?p=647</guid>
		<description><![CDATA[This is the fourth in a x part series about Meteor for beginners. Part One &#8211; Leaderboard: Add a button to change sort order Part Two &#8211; Leaderboard: Add a button to randomise players&#8217; scores Part Three &#8211; Leaderboard: Add and remove players from the leaderboard Part Four &#8211; Todos: make urls friendly (this post) <a href="http://mattfrear.com/2012/08/31/meteor-todos-part-1/" class="excerpt-more-link">[&#8230;]</a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mattfrear.com&#038;blog=12300335&#038;post=647&#038;subd=mattfrear&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>This is the fourth in a x part series about <a href="http://meteor.com">Meteor</a> for beginners.</p>
<ul>
<li><a href="http://mattfrear.com/2012/08/29/enhancing-the-meteor-leaderboard-sample/" title="Enhancing the Meteor leaderboard sample">Part One &#8211; Leaderboard: Add a button to change sort order</a></li>
<li><a href="http://mattfrear.com/2012/08/30/meteor-leaderboard-part-2/" title="Meteor leaderboard sample exercise two">Part Two &#8211; Leaderboard: Add a button to randomise players&#8217; scores</a></li>
<li><a href="http://mattfrear.com/2012/08/31/meteor-leaderboard-part-3/" title="Meteor leaderboard sample exercise three">Part Three &#8211; Leaderboard: Add and remove players from the leaderboard</a></li>
<li>Part Four &#8211; Todos: make urls friendly (this post)</li>
</ul>
<h4>Introduction</h4>
<p>I&#8217;ve been trying to get up to speed with <a href="http://meteor.com">Meteor</a> lately. Since I don&#8217;t have any experience with nodejs it&#8217;s been a challenge.</p>
<p>I started by looking at the leaderboard sample, and then the <a href="http://meteor.com/examples/todos">todos sample</a>. At the end of the video the author lays down a challenge &#8211; to make the URLs friendly. So instead of <a href="http://localhost:3000/bbbeec7c-6749-400b-bc45-4ed744e010b7" rel="nofollow">http://localhost:3000/bbbeec7c-6749-400b-bc45-4ed744e010b7</a> it should be <a href="http://localhost:3000/Languages" rel="nofollow">http://localhost:3000/Languages</a>. In order to do that I needed to understand how routing works.</p>
<p><a href="http://mattfrear.files.wordpress.com/2012/08/screen-shot-2012-08-23-at-21-09-48.png"><img class="aligncenter size-full wp-image-570" title="todos sample" src="http://mattfrear.files.wordpress.com/2012/08/screen-shot-2012-08-23-at-21-09-48.png?w=500&#038;h=351" alt="" width="500" height="351" /></a></p>
<p>When you click on a todo list in the left, this code fires:</p>
<pre class="brush: jscript; title: ; notranslate">
Template.lists.events = {
  'mousedown .list': function (evt) { // select list
    Router.setList(this._id);
  },
</pre>
<p>which calls:</p>
<pre class="brush: jscript; highlight: [9,10,11]; title: ; notranslate">
var TodosRouter = Backbone.Router.extend({
  routes: {
    &quot;:list_id&quot;: &quot;main&quot;
  },
  main: function (list_id) {
    Session.set(&quot;list_id&quot;, list_id);
    Session.set(&quot;tag_filter&quot;, null);
  },
  setList: function (list_id) {
    this.navigate(list_id, true);
  }
});
</pre>
<p>The setList function calls navigate, which is <a href="http://backbonejs.org/#Router-navigate">Backbone.js&#8217;s router function</a> to save the current location in the browser&#8217;s history. The &#8220;true&#8221; parameter also tells the browser to navigate to the url, so if list_id = &#8220;1234&#8243; the browser will navigate to i.e. localhost:3000/1234.</p>
<p>According to the routes defined here</p>
<pre class="brush: jscript; highlight: [2,3]; title: ; notranslate">
var TodosRouter = Backbone.Router.extend({
  routes: {
    &quot;:list_id&quot;: &quot;main&quot;
  },
</pre>
<p>if I navigate to localhost:3000/1234, then &#8220;1234&#8243; will be passed to the &#8220;main&#8221; function as the &#8220;list_id&#8221; parameter. Which takes us to:</p>
<pre class="brush: jscript; highlight: [5,6,7]; title: ; notranslate">
var TodosRouter = Backbone.Router.extend({
  routes: {
    &quot;:list_id&quot;: &quot;main&quot;
  },
  main: function (list_id) {
    Session.set(&quot;list_id&quot;, list_id);
    Session.set(&quot;tag_filter&quot;, null);
  },
  setList: function (list_id) {
    this.navigate(list_id, true);
  }
});
</pre>
<p>OK, so the only thing that the &#8220;main&#8221; function does is set two Session variables. What effect does that have? Time to look at some html.</p>
<p>client/todos.html:</p>
<pre class="brush: xml; highlight: [1,8]; title: ; notranslate">
&lt;template name=&quot;todos&quot;&gt;
  {{#if any_list_selected}}
  &lt;div id=&quot;items-view&quot;&gt;
    &lt;div id=&quot;new-todo-box&quot;&gt;
      &lt;input type=&quot;text&quot; id=&quot;new-todo&quot; placeholder=&quot;New item&quot; /&gt;
    &lt;/div&gt;
    &lt;ul id=&quot;item-list&quot;&gt;
      {{#each todos}}
        {{&gt; todo_item}}
      {{/each}}
    &lt;/ul&gt;
  &lt;/div&gt;
  {{/if}}
&lt;/template&gt;
</pre>
<p>That there is a <a href="http://www.handlebarsjs.com/">Handlebars</a> template, with name=&#8221;todos&#8221;. Interestingly, it has a &#8220;#each todos&#8221;. The data for that is retrieved by a helper function called &#8220;todos&#8221; (on the Template also called &#8220;todos&#8221;), i.e. this:</p>
<pre class="brush: jscript; title: ; notranslate">
Template.todos.todos = function () {
  // Determine which todos to display in main pane,
  // selected based on list_id and tag_filter.

  var list_id = Session.get('list_id');
  if (!list_id)
    return {};

  var sel = {list_id: list_id};
  var tag_filter = Session.get('tag_filter');
  if (tag_filter)
    sel.tags = tag_filter;

  return Todos.find(sel, {sort: {timestamp: 1}});
};
</pre>
<p>This template (like all Meteor templates) <a href="http://docs.meteor.com/#reactivity">reactively</a> monitors the Session and detects that the value for Session.get(&#8216;list_id&#8217;) has changed, so it runs again and returns the todo items to be rendered. Each todo item is then rendered by another Handlebars template called todo_item , as per the {{&gt; todo_item}} in the html.</p>
<p>In summary then,</p>
<ol>
<li>Todo list link is clicked in the left pane, calls TodosRouter.setList(list_id).</li>
<li>TodosRouter.setList navigates to ~/list_id</li>
<li>Router.main sets Session[list_id] variable.</li>
<li>The template helper &#8220;todos&#8221; detects Session[list_id] has changed so it re-runs.</li>
<li>The Handlebars template named &#8220;todos&#8221; is re-rendered with the result of the &#8220;todos&#8221; template helper.</li>
</ol>
<h4>So how do we make the URLs friendly?</h4>
<p>Now that we understand how routing works in Meteor, we can take the TodosRouter shown above and change:</p>
<ol>
<li>TodosRouter.setList(list_id) to TodosRouter.setList(list_name)</li>
<li>TodosRouter.setList should navigate to ~/list_name</li>
<li>Router.main can lookup the correct list_id from the list_name and set the Session[list_id] as before.</li>
</ol>
<p>So</p>
<pre class="brush: jscript; highlight: [3,5,6,7,8,11,12]; title: ; notranslate">
var TodosRouter = Backbone.Router.extend({
  routes: {
    &quot;:list_name&quot;: &quot;main&quot;
  },
  main: function (list_name) {
    var list = Lists.findOne({name: list_name});
    if (list)
      Session.set(&quot;list_id&quot;, list._id);
    Session.set(&quot;tag_filter&quot;, null);
  },
  setList: function (list_name) {
    this.navigate(list_name, true);
  }
});
</pre>
<p>We also need to change all the code which calls setList():</p>
<pre class="brush: jscript; highlight: [3]; title: ; notranslate">
Template.lists.events = {
  'mousedown .list': function (evt) { // select list
    Router.setList(this.name);
  },
</pre>
<pre class="brush: jscript; highlight: [5]; title: ; notranslate">
Meteor.subscribe('lists', function () {
  if (!Session.get('list_id')) {
    var list = Lists.findOne({}, {sort: {name: 1}});
    if (list)
      Router.setList(list.name);
  }
});
</pre>
<pre class="brush: jscript; highlight: [5]; title: ; notranslate">
Template.lists.events[ okcancel_events('#new-list') ] =
  make_okcancel_handler({
    ok: function (text, evt) {
      var id = Lists.insert({name: text});
      Router.setList(text);
</pre>
<p>Finally, for cosmetic reasons, we should change the &#8220;lists&#8221; template so that the html that&#8217;s rendered for the todo list links has the correct href attribute &#8211; so that when the user hovers over the link they see the new friendly url.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;a class=&quot;list-name {{name_class}}&quot; href=&quot;/{{name}}&quot;&gt;
  {{name}}
&lt;/a&gt;
</pre>
<p><a href="http://mattfrear.files.wordpress.com/2012/08/screen-shot-2012-08-28-at-21-22-40.png"><img src="http://mattfrear.files.wordpress.com/2012/08/screen-shot-2012-08-28-at-21-22-40.png?w=500&#038;h=357" alt="" title="Screen Shot 2012-08-28 at 21.22.40" width="500" height="357" class="aligncenter size-full wp-image-598" /></a><br />
See the source code on <a href="https://github.com/mattfrear/meteor-todos">github</a>.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mattfrear.wordpress.com/647/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mattfrear.wordpress.com/647/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mattfrear.com&#038;blog=12300335&#038;post=647&#038;subd=mattfrear&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://mattfrear.com/2012/08/31/meteor-todos-part-1/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/5da3065d9a83a23a90c18a5e7d20b180?s=96&#38;d=http%3A%2F%2F2.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">mattfrear</media:title>
		</media:content>

		<media:content url="http://mattfrear.files.wordpress.com/2012/08/screen-shot-2012-08-23-at-21-09-48.png" medium="image">
			<media:title type="html">todos sample</media:title>
		</media:content>

		<media:content url="http://mattfrear.files.wordpress.com/2012/08/screen-shot-2012-08-28-at-21-22-40.png" medium="image">
			<media:title type="html">Screen Shot 2012-08-28 at 21.22.40</media:title>
		</media:content>
	</item>
		<item>
		<title>Meteor leaderboard sample exercise three</title>
		<link>http://mattfrear.com/2012/08/31/meteor-leaderboard-part-3/</link>
		<comments>http://mattfrear.com/2012/08/31/meteor-leaderboard-part-3/#comments</comments>
		<pubDate>Fri, 31 Aug 2012 19:37:23 +0000</pubDate>
		<dc:creator>mattfrear</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[meteorjs]]></category>

		<guid isPermaLink="false">http://mattfrear.com/?p=636</guid>
		<description><![CDATA[This is the third in a x part series about Meteor for beginners. Part One &#8211; Leaderboard: Add a button to change sort order Part Two &#8211; Leaderboard: Add a button to randomise players&#8217; scores Part Three &#8211; Leaderboard: Add and remove players from the leaderboard (this post) Exercise 3a: Remove a scientist from the <a href="http://mattfrear.com/2012/08/31/meteor-leaderboard-part-3/" class="excerpt-more-link">[&#8230;]</a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mattfrear.com&#038;blog=12300335&#038;post=636&#038;subd=mattfrear&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>This is the third in a x part series about <a href="http://meteor.com">Meteor</a> for beginners.</p>
<ul>
<li><a href="http://mattfrear.com/2012/08/29/enhancing-the-meteor-leaderboard-sample/" title="Enhancing the Meteor leaderboard sample">Part One &#8211; Leaderboard: Add a button to change sort order</a></li>
<li><a href="http://mattfrear.com/2012/08/30/meteor-leaderboard-part-2/" title="Meteor leaderboard sample exercise two">Part Two &#8211; Leaderboard: Add a button to randomise players&#8217; scores</a></li>
<li>Part Three &#8211; Leaderboard: Add and remove players from the leaderboard (this post)</li>
</ul>
<h4>Exercise 3a: Remove a scientist from the leaderboard</h4>
<p>This should be easy. First, let&#8217;s add a button.</p>
<pre class="brush: xml; highlight: [9]; title: ; notranslate">
&lt;template name=&quot;leaderboard&quot;&gt;
  
  ...

  {{#if selected_name}}
  &lt;div class=&quot;details&quot;&gt;
    &lt;div class=&quot;name&quot;&gt;{{selected_name}}&lt;/div&gt;
    &lt;input type=&quot;button&quot; class=&quot;inc&quot; value=&quot;Give 5 points&quot; /&gt;
    &lt;input type=&quot;button&quot; class=&quot;delete&quot; value=&quot;Delete&quot; /&gt;
  &lt;/div&gt;
  {{/if}}

  ...
&lt;/template&gt;
</pre>
<p>And now the event to fire when the button is clicked:</p>
<pre class="brush: jscript; highlight: [9]; title: ; notranslate">
  Template.leaderboard.events = {
    
    ...

    'click input.delete': function() {
      if (confirm('Are you sure you want to delete the player?')) {
        Players.remove(Session.get(&quot;selected_player&quot;));
      }
    }
</pre>
<p>N.B. the remove() function accepts either a selector i.e. Players.remove({_id: Session.get(&#8220;selected_player&#8221;)}), or a string (which is the _id) as its first argument.</p>
<h4>Exercise 3b: Add a new scientist to the leaderboard</h4>
<p>Let&#8217;s add a new &#8220;addPlayer&#8221; template to the html:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;template name=&quot;addPlayer&quot;&gt;
    &lt;div&gt;
        &lt;div&gt;Add a new player:&lt;/div&gt;
        &lt;span class=&quot;name&quot;&gt;Name:&lt;/span&gt;
        &lt;input type=&quot;text&quot; id=&quot;playerName&quot; /&gt;
        &lt;span class=&quot;score&quot;&gt;Score:&lt;/span&gt;
        &lt;input type=&quot;text&quot; id=&quot;playerScore&quot; /&gt;
        &lt;input type=&quot;button&quot; class=&quot;add&quot; value=&quot;Add player&quot; /&gt;
    &lt;/div&gt;
&lt;/template&gt;
</pre>
<p>And now render it after the leaderboard template:</p>
<pre class="brush: plain; highlight: [4]; title: ; notranslate">
&lt;body&gt;
  &lt;div id=&quot;outer&quot;&gt;
    {{&gt; leaderboard}}
    {{&gt; addPlayer}}
  &lt;/div&gt;
&lt;/body&gt;
</pre>
<p>And now lets add template event code which will fire when the &#8220;Add player&#8221; button is clicked:</p>
<pre class="brush: jscript; highlight: [8,9,10,11,12,13]; title: ; notranslate">

  Template.player.events = {
    'click': function () {
      Session.set(&quot;selected_player&quot;, this._id);
    }
  };

  Template.addPlayer.events = {
    'click input.add': function () {
      // todo - add validation
      Players.insert({name: playerName.value, score: Number(playerScore.value)});
    }
  };
}
</pre>
<p><a href="http://mattfrear.files.wordpress.com/2012/08/screen-shot-2012-08-31-at-08-29-31.png"><img src="http://mattfrear.files.wordpress.com/2012/08/screen-shot-2012-08-31-at-08-29-31.png?w=500&#038;h=374" alt="" title="Screen Shot 2012-08-31 at 08.29.31" width="500" height="374" class="aligncenter size-full wp-image-643" /></a></p>
<p><a href="https://github.com/mattfrear/meteor-leaderboard">Browse the code</a> on Github.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mattfrear.wordpress.com/636/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mattfrear.wordpress.com/636/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mattfrear.com&#038;blog=12300335&#038;post=636&#038;subd=mattfrear&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://mattfrear.com/2012/08/31/meteor-leaderboard-part-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/5da3065d9a83a23a90c18a5e7d20b180?s=96&#38;d=http%3A%2F%2F2.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">mattfrear</media:title>
		</media:content>

		<media:content url="http://mattfrear.files.wordpress.com/2012/08/screen-shot-2012-08-31-at-08-29-31.png" medium="image">
			<media:title type="html">Screen Shot 2012-08-31 at 08.29.31</media:title>
		</media:content>
	</item>
		<item>
		<title>Meteor leaderboard sample exercise two</title>
		<link>http://mattfrear.com/2012/08/30/meteor-leaderboard-part-2/</link>
		<comments>http://mattfrear.com/2012/08/30/meteor-leaderboard-part-2/#comments</comments>
		<pubDate>Thu, 30 Aug 2012 20:19:07 +0000</pubDate>
		<dc:creator>mattfrear</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[meteorjs]]></category>

		<guid isPermaLink="false">http://mattfrear.com/?p=617</guid>
		<description><![CDATA[This is the second in a x part series about Meteor for beginners. Part One &#8211; Leaderboard: Add a button to change sort order Part Two &#8211; Leaderboard: Add a button to randomise players&#8217; scores (this post) Exercise 2: Add a button to randomise all players scores First, let&#8217;s add the button to the bottom <a href="http://mattfrear.com/2012/08/30/meteor-leaderboard-part-2/" class="excerpt-more-link">[&#8230;]</a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mattfrear.com&#038;blog=12300335&#038;post=617&#038;subd=mattfrear&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>This is the second in a x part series about <a href="http://meteor.com">Meteor</a> for beginners.</p>
<ul>
<li><a href="http://mattfrear.com/2012/08/29/enhancing-the-meteor-leaderboard-sample/" title="Enhancing the Meteor leaderboard sample">Part One &#8211; Leaderboard: Add a button to change sort order</a></li>
<li>Part Two &#8211; Leaderboard: Add a button to randomise players&#8217; scores (this post)</li>
</ul>
<h4>Exercise 2: Add a button to randomise all players scores</h4>
<p>First, let&#8217;s add the button to the bottom of the leaderboard template.<br />
leaderboard.html:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;template name=&quot;leaderboard&quot;&gt;

  ...

  &lt;div&gt;
      &lt;input type=&quot;button&quot; class=&quot;randomise&quot; value=&quot;Randomise&quot; /&gt;
  &lt;/div&gt;
&lt;/template&gt;
</pre>
<p>The meteor sample already has a formula to generate a random score which is called on startup if the database is empty. So let&#8217;s refactor that into a function so that we can reuse it.</p>
<pre class="brush: jscript; highlight: [2,3,4,17]; title: ; notranslate">
//
var randomScore = function() {
  return Math.floor(Math.random()*10)*5;
}

// On server startup, create some players if the database is empty.
if (Meteor.is_server) {
  Meteor.startup(function () {
    if (Players.find().count() === 0) {
      var names = [&quot;Ada Lovelace&quot;,
                   &quot;Grace Hopper&quot;,
                   &quot;Marie Curie&quot;,
                   &quot;Carl Friedrich Gauss&quot;,
                   &quot;Nikola Tesla&quot;,
                   &quot;Claude Shannon&quot;];
      for (var i = 0; i &lt; names.length; i++)
        Players.insert({name: names[i], score: randomScore()});
    }
  });
}
</pre>
<p>Now all we need to do is add an event to handle the button click which will do the work:</p>
<pre class="brush: jscript; title: ; notranslate">
  Template.leaderboard.events = {

    ...

    'click input.randomise': function() {
      Players.find({}).forEach(function(player) {
        Players.update(player, {$set: {score: randomScore()}});
      });
    }
  };
</pre>
<p><a href="http://mattfrear.files.wordpress.com/2012/08/screen-shot-2012-08-30-at-21-11-13.png"><img src="http://mattfrear.files.wordpress.com/2012/08/screen-shot-2012-08-30-at-21-11-13.png?w=500&#038;h=311" alt="" title="Screen Shot 2012-08-30 at 21.11.13" width="500" height="311" class="aligncenter size-full wp-image-620" /></a></p>
<p>Browse the code at <a href="https://github.com/mattfrear/meteor-leaderboard/tree/0bcd085e51eab24346e1013ffc18d37e9e2b2c3f">github</a>.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mattfrear.wordpress.com/617/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mattfrear.wordpress.com/617/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mattfrear.com&#038;blog=12300335&#038;post=617&#038;subd=mattfrear&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://mattfrear.com/2012/08/30/meteor-leaderboard-part-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/5da3065d9a83a23a90c18a5e7d20b180?s=96&#38;d=http%3A%2F%2F2.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">mattfrear</media:title>
		</media:content>

		<media:content url="http://mattfrear.files.wordpress.com/2012/08/screen-shot-2012-08-30-at-21-11-13.png" medium="image">
			<media:title type="html">Screen Shot 2012-08-30 at 21.11.13</media:title>
		</media:content>
	</item>
		<item>
		<title>Meteor leaderboard sample exercise one</title>
		<link>http://mattfrear.com/2012/08/29/enhancing-the-meteor-leaderboard-sample/</link>
		<comments>http://mattfrear.com/2012/08/29/enhancing-the-meteor-leaderboard-sample/#comments</comments>
		<pubDate>Wed, 29 Aug 2012 21:53:42 +0000</pubDate>
		<dc:creator>mattfrear</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[meteorjs]]></category>

		<guid isPermaLink="false">http://mattfrear.com/?p=600</guid>
		<description><![CDATA[This is the first in a x part series about Meteor for beginners. Part One &#8211; Leaderboard: Add a button to change sort order (this post) Part Two &#8211; Leaderboard: Add a button to randomise players&#8217; scores Introduction I’ve been trying to get up to speed with Meteor lately. Since I don’t have any experience <a href="http://mattfrear.com/2012/08/29/enhancing-the-meteor-leaderboard-sample/" class="excerpt-more-link">[&#8230;]</a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mattfrear.com&#038;blog=12300335&#038;post=600&#038;subd=mattfrear&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>This is the first in a x part series about <a href="http://meteor.com">Meteor</a> for beginners.</p>
<ul>
<li>Part One &#8211; Leaderboard: Add a button to change sort order (this post)</li>
<li><a href="http://mattfrear.com/2012/08/30/meteor-leaderboard-part-2/" title="Meteor leaderboard sample exercise two">Part Two &#8211; Leaderboard: Add a button to randomise players&#8217; scores</a></li>
</ul>
<h4>Introduction</h4>
<p>I’ve been trying to get up to speed with <a href="http://meteor.com">Meteor</a> lately. Since I don’t have any experience with nodejs it’s been a challenge. However, Meteor&#8217;s documentation is very good so I&#8217;m getting there.</p>
<p>I started by looking at the <a href="http://meteor.com/examples/leaderboard">leaderboard sample</a>. </p>
<p><a href="http://mattfrear.files.wordpress.com/2012/08/screen-shot-2012-08-29-at-21-09-12.png"><img src="http://mattfrear.files.wordpress.com/2012/08/screen-shot-2012-08-29-at-21-09-12.png?w=500&#038;h=355" alt="" title="Screen Shot 2012-08-29 at 21.09.12" width="500" height="355" class="aligncenter size-full wp-image-602" /></a></p>
<p>The tutorial suggests making 3 enhancements to the leaderboard sample as an exercise. Here&#8217;s my attempt at the first one.</p>
<h4>Exercise 1: Add a button to toggle between sorting by score and by name</h4>
<p>First let&#8217;s add a button to the bottom of the &#8220;leaderboard&#8221; template</p>
<pre class="brush: xml; highlight: [19,20,21]; title: ; notranslate">
&lt;template name=&quot;leaderboard&quot;&gt;
  &lt;div class=&quot;leaderboard&quot;&gt;
    {{#each players}}
      {{&gt; player}}
    {{/each}}
  &lt;/div&gt;

  {{#if selected_name}}
  &lt;div class=&quot;details&quot;&gt;
    &lt;div class=&quot;name&quot;&gt;{{selected_name}}&lt;/div&gt;
    &lt;input type=&quot;button&quot; class=&quot;inc&quot; value=&quot;Give 5 points&quot; /&gt;
  &lt;/div&gt;
  {{/if}}

  {{#unless selected_name}}
  &lt;div class=&quot;none&quot;&gt;Click a player to select&lt;/div&gt;
  {{/unless}}

  &lt;div&gt;
      &lt;input type=&quot;button&quot; class=&quot;sort&quot; value=&quot;Change sorting&quot; /&gt;
  &lt;/div&gt;
&lt;/template&gt;
</pre>
<p>That there is a <a href="http://handlebarsjs.com/">Handlebars</a> template with name=&#8221;leaderboard&#8221;. Notice that it has a {{#each players}}. We&#8217;ll get to that in a minute.<br />
Now let&#8217;s add javascript to toggle the sort order. We&#8217;ll need to save the sort order in the Session, so let&#8217;s set its default value at startup.</p>
<pre class="brush: jscript; highlight: [2,3]; title: ; notranslate">
if (Meteor.is_client) {
  Meteor.startup(function() {
    Session.set(&quot;sort_order&quot;, {score: -1, name: 1});
  });
</pre>
<p>{score: -1, name: 1} means sort by score (descending) first, then name.<br />
The {{#each players}} I mentioned earlier calls the Template.leaderboard.players() function, so let&#8217;s change that to use the sort order stored in the Session.</p>
<pre class="brush: jscript; highlight: [2]; title: ; notranslate">
  Template.leaderboard.players = function () {
    return Players.find({}, {sort: Session.get(&quot;sort_order&quot;)});
  };
</pre>
<p>Now all we need to do is change the sort order stored in the Session whenever the button is clicked. So let&#8217;s add an event to the Template.leaderboard.events object which is fired when the &#8220;Change sorting&#8221; button is clicked.</p>
<pre class="brush: jscript; highlight: [5,6,7,8,9,10,11,12,13,14]; title: ; wrap-lines: false; notranslate">
  Template.leaderboard.events = {
    'click input.inc': function () {
      Players.update(Session.get(&quot;selected_player&quot;), {$inc: {score: 5}});
    },
    'click input.sort': function() {
      var sortOrder = Session.get(&quot;sort_order&quot;);

      if (Object.keys(sortOrder)[0] == &quot;score&quot;) { // sort by score desc
        Session.set(&quot;sort_order&quot;, { name: 1, score: -1 }); // sort by name
      }
      else {
        Session.set(&quot;sort_order&quot;, { score: -1, name: 1 }); // sort by score desc
      }
    }
  };
</pre>
<p><a href="http://mattfrear.files.wordpress.com/2012/08/screen-shot-2012-08-29-at-22-20-34.png"><img src="http://mattfrear.files.wordpress.com/2012/08/screen-shot-2012-08-29-at-22-20-34.png?w=500&#038;h=375" alt="" title="Screen Shot 2012-08-29 at 22.20.34" width="500" height="375" class="aligncenter size-full wp-image-608" /></a></p>
<p>See the code on <a href="https://github.com/mattfrear/meteor-leaderboard/tree/fe0b84bc20b95ff1edab92a5c9ea22ac97d500e6">github</a>.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mattfrear.wordpress.com/600/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mattfrear.wordpress.com/600/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mattfrear.com&#038;blog=12300335&#038;post=600&#038;subd=mattfrear&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://mattfrear.com/2012/08/29/enhancing-the-meteor-leaderboard-sample/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/5da3065d9a83a23a90c18a5e7d20b180?s=96&#38;d=http%3A%2F%2F2.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">mattfrear</media:title>
		</media:content>

		<media:content url="http://mattfrear.files.wordpress.com/2012/08/screen-shot-2012-08-29-at-21-09-12.png" medium="image">
			<media:title type="html">Screen Shot 2012-08-29 at 21.09.12</media:title>
		</media:content>

		<media:content url="http://mattfrear.files.wordpress.com/2012/08/screen-shot-2012-08-29-at-22-20-34.png" medium="image">
			<media:title type="html">Screen Shot 2012-08-29 at 22.20.34</media:title>
		</media:content>
	</item>
	</channel>
</rss>
