<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-8417810603086728638</id><updated>2026-03-10T00:11:09.906+05:30</updated><category term="ColdFusion"/><category term="JavaScript/jQuery"/><category term="HTML5"/><category term="Design Patterns"/><category term="REST"/><category term="CFBuilder"/><category term="BackboneJS"/><category term="Announcements"/><category term="Ajax"/><category term="Kiss My App"/><category term="AngularJS"/><category term="CSS"/><category term="RequireJS"/><category term="Kendo UI"/><category term="Misc"/><category term="Books"/><category term="React"/><category term="Redux"/><category term="Hugo"/><category term="Static Site Generator"/><category term="UnderscoreJS"/><category term="ES6"/><category term="Server Monitor"/><category term="Angular"/><category term="Flex"/><category term="GraphQL"/><category term="IMAP"/><category term="Material Design"/><category term="MobX"/><category term="PageJS"/><category term="Photoshop"/><category term="React-Native"/><category term="React-Router"/><category term="WebRTC"/><title type='text'>Sagar Ganatra&#39;s Blog</title><subtitle type='html'>&lt;br&gt;&#xa;&lt;b&gt;&#xa;A blog on HTML5, JavaScript, ColdFusion and other web technologies.&#xa;&lt;/b&gt;</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://www.sagarganatra.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8417810603086728638/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://www.sagarganatra.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/8417810603086728638/posts/default?start-index=26&amp;max-results=25&amp;redirect=false'/><author><name>Sagar Ganatra</name><uri>http://www.blogger.com/profile/15129859862786257527</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhoO56BqdUmSACmPZKwemvyzRtEm1xJVsPVudy1_Tc2U4vafHustJn0_oFtUkKVcz1oGe_p2woZN3j04yI3Sf_xsTrrlcdno6mLnN1Qz380TamkT3P919jIRjh1acuRGA/s220/Mypic.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>117</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8417810603086728638.post-4874249076181249555</id><published>2019-06-24T19:00:00.000+05:30</published><updated>2019-06-25T09:41:48.379+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="Angular"/><title type='text'>How to use the APP_INITIALIZER token to hook into the Angular bootstrap process</title><content type='html'>I&#39;ve been building applications using Angular as a framework of choice for more than a year and this post is not about another React vs Angular or the quirks of each framework. Honestly, I like Angular and every day I discover something new which makes development easier and makes me look like a guy who built something very complex in a matter of hours which would&#39;ve taken a long time to put the correct architecture in place if I had chosen a different framework. The first thing that I learned in Angular is the use of the APP_INITIALIZER token.&lt;br /&gt;
&lt;div&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
The documentation at &lt;a href=&quot;https://angular.io/api/core/APP_INITIALIZER&quot;&gt;angular.io&lt;/a&gt;&amp;nbsp;says - &#39;&lt;i&gt;A function that will be executed when an application is initialized&lt;/i&gt;&#39;. It does not spew any details on how to use this function and where to include it.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Sidenote: I must say the documentation could&#39;ve been better with examples and a detailed explanation for the given feature could&#39;ve helped. But hey, I can&#39;t hold this against you Angular :)&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
The APP_INITIALIZER token is used when you want to get the application&#39;s configuration details from an API and keep it ready before the application renders the page. For example, you would want to load the necessary language files before rendering any of the templates or you would want to resolve a remote API which provides information on the environment that the application is being run on. It&#39;s similar to how the &#39;&lt;i&gt;resolve&lt;/i&gt;&#39; attribute in the router&#39;s configuration is used to get data from the remote API and feed it into the route&#39;s &#39;&lt;i&gt;data&lt;/i&gt;&#39; source. In this case, the remote API is resolved first and then the application continues with the bootstrap process.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Here&#39;s an example of how the APP_INITIALIZER token is included in the application. The main module of the application - &lt;i&gt;app.module.ts&lt;/i&gt; includes the APP_INITIALER in its &#39;&lt;i&gt;providers&lt;/i&gt;&#39; section:&lt;/div&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/sagar-ganatra/0cdd1c15ceb8313f82b1255c73e561c2.js&quot;&gt;&lt;/script&gt;

&lt;br /&gt;
&lt;div&gt;
Notice that the &#39;&lt;i&gt;providers&lt;/i&gt;&#39; section includes APP_INITIALIZER with the attribute &#39;&lt;i&gt;useFactory&lt;/i&gt;&#39; referring to factory function &#39;&lt;i&gt;initApp&#39;&lt;/i&gt;. Here&#39;s the definition of the &lt;i&gt;initApp&lt;/i&gt; factory function:&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;script src=&quot;https://gist.github.com/sagar-ganatra/ea66c1159bd32d361e21afd82d85f056.js&quot;&gt;&lt;/script&gt;

&lt;br /&gt;
&lt;div&gt;
The factory function is expected to return a Promise and only after the promise has resolved the application bootstrap process would continue. In the above code snippet, a delay of three seconds is added before the promise resolves. This blocks the bootstrapping of the application for three seconds. Similarly, you could use an HTTP service (from &lt;i&gt;HttpClient&lt;/i&gt;) to request data from an API and only after the request is complete that the application bootstrap process would continue. However, to use Angular&#39;s &lt;i&gt;HttpClient&lt;/i&gt; in the &lt;i&gt;initApp&lt;/i&gt; factory function, include &lt;i&gt;HttpClientModule&lt;/i&gt; in the imports section and also specify &lt;i&gt;HttpClient&lt;/i&gt; as a dependency (&lt;i&gt;deps&lt;/i&gt;) to the APP_INITIALIZER provider:&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;imports: [&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&amp;nbsp; BrowserModule,&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;b&gt;HttpClientModule&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;],&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;providers: [&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;{&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&amp;nbsp; provide: APP_INTIALIZER,&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&amp;nbsp; useFactory: initApp,&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&amp;nbsp; multi: true,&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&amp;nbsp; &lt;b&gt;deps: [HttpClient]&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;]&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;...&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Next, update the &lt;i&gt;initiApp&lt;/i&gt; factory function and use the instance of &lt;i&gt;HttpClient&lt;/i&gt; to request data from a remote service:&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;script src=&quot;https://gist.github.com/sagar-ganatra/710a21d0fc196694691eaa124405cf24.js&quot;&gt;&lt;/script&gt;

&lt;br /&gt;
&lt;div&gt;
The &#39;&lt;i&gt;get&lt;/i&gt;&#39; method on the &lt;i&gt;HttpClient&lt;/i&gt; instance returns a &lt;i&gt;Subscription&lt;/i&gt; (see RxJS) and the &lt;i&gt;toPromise&lt;/i&gt;&amp;nbsp;method is used to convert the Subscription to a Promise. If the factory method returns the subscription, the application would continue to bootstrap as if there was no APP_INITIALIZER token added to the module.&lt;br /&gt;
&lt;br /&gt;
The source code for the above example is available at -&amp;nbsp;&lt;a href=&quot;https://github.com/sagar-ganatra/angular-app-initializer&quot;&gt;https://github.com/sagar-ganatra/angular-app-initializer&lt;/a&gt;&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://www.sagarganatra.com/feeds/4874249076181249555/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.sagarganatra.com/2019/06/appinitializer-token-angular-bootstrap.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8417810603086728638/posts/default/4874249076181249555'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8417810603086728638/posts/default/4874249076181249555'/><link rel='alternate' type='text/html' href='http://www.sagarganatra.com/2019/06/appinitializer-token-angular-bootstrap.html' title='How to use the APP_INITIALIZER token to hook into the Angular bootstrap process'/><author><name>Sagar Ganatra</name><uri>http://www.blogger.com/profile/15129859862786257527</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhoO56BqdUmSACmPZKwemvyzRtEm1xJVsPVudy1_Tc2U4vafHustJn0_oFtUkKVcz1oGe_p2woZN3j04yI3Sf_xsTrrlcdno6mLnN1Qz380TamkT3P919jIRjh1acuRGA/s220/Mypic.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8417810603086728638.post-5208588043014780769</id><published>2018-10-01T17:55:00.000+05:30</published><updated>2018-10-01T17:55:12.349+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="Announcements"/><category scheme="http://www.blogger.com/atom/ns#" term="Books"/><category scheme="http://www.blogger.com/atom/ns#" term="React"/><category scheme="http://www.blogger.com/atom/ns#" term="React-Native"/><category scheme="http://www.blogger.com/atom/ns#" term="React-Router"/><category scheme="http://www.blogger.com/atom/ns#" term="Redux"/><title type='text'>My third book titled — ‘React-Router Quick Start Guide’ published!</title><content type='html'>The title says it all. This is my third book with Packt Publishing and I wrote a book after four long years. In the last few months, I’ve spent my weekends writing this book and it was an arduous undertaking. Here’s the cover image:&lt;br /&gt;
&lt;br /&gt;
&lt;img height=&quot;640&quot; src=&quot;https://cdn-images-1.medium.com/max/1600/1*rnK9xAsp7xeHcKZiEvPUGA.png&quot; width=&quot;513&quot; /&gt;&lt;br /&gt;
&lt;br /&gt;
I have used React and React-Router in many projects and during the course of writing this book I’ve learned a great deal about these frameworks/libraries. This book is all about the ‘React-Router’ library and how you can use it any React application (web or native).&lt;br /&gt;
&lt;br /&gt;
The book covers the following topics:&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Chapter 1, Introduction to React Router 4 and Creating Your First Route&lt;/b&gt;, is an introduction to the component-based architecture in React and how you can get started with creating routes using the Route component from React Router.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Chapter 2, Configuring Routes, Using Various Options in the Route Component&lt;/b&gt;, discusses various Route component props that can be used to match the requested URL location and how these matches can be used to render a component. Also, the chapter explains how routes can be added dynamically as the user traverses through the application.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Chapter 3, Using Link and NavLink Components to Navigate to a Route&lt;/b&gt;, talks about how to use the Link and NavLink components in React Router to allow you to navigate to routes defined in the application. This chapter also explains&amp;nbsp;the higher-order component withRouter and how to prevent accidental transition using the Prompt component.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Chapter 4, Using Redirect and Switch Components&lt;/b&gt;, goes into how to use the Redirect component to redirect the user to a different route and the Switch component to match one route and redirect the user to a 404 page not found page if the requested location is not found.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Chapter 5, Understanding the Core Router and Configuring BrowserRouter and HashRouter Components&lt;/b&gt;, is an in-depth explanation of how the core router interface is used to update the sections of the screen and the browser’s history. The chapter also explains two router interfaces used in a web application: BrowserRouter and HashRouter.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Chapter 6, Using StaticRouter in a Server-Side-Rendered React Application&lt;/b&gt;, explores how to use the StaticRouter component to provide routing features on a server-side-rendered application. The chapter also explains how StaticRouter and BrowserRouter can be used to build an isomorphic web application.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Chapter 7, Using NativeRouter in a React-Native Application&lt;/b&gt;, details how to provide routing in a native mobile application developed with React Native using the NativeRouter component. The chapter also explains how you can integrate with the device’s back button using the BackButton component and provide deep linking support using the DeepLinking component.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Chapter 8, Redux Bindings with Connected-React-Router&lt;/b&gt;, examines how to use the connected-react-router library, which provides Redux bindings for React Router; the chapter explains how to read routing information from the router state in the Redux store and how to navigate by dispatching actions to the store.&lt;br /&gt;
&lt;br /&gt;
You can buy a copy of this book here — &lt;a href=&quot;https://www.packtpub.com/web-development/react-router-quick-start-guide&quot;&gt;https://www.packtpub.com/web-development/react-router-quick-start-guide&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.sagarganatra.com/feeds/5208588043014780769/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.sagarganatra.com/2018/10/my-third-book-react-router-quick-start-guide.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8417810603086728638/posts/default/5208588043014780769'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8417810603086728638/posts/default/5208588043014780769'/><link rel='alternate' type='text/html' href='http://www.sagarganatra.com/2018/10/my-third-book-react-router-quick-start-guide.html' title='My third book titled — ‘React-Router Quick Start Guide’ published!'/><author><name>Sagar Ganatra</name><uri>http://www.blogger.com/profile/15129859862786257527</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhoO56BqdUmSACmPZKwemvyzRtEm1xJVsPVudy1_Tc2U4vafHustJn0_oFtUkKVcz1oGe_p2woZN3j04yI3Sf_xsTrrlcdno6mLnN1Qz380TamkT3P919jIRjh1acuRGA/s220/Mypic.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8417810603086728638.post-4203407753203089467</id><published>2018-01-26T19:43:00.000+05:30</published><updated>2018-01-26T19:44:05.700+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript/jQuery"/><category scheme="http://www.blogger.com/atom/ns#" term="MobX"/><category scheme="http://www.blogger.com/atom/ns#" term="React"/><category scheme="http://www.blogger.com/atom/ns#" term="Redux"/><title type='text'>Using MobX to manage application state in a React application</title><content type='html'>I have been writing applications using React and Redux for quite some time now and thought of trying other state management solutions out there. It&#39;s not that I have faced any issues with Redux; however, I wanted to explore other approaches to state management. I recently came across &lt;a href=&quot;https://mobx.js.org/index.html&quot; target=&quot;_blank&quot;&gt;MobX&lt;/a&gt;&amp;nbsp;and thought of giving it a try. The library uses the premise of&amp;nbsp; `Observables` to tie the application state with the view layer (React). It&#39;s also an implementation of the Flux pattern wherein it uses multiple stores to save the application state; each store referring to a particular entity. Redux, on the other hand, uses a single store with top-level state variables referring to various entities.&lt;br /&gt;
&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;b&gt;On Redux vs MobX:&lt;/b&gt;&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;div&gt;
Redux uses functional programming approach to update the state:&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt; &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;(state, action) =&amp;gt; newState;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
It accepts two arguments - current state and an action and returns a new state. In Redux, the state is immutable i.e. to update the view, the state reference in the Redux store itself should be updated. For example, to add a new item to the cart you would:&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;(state, action) =&amp;gt; {&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&amp;nbsp; &amp;nbsp;return [...state.items, action.item];&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;}&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
instead of&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;return state.items.push(item);&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
MobX, on the other hand, uses an object-oriented approach to state management. A store in MobX is nothing but an instance of a class which has observable properties:&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;class Cart {&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; @observable itemsInBag = [];&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; @observable itemsInWishlist = [];&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;}&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
The decorator &lt;span style=&quot;font-family: inherit;&quot;&gt;`@observable`&lt;/span&gt;&amp;nbsp;(defined in&amp;nbsp;&lt;span style=&quot;font-family: inherit;&quot;&gt;`mobx`&lt;/span&gt;&amp;nbsp;library) is used to declare a property in the class as an observable. It&#39;s initialized to an empty array and any changes to this array will let the observers know. In this case, the observer is our view component in React:&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/sagar-ganatra/8c9c5e96fc97883686c9a007c808a0b8.js&quot;&gt;&lt;/script&gt;
&lt;/div&gt;
&lt;/div&gt;
The above React component class has the `@observer` decorator, declaring that view component will get updated with the changes in the &lt;i&gt;props&lt;/i&gt;. Notice `&lt;i&gt;this.props.cart&lt;/i&gt;` in the component&#39;s &lt;i&gt;render&lt;/i&gt; function, the observable property declared in the Cart class - &lt;i&gt;itemsInBag&lt;/i&gt; is being observed by this React component. Any additions/deletions/updates in the observable property will rerender the observer component.&lt;br /&gt;
&lt;br /&gt;
Here the view component gets an instance of the cart object as a &lt;i&gt;prop&lt;/i&gt; from the parent container:&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;const cart = new Cart()&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;return (&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&amp;nbsp; &amp;lt;ShoppingCart cart={cart} /&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
The view component also has `&lt;i&gt;this.props.cart.bagCount`&lt;/i&gt; instead of `&lt;i&gt;this.props.cart.itemInBag.length`&lt;/i&gt;; this is on purpose. MobX provides decorators that can derive values from the state. In this case, the &lt;i&gt;bagCount&lt;/i&gt; property is declared as a `@computed` property:&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;class Cart {&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; @observable itemsInBag = [];&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; @observable itemsInWishlist = [];&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;b&gt;@computed get bagCount() {&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&lt;b&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return this.itesmsInBag.reduce((count, bagItem) =&amp;gt; {&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&lt;b&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return count&amp;nbsp;+ bagItem.count;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&lt;b&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}, 0);&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&lt;b&gt;&amp;nbsp; &amp;nbsp; }&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;}&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
The computed getter (get bagCount) function returns the number of items in the cart; it&#39;s executed every time the observable properties in the class are updated. This is very handy because the computation logic is present in the Cart class instead of it being in the View component. It means consistency in the model layer and the code remains DRY.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;On setting up the environment for using ES7 decorators&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
I generally use `create-react-app` to quickly scaffold out the front-end and then modify it to add other libraries. However, it reported errors when I started to use the decorators (observable, observer and computed). Later I discovered that ES7 decorators are still at the proposal stage and are not part of the language yet and thus it&#39;s not supported in `create-react-app`. I had to use `yarn eject` to get all the configuration in my local setup and then add babel plugins to get the decorators working:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;yarn add --dev babel-cli babel-preset-env&amp;nbsp; babel-plugin-transform-decorators-legacy&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
and then added&amp;nbsp;&lt;i class=&quot;&quot;&gt;.babelrc&lt;/i&gt; file to the project&#39;s root directory:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;{&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&amp;nbsp; &quot;presets&quot;: [&quot;env&quot;, &quot;react&quot;, &quot;stage-1&quot;],&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&amp;nbsp; &quot;plugins&quot;: [&quot;transform-decorators-legacy&quot;]&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;}&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
This should not report any errors when you start the app (using yarn start). Also, there&#39;s an option to use the function `&lt;i&gt;extendObservable`&lt;/i&gt; to create an observable instead of using ES7 decorators:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;extendObservable(this, {&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&amp;nbsp; itemsInBag: [],&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&amp;nbsp; get bagCount() {&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; return this.itemsInBag.length;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&amp;nbsp; }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;})&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
This is very much ES5 syntax; however, I really liked the ES7 decorators&#39; syntax and I hope it gets accepted in the language.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;Demo App&lt;/b&gt; -&amp;nbsp;&lt;a href=&quot;https://sagar-ganatra.github.io/react-mobx-shopping-cart/&quot;&gt;https://sagar-ganatra.github.io/react-mobx-shopping-cart/&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;GitHub repo&lt;/b&gt; -&amp;nbsp;&lt;a href=&quot;https://github.com/sagar-ganatra/react-mobx-shopping-cart/&quot;&gt;https://github.com/sagar-ganatra/react-mobx-shopping-cart/&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://www.sagarganatra.com/feeds/4203407753203089467/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.sagarganatra.com/2018/01/using-mobx-to-manage-application-state-in-react-application.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8417810603086728638/posts/default/4203407753203089467'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8417810603086728638/posts/default/4203407753203089467'/><link rel='alternate' type='text/html' href='http://www.sagarganatra.com/2018/01/using-mobx-to-manage-application-state-in-react-application.html' title='Using MobX to manage application state in a React application'/><author><name>Sagar Ganatra</name><uri>http://www.blogger.com/profile/15129859862786257527</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhoO56BqdUmSACmPZKwemvyzRtEm1xJVsPVudy1_Tc2U4vafHustJn0_oFtUkKVcz1oGe_p2woZN3j04yI3Sf_xsTrrlcdno6mLnN1Qz380TamkT3P919jIRjh1acuRGA/s220/Mypic.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8417810603086728638.post-2264780591062321217</id><published>2018-01-23T16:47:00.001+05:30</published><updated>2018-01-23T16:47:45.519+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="GraphQL"/><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript/jQuery"/><category scheme="http://www.blogger.com/atom/ns#" term="React"/><category scheme="http://www.blogger.com/atom/ns#" term="Redux"/><title type='text'>On GraphQL and building an application using React Apollo</title><content type='html'>&lt;span style=&quot;font-family: inherit;&quot;&gt;When I visualize building an application, I would think of using React and Redux on the front-end which talks to a set of RESTful services built with Node and Hapi (or Express). However, over a period of time, I&#39;ve realized that this approach does not scale well when you add new features to the front-end. For example, consider a page that displays user information along with courses that a user has enrolled in. At a later point, you decide to add a section that displays popular book titles that one can view and purchase. If every entity is considered as a microservice then to get data from three different microservices would require three &lt;i&gt;http&lt;/i&gt;&amp;nbsp;requests to be sent by the front-end app. The performance of the app would degrade with the increase in the number of &lt;i&gt;http&lt;/i&gt; requests.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt; &lt;span style=&quot;font-family: inherit;&quot;&gt;I read about GraphQL and knew that it is an ideal way of building an app and I need not look forward to anything else. The GraphQL layer can be viewed as a facade which sits on top of your RESTful services or a layer which can be used to talk&amp;nbsp;&lt;/span&gt;directly&amp;nbsp;&lt;span style=&quot;font-family: inherit;&quot;&gt;to the persistent layer. This layer provides an interface which allows its clients (front-end apps) to query the required fields from various entities in one single &lt;/span&gt;&lt;i class=&quot;&quot; style=&quot;font-family: inherit;&quot;&gt;http&lt;/i&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt; request.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;/span&gt;

&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;b&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;GraphQL - On the Server&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt; &lt;span style=&quot;font-family: inherit;&quot;&gt;On the server side, GraphQL provides a schema language using which you can construct the domain model. In GraphQL terms, these are `types`, a `type` is used to represent an entity such as User, Course, Book etc. It looks something like this:&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt; &lt;span style=&quot;font-family: inherit;&quot;&gt;type CourseType {&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&amp;nbsp; &amp;nbsp; id: ID!&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&amp;nbsp; &amp;nbsp; name: String&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&amp;nbsp; &amp;nbsp; level: Int&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&amp;nbsp; &amp;nbsp; description: String&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;}&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;Here, each field in &lt;i&gt;CourseType&lt;/i&gt;&amp;nbsp;entity has a type indicating the value that it can hold (String, Float, Character, Int etc). Apart from the Scalar types, a field could also be used to declare the relationship between two types. For example, a StudentType can have a field `courses` to declare the courses that he/she has enrolled in:&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt; &lt;span style=&quot;font-family: inherit;&quot;&gt;type StudentType {&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;id: ID!&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;firstName: String&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;lastName: String&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;courses: [CourseType]!&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;}&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt; &lt;span style=&quot;font-family: inherit;&quot;&gt;Here the field `courses` is of type `[CourseType]!`. The array notation is used to indicate that a Student record can have a collection of courses i.e. a student can enrol in multiple courses(1-to-many relationship). The bang (!) is used to indicate that it&#39;s a required field.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt; &lt;span style=&quot;font-family: inherit;&quot;&gt;Apart from defining types, one is required to specify what can be retrieved using a `Query` and what can be updated using `Mutation`.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt; &lt;span style=&quot;font-family: inherit;&quot;&gt;type Query {&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&amp;nbsp; &amp;nbsp; allCourses: [CourseType]&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&amp;nbsp; &amp;nbsp; allStudents: [StudentType]&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;}&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt; &lt;span style=&quot;font-family: inherit;&quot;&gt;type Mutation {&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&amp;nbsp; &amp;nbsp; createCourse(name: String, level: Int, description: String): CourseType&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&amp;nbsp; &amp;nbsp; createStudent(firstName: String, lastName: String, courses: [CourseType]!): StudentType&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&amp;nbsp; &amp;nbsp; updateCourse(id: ID!, name: String, level: Int, description: String): CourseType&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&amp;nbsp; &amp;nbsp; .&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&amp;nbsp; &amp;nbsp; .&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&amp;nbsp; &amp;nbsp; .&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;}&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt; &lt;span style=&quot;font-family: inherit;&quot;&gt;Here types `Query` and `Mutation` are special types. They&#39;re not used to define an entity, rather they&#39;re used to specify the operations that you can perform on these entities. For example, `allCourses` in `Query` is used to declare that the client can use this to retrieve a list of courses (returns [CourseType]). A Mutation type, on the other hand, is used to indicate the operations that you can perform to update these entities. In the above example, createCourse, createStudent etc are the operations that you can perform to add or update records.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;All the above types put together come to form the type definition for your schema and it gives a high-level overview of the domain model and the operations that you could perform on various entities. However, the business logic for how the data would be retrieved or updated is not present. To accomplish this, one is required to write resolvers. A resolver provides the implementation that maps to the operations declared in the schema. A sample resolver for the above example looks like this:&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt; &lt;span style=&quot;font-family: inherit;&quot;&gt;const resolvers = {&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&amp;nbsp; &amp;nbsp; Query: {&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; allCourses: () =&amp;gt; {&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return COURSES;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&amp;nbsp; &amp;nbsp; },&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&amp;nbsp; &amp;nbsp; Mutation: {&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; createCourse: (_, { input }) =&amp;gt; {&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; let { id, name, description, level } = input;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; COURSES.push({&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; id,&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; name,&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; description,&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; level&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; });&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return input;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&amp;nbsp; &amp;nbsp; }&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;};&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt; &lt;span style=&quot;font-family: inherit;&quot;&gt;The resolvers object contains two properties Query and Mutation; under these, you would define the various operations that can be performed on the entities declared in the schema. Note, that the name of the operations would map to the ones specified in the schema (here allCourses in type Query and createCourse in type Mutation). The type definitions are independent of the language or the platform that you choose. However, the resolvers are written in the language of your choice; in this case JavaScript.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt; &lt;span style=&quot;font-family: inherit;&quot;&gt;The type definitions and resolvers come together to define the executable schema which can then be used to define middleware in a Node&amp;nbsp;+ Express environment:&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt; &lt;span style=&quot;font-family: inherit;&quot;&gt;const schema = makeExecutableSchema({ typeDefs, resolvers});&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt; &lt;/span&gt; &lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;app.use(&#39;/graphql&#39;,&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;bodyParser.json(),&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;graphqlExpress({&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; schema&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }));&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt; I&#39;ve used `graphql-tools` and `apollo-graphql-express` modules to create the schema and the middleware which would accept incoming requests.&lt;br /&gt;
&lt;br /&gt;
To test the server setup, you could make use of the GraphiQL interface which allows you to inspect the operations declared in the schema, add this:&lt;br /&gt;
&lt;br /&gt;
app.use(&#39;/graphiql&#39;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; graphiqlExpress({&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; endpointURL: &#39;/graphql&#39;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }));&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;The graphiql interface provides us with a way to test the operations declared in `Query` and `Mutation` of our schema:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiwrm62c1RSqGXNTaF6Rv2iN2omMY171Jw3GUADEho-pcyVkYGegSNiQ8NjIyClw8BdXxL99CzgFe15IAqqmGRUhFlND0mVDxt6grPe-asgoKR_olyfPdPurJe09CmeBZUW8s0NJBjMD1ES/s1600/graphiql-interface.tiff&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;932&quot; data-original-width=&quot;1600&quot; height=&quot;372&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiwrm62c1RSqGXNTaF6Rv2iN2omMY171Jw3GUADEho-pcyVkYGegSNiQ8NjIyClw8BdXxL99CzgFe15IAqqmGRUhFlND0mVDxt6grPe-asgoKR_olyfPdPurJe09CmeBZUW8s0NJBjMD1ES/s640/graphiql-interface.tiff&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
Here, the object notation on the left side allows me to specify the query method and the fields that I need from the `courses` model (id and name). The response from the server (on the right side) includes only the data that I have requested. Although the resolver itself returns the entire object, GraphQL ensures that only the requested data is returned in the response; thus reducing the size of the payload.&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;b&gt;GraphQL - On the client side&lt;/b&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
On the client side, the first step would be to connect to the GraphQL server and wrap the root component with the Provider (ApolloProvider from `react-apollo`):&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;
import React from &#39;react&#39;;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;
import ReactDOM from &#39;react-dom&#39;;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;
import { ApolloProvider } from &#39;react-apollo&#39;;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;
import { ApolloClient } from &#39;apollo-client&#39;;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;
import { HttpLink } from &#39;apollo-link-http&#39;;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;
import &#39;./index.css&#39;;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;
import App from &#39;./App&#39;;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;
const client = new ApolloClient({&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;
&amp;nbsp; &amp;nbsp; link: new HttpLink({ uri: &#39;http://localhost:8080/graphql&#39; })&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;
})&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;
ReactDOM.render(&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;
&amp;nbsp; &amp;nbsp; &amp;lt;ApolloProvider client={client}&amp;gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;App /&amp;gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;
&amp;nbsp; &amp;nbsp; &amp;lt;/ApolloProvider&amp;gt;,&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;
&amp;nbsp; &amp;nbsp; document.getElementById(&#39;root&#39;));&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
Next, we use the `react-apollo` module which provides a higher-order function using which we can glue together a component with the result from a GraphQL query response:&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
import React, { Component } from &#39;react&#39;;&lt;br /&gt;
import { graphql } from &#39;react-apollo&#39;;&lt;br /&gt;
import gql from &#39;graphql-tag&#39;;&lt;br /&gt;
import Course from &#39;./Course&#39;;&lt;br /&gt;
&lt;br /&gt;
class CourseList extends Component {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; render() {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; const { allCourses } = this.props.data;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (!allCourses) return null;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return allCourses.map(course =&amp;gt; {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return (&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;Course key={course.id}&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; course={course} /&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; );&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; });&lt;br /&gt;
&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
export default graphql(gql`&lt;br /&gt;
&amp;nbsp; &amp;nbsp; query CourseListQuery {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; allCourses {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; id&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; name&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; description&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
`)(CourseList);&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;Here the graphql higher-order function accepts two arguments - the GraphQL query and the view component that has to be updated with the query result. The result of the query response is passed to the component as props (this.props.data).&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;b&gt;Next steps:&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;I&#39;ve briefly read about `Relay` and I plan to experiment with it to see how it can be used to connect to a GraphQL server and compare it to see how it fairs with Apollo.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;b&gt;GitHub repo&lt;/b&gt; -&amp;nbsp;&lt;a href=&quot;https://github.com/sagar-ganatra/react-graphql-apollo-app&quot;&gt;https://github.com/sagar-ganatra/react-graphql-apollo-app&lt;/a&gt;&lt;/span&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.sagarganatra.com/feeds/2264780591062321217/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.sagarganatra.com/2018/01/on-graphql-and-building-application-using-react-apollo.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8417810603086728638/posts/default/2264780591062321217'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8417810603086728638/posts/default/2264780591062321217'/><link rel='alternate' type='text/html' href='http://www.sagarganatra.com/2018/01/on-graphql-and-building-application-using-react-apollo.html' title='On GraphQL and building an application using React Apollo'/><author><name>Sagar Ganatra</name><uri>http://www.blogger.com/profile/15129859862786257527</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhoO56BqdUmSACmPZKwemvyzRtEm1xJVsPVudy1_Tc2U4vafHustJn0_oFtUkKVcz1oGe_p2woZN3j04yI3Sf_xsTrrlcdno6mLnN1Qz380TamkT3P919jIRjh1acuRGA/s220/Mypic.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiwrm62c1RSqGXNTaF6Rv2iN2omMY171Jw3GUADEho-pcyVkYGegSNiQ8NjIyClw8BdXxL99CzgFe15IAqqmGRUhFlND0mVDxt6grPe-asgoKR_olyfPdPurJe09CmeBZUW8s0NJBjMD1ES/s72-c/graphiql-interface.tiff" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8417810603086728638.post-9208100366626112807</id><published>2017-07-28T21:39:00.001+05:30</published><updated>2018-01-23T16:22:44.119+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript/jQuery"/><category scheme="http://www.blogger.com/atom/ns#" term="React"/><category scheme="http://www.blogger.com/atom/ns#" term="Redux"/><title type='text'>React Redux starter kit - Rekit</title><content type='html'>I have been developing applications using React and Redux for quite some time now and I feel there are several starter kits out there. Although some add too much of boilerplate code, some include several libraries (to make it one kit that includes all) and some take the route of adding minimal boilerplate to include only the required libraries. I plan to write about these React-Redux starter kits/boilerplates in the coming weeks. This post focuses on a starter kit called Rekit. Rekit provides basic scaffolding and comes with a CLI that allows you to add features to your React application. Rekit focuses on application structure. It divides the application in terms of features, wherein each feature acts as a decoupled component and then assembled at the root level.&lt;br /&gt;
&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;Since I mentioned the word &#39;boilerplate&#39;, a React-Redux application would have to include some boilerplate code before one starts to write any functional code. Even a simple application would need some boilerplate code added. A project created with Rekit has basic scaffolding and also includes boilerplate code such as configuring a store, adding middleware such as redux-thunk and router (react-router-redux), adding root path (/) to the list of routes and defining an App container where the route components would be rendered etc. It brings developer to a place where he&#39;s are ready to add functional code to the application.&lt;br /&gt;
&lt;br /&gt;
Rekit follows feature oriented architecture to structure the application. Instead of building the application in terms of containers, components and actions; an application built with Rekit is organized in terms of features. Here, each feature is decoupled and would have its own set of containers, components, routes and actions. For example, consider an application that allows you to add a to-do and list the to-dos; it would have two routes - /add and /list, two containers - &#39;Add&#39; and &#39;List&#39; that connect to the Redux store and dispatch actions that update the state variables in the Redux store, actions - &#39;addTodo&#39;&amp;nbsp;and &#39;getTodos&#39; that update and read from the Redux state. Also, the CLI allows you to create dumb components(view-only) that are then included in container&#39;s render method whose sole responsibility would be to display the values passed to it and invoke handlers defined in its parent container.&lt;br /&gt;
&lt;br /&gt;
Rekit CLI makes it really easy to create an application and add features to it. After installing Rekit (&lt;i&gt;npm i -g rekit&lt;/i&gt;), you can use &lt;i&gt;rekit&lt;/i&gt; command to create a project.&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;rekit&amp;nbsp;create todo-app&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
this would create a todo-app with package.json&amp;nbsp;in it. Change the directory to the newly created project and then do &#39;&lt;i&gt;npm i&lt;/i&gt;&#39; to install the dependencies.&lt;br /&gt;
&lt;br /&gt;
The next step would be to add a feature and a couple of Containers and Actions in the feature:&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;rekit add feature todo&lt;/i&gt;
&lt;br /&gt;
&lt;i&gt;rekit add component todo/List -c&lt;/i&gt; // -c flag to create a container component&lt;br /&gt;
&lt;i&gt;rekit add component todo/Add -c&lt;/i&gt;
&lt;br /&gt;
&lt;i&gt;rekit add action todo/add&lt;/i&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;divCF&quot;&gt;
+ todo-app&lt;br /&gt;
&amp;nbsp; &amp;nbsp; + src&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; + common&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;- configStore.js&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; - history.js&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; - rootReducer.js&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; - routeConfig.js&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;+ features&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;+ todo&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;+ redux&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; - actions.js&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; - add.js&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; - constants.js&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; - initialState.js&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; - reducer.js&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; - update.js&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; - Add.js&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; - Add.less&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; - index.js&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; - List.js&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; - List.less&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; - ListItem.js&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; - ListItem.less&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; - route.js&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; - style.less&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; + images&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; + styles&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;- index.html&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;- index.js&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;- Root.js&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; + tests&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; + tools&lt;/div&gt;
&lt;br /&gt;
Rekit scaffolds the project with a basic setup which includes the entry point to the application in index.js, redux store and route configuration related files in &lt;i&gt;common&lt;/i&gt; directory and it also includes a &#39;default page&#39; as a feature (not shown above). It adds/updates directories and files in the project as and when you add a feature, component or an action.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;On one action per file methodology:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Rekit makes it a mandate to create one action per file instead of several actions in a single file and calling it as a reducer. I was initially not comfortable with this approach but then by following through the application structure, it made more sense. Every action is defined in a file and it exports two functions – an action and a reducer.&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;http://gist-it.appspot.com/http://github.com/sagar-ganatra/rekit-todo-app/blob/master/src/features/todo/redux/add.js&quot;&gt;&lt;/script&gt; The CLI then includes this file in feature’s root reducer file - todo/redux/reducer.js:&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;http://gist-it.appspot.com/http://github.com/sagar-ganatra/rekit-todo-app/blob/master/src/features/todo/redux/reducer.js&quot;&gt;&lt;/script&gt; Notice the last line - &lt;i&gt;return reducers.reduce((s, r) =&amp;gt; r(s, action), newState);&lt;/i&gt; it returns the reducer function for each of the reducers defined in the feature. The feature root reducer was earlier imported into the application’s root reducer:&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;http://gist-it.appspot.com/http://github.com/sagar-ganatra/rekit-todo-app/blob/master/src/common/rootReducer.js&quot;&gt;&lt;/script&gt; The CLI adds the import statements, updates the &lt;i&gt;reducer&lt;/i&gt; list and keeps the application updated whenever a new feature is added or updated. I&#39;ve been very happy with this starter kit so far, not to forget, it adds unit test files, linting rules and build configuration files. Also, there is an option to replace &lt;i&gt;redux-thunk&lt;/i&gt; with &lt;i&gt;redux-saga&lt;/i&gt;.&lt;br /&gt;
&lt;br /&gt;
I&#39;ve created a sample todo app and have posted the code on GitHub - &lt;a href=&quot;https://github.com/sagar-ganatra/rekit-todo-app&quot;&gt;https://github.com/sagar-ganatra/rekit-todo-app&lt;/a&gt;
 </content><link rel='replies' type='application/atom+xml' href='http://www.sagarganatra.com/feeds/9208100366626112807/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.sagarganatra.com/2017/07/react-redux-starter-kit-rekit.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8417810603086728638/posts/default/9208100366626112807'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8417810603086728638/posts/default/9208100366626112807'/><link rel='alternate' type='text/html' href='http://www.sagarganatra.com/2017/07/react-redux-starter-kit-rekit.html' title='React Redux starter kit - Rekit'/><author><name>Sagar Ganatra</name><uri>http://www.blogger.com/profile/15129859862786257527</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhoO56BqdUmSACmPZKwemvyzRtEm1xJVsPVudy1_Tc2U4vafHustJn0_oFtUkKVcz1oGe_p2woZN3j04yI3Sf_xsTrrlcdno6mLnN1Qz380TamkT3P919jIRjh1acuRGA/s220/Mypic.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8417810603086728638.post-7278491368748057675</id><published>2016-12-13T17:26:00.000+05:30</published><updated>2016-12-13T17:26:03.741+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="CSS"/><category scheme="http://www.blogger.com/atom/ns#" term="Hugo"/><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript/jQuery"/><category scheme="http://www.blogger.com/atom/ns#" term="Static Site Generator"/><title type='text'>Building your static site with Hugo, FlightJS, SASS and Gulp</title><content type='html'>Hugo provides a good workspace for creating layouts and content. I&#39;m very much satisfied with the options available to customise the site. However, Hugo does not have a say in how CSS and JavaScript should be structured so that it can be included on our site. In Hugo, the DOM nodes are already created and we need a mechanism which we can employ in adding event listeners to these DOM nodes.&lt;br /&gt;
&lt;br /&gt;
SPA frameworks like Angular and React, create DOM nodes and define event listeners in the controller of the&amp;nbsp;component. To attach event listeners to an existing DOM tree I came across a JavaScript framework called &lt;a href=&quot;https://flightjs.github.io/&quot;&gt;FlightJS&lt;/a&gt;. It&#39;s a framework created by folks at Twitter that helps in adding behaviour to the DOM nodes. It&#39;s a minimal framework which does not dictate how the DOM nodes should be rendered nor it dictates the other aspects of the web application, such as routing, request/response handling, structuring data so that other components can consume it etc. FlightJS provides only a mechanism that enables us to add behaviour to the existing DOM nodes.&lt;br /&gt;
&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;This is exactly what I needed to build my static site. Let&#39;s take a look at how I have structured my site using &lt;i&gt;SCSS&lt;/i&gt;, &lt;i&gt;FlightJS&lt;/i&gt; and &lt;i&gt;Gulp&lt;/i&gt; for building the static content:&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;
--src&lt;br /&gt;
&amp;nbsp; --js&lt;br /&gt;
&amp;nbsp; &amp;nbsp; --pages&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; --home&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; --index.js&lt;br /&gt;
&amp;nbsp; &amp;nbsp; --vendor&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; --flight.js&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; --jquery.js&lt;br /&gt;
&amp;nbsp; --styles&lt;br /&gt;
&amp;nbsp; &amp;nbsp; --pages&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; --home&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; --index.scss&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; --vendor&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; --index.scss&lt;br /&gt;
&lt;/code&gt;
&lt;br /&gt;
I have created an &#39;&lt;i&gt;src&lt;/i&gt;&#39; directory in my Hugo site which will contain all the JavaScript and SCSS files. Hugo&#39;s documentation suggests that we need to keep all static content (JavaScript, CSS, images, font files etc) in &#39;&lt;i&gt;static&lt;/i&gt;&#39; directory. Here &#39;&lt;i&gt;src&lt;/i&gt;&#39; directory will contain the development code i.e. unprocessed SCSS files and non-minified JavaScript files. The &#39;&lt;i&gt;static&lt;/i&gt;&#39; directory, on the other hand, will contain CSS code (processed SCSS) and minified JavaScript files which are production ready.&lt;br /&gt;
&lt;br /&gt;
In our example, the &lt;i&gt;FlightJS&lt;/i&gt; code can be included in &#39;&lt;i&gt;js/pages/home/index.js&lt;/i&gt;&#39; file. Here&#39;s the code which creates a &lt;i&gt;FlightJS&lt;/i&gt; component, defines a &#39;&lt;i&gt;click&lt;/i&gt;&#39; event handler and attaches the component to an existing DOM node:&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/sagar-ganatra/c04531ce026a08b6dcb57fa6dfa8059b.js&quot;&gt;&lt;/script&gt;

&lt;br /&gt;
FlightJS has a dependency on &lt;i&gt;jQuery&lt;/i&gt; and thus you see &lt;i&gt;jquery.js&lt;/i&gt; present in the &#39;&lt;i&gt;vendor&lt;/i&gt;&#39; directory. A lot can be done with FlightJS, however, I&#39;m restricting this post to build a proof of concept which demonstrates the minimal functionality.&lt;br /&gt;
&lt;br /&gt;
The next step is to add a build process that compiles the SCSS files, compress and concatenates JS files and creates a hash for these files for browser cache busting. I&#39;m using &lt;i&gt;GulpJS&lt;/i&gt; to create a pipeline build and here&#39;s the sequence:&lt;br /&gt;
&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;Compile &lt;i&gt;SCSS&lt;/i&gt; files - compile &#39;&lt;i&gt;pages&lt;/i&gt;&#39; and &#39;vendor&#39; files separately.&lt;/li&gt;
&lt;li&gt;Concatenate the vendor related CSS files.&lt;/li&gt;
&lt;li&gt;Move the generated files to &#39;&lt;i&gt;static/css&lt;/i&gt;&#39; directory.&lt;/li&gt;
&lt;li&gt;Compress the JS files - &#39;&lt;i&gt;pages&lt;/i&gt;&#39; and &#39;&lt;i&gt;vendor&lt;/i&gt;&#39; files separately.&lt;/li&gt;
&lt;li&gt;Move the generated files to &#39;&lt;i&gt;static/js&lt;/i&gt;&#39; directory.&lt;/li&gt;
&lt;li&gt;Use &#39;&lt;i&gt;&lt;a href=&quot;https://www.npmjs.com/package/gulp-hash&quot; target=&quot;_blank&quot;&gt;gulp-hash&lt;/a&gt;&lt;/i&gt;&#39; to create a&amp;nbsp;hash for the generated JS and CSS files. Create a hash manifest file and place it in the &#39;&lt;i&gt;data&lt;/i&gt;&#39; directory (&lt;i&gt;assets_js.json&lt;/i&gt; and &lt;i&gt;assets_css.json&lt;/i&gt;).&lt;/li&gt;
&lt;/ol&gt;
&lt;br /&gt;
The &lt;i&gt;gulpfile.js&lt;/i&gt; used to build the pipeline can be referred here: &lt;a href=&quot;https://github.com/sagar-ganatra/hugo_example/blob/master/gulpfile.js&quot;&gt;https://github.com/sagar-ganatra/hugo_example/blob/master/gulpfile.js&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
After&amp;nbsp;compiling and generating content in the &#39;&lt;i&gt;static&lt;/i&gt;&#39; directory, you can refer to these files in your layout templates:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;link href=&quot;{{ .Site.BaseURL }}css/vendor/vendor.css }}&quot; rel=&quot;stylesheet&quot; type=&quot;text/css&quot;&amp;gt;&lt;br /&gt;
&amp;lt;script src=&quot;{{ .Site.BaseURL }}js/vendor/vendor.js }}&quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here the template variable {{ .Site.BaseURL }} would be replaced with the baseUrl defined in the config.toml file and when the generator creates the static files, it would be referring to the file &#39;&amp;lt;site&amp;gt;/css/vendor/vendor.css&#39; and &#39;&amp;lt;site&amp;gt;/js/vendor/vendor.js&#39;. Since we are creating adding a hash to these files, it would not be possible to refer to &#39;&lt;i&gt;vendor.js&lt;/i&gt;&#39; and &#39;&lt;i&gt;vendor.css&lt;/i&gt;&#39; files like this. However, we can use the manifest files created when generating a&amp;nbsp;hash&amp;nbsp;for referring these files.&lt;br /&gt;
&lt;br /&gt;
As noted in the last step of the Gulp build process, we are creating manifest files &#39;&lt;i&gt;assets_js.json&lt;/i&gt;&#39; and &#39;&lt;i&gt;assets_css.json&lt;/i&gt;&#39; in the &#39;&lt;i&gt;data&lt;/i&gt;&#39; directory. The content is a JSON structure that contains hash references:&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;
{&lt;br /&gt;
&amp;nbsp; &quot;pages/home.js&quot;:&quot;pages/home_4740e2cf.js&quot;,&lt;br /&gt;
&amp;nbsp; &quot;pages/home_debug.js&quot;:&quot;pages/home_debug_3f723556.js&quot;,&lt;br /&gt;
&amp;nbsp; &quot;vendor/vendor.js&quot;:&quot;vendor/vendor_f8da36b2.js&quot;,&lt;br /&gt;
&amp;nbsp; &quot;vendor/vendor_debug.js&quot;:&quot;vendor/vendor_debug_b3868b34.js&quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;/code&gt;
&lt;br /&gt;
Hugo can read files in the &#39;&lt;i&gt;data&lt;/i&gt;&#39; directory and it supports &lt;i&gt;TOML&lt;/i&gt;, &lt;i&gt;YAML&lt;/i&gt; and &lt;i&gt;JSON&lt;/i&gt; file formats. Now we can modify our template to get the hash refernce from the asset files:&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;
&amp;lt;link&lt;br /&gt;
&amp;nbsp; &amp;nbsp; href=&quot;{{ .Site.BaseURL }}css/{{ index .Site.Data.code_assets.assets_css &quot;vendor/vendor.css&quot; }}&quot;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; rel=&quot;stylesheet&quot;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; type=&quot;text/css&quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;/code&gt; and&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;
&amp;lt;script&lt;br /&gt;
&amp;nbsp; &amp;nbsp; src=&quot;{{ .Site.BaseURL }}js/{{ index .Site.Data.code_assets.assets_js &quot;vendor/vendor.js&quot; }}&quot;&amp;gt;&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;/code&gt;
&lt;br /&gt;
The template variable &#39;&lt;i&gt;.Site.Data.code_assets.assets_js&lt;/i&gt;&#39; will contain reference to the values in the file &#39;&lt;i&gt;data/code_assets/asset_js.json&lt;/i&gt;&#39; and the reference key &#39;&lt;i&gt;vendor/vendor.js&lt;/i&gt;&#39; would return the value assigned to it (&lt;i&gt;vendor/vendor_f8da36b2.js&lt;/i&gt;).&lt;br /&gt;
&lt;br /&gt;
Code is shared on my github repository here:&amp;nbsp;&lt;a href=&quot;https://github.com/sagar-ganatra/hugo_example&quot;&gt;https://github.com/sagar-ganatra/hugo_example&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.sagarganatra.com/feeds/7278491368748057675/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.sagarganatra.com/2016/12/building-your-static-site-with-hugo.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8417810603086728638/posts/default/7278491368748057675'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8417810603086728638/posts/default/7278491368748057675'/><link rel='alternate' type='text/html' href='http://www.sagarganatra.com/2016/12/building-your-static-site-with-hugo.html' title='Building your static site with Hugo, FlightJS, SASS and Gulp'/><author><name>Sagar Ganatra</name><uri>http://www.blogger.com/profile/15129859862786257527</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhoO56BqdUmSACmPZKwemvyzRtEm1xJVsPVudy1_Tc2U4vafHustJn0_oFtUkKVcz1oGe_p2woZN3j04yI3Sf_xsTrrlcdno6mLnN1Qz380TamkT3P919jIRjh1acuRGA/s220/Mypic.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8417810603086728638.post-4389149698595560239</id><published>2016-12-08T18:43:00.001+05:30</published><updated>2016-12-08T19:31:49.158+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="Hugo"/><category scheme="http://www.blogger.com/atom/ns#" term="Static Site Generator"/><title type='text'>Hugo - On layouts and content organization</title><content type='html'>Layouts in Hugo allow you to define the how the posts in the content directory would be displayed. In addition to defining layouts for the content posts, you can define the layout for the home page, define partials and include it in different layout templates, also define the default layout to be used in case the matching content type layout is not found.&lt;br /&gt;
&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;The directory structure followed in Layouts imitates the directory structure of the content directory:&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;
--layouts&lt;br /&gt;
&amp;nbsp; --_default&lt;br /&gt;
&amp;nbsp; &amp;nbsp; --single.html&lt;br /&gt;
&amp;nbsp; &amp;nbsp; --summary.html&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;
&amp;nbsp; --pages&lt;br /&gt;
&amp;nbsp; &amp;nbsp; --single.html&lt;br /&gt;
&amp;nbsp; &amp;nbsp; --summary.html&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; --partials&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; &amp;nbsp; --header.html&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; &amp;nbsp; --aside.html&lt;br /&gt;
&amp;nbsp; --index.html&lt;br /&gt;
&lt;/code&gt;
&lt;br /&gt;
The site&#39;s home page is defined in layout&#39;s index.html file. If you&#39;re building a blog, this page would list the recent&amp;nbsp;posts. Hugo provides several Site level variables that you use it in this template file:&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/sagar-ganatra/206ddadf076a8bf48bde159f86e084ca.js&quot;&gt;&lt;/script&gt;

&lt;br /&gt;
Notice that several template variables are used to create the home page. The one that will display recent posts is mentioned inside the body tag of the template:&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;
{{ range .Data.Pages }}&lt;br /&gt;
&amp;nbsp; {{ if or (eq .Type &quot;posts&quot;) (eq .Type &quot;posts-series&quot;) }}&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;lt;h3&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;a href={{ .Permalink }}&amp;gt;{{ .Title }}&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;/h3&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;{{ .Render &quot;summary&quot; }}&lt;br /&gt;
&amp;nbsp; {{ end }}&lt;br /&gt;
{{ end }}&lt;br /&gt;
&lt;/code&gt;
&lt;br /&gt;
The &lt;i&gt;range&lt;/i&gt; operator is used to iterate over an array; here the template variable &lt;i&gt;.Data.Pages&lt;/i&gt; contain&amp;nbsp;all the posts listed in the content directory. Inside the &lt;i&gt;range&lt;/i&gt; loop, a condition is specified to see if the page if of a particular &lt;i&gt;Type&lt;/i&gt;. The &lt;i&gt;Type&lt;/i&gt; information is determined by the location of the post in the content directory. If the post is defined in the &#39;&lt;i&gt;posts&lt;/i&gt;&#39; directory then the type would be &#39;&lt;i&gt;posts&lt;/i&gt;&#39;, similarly, if you have top level pages defined in &#39;&lt;i&gt;pages&lt;/i&gt;&#39; directory, then the type would be &#39;&lt;i&gt;pages&lt;/i&gt;&#39;. Alternatively, you can override the default &lt;i&gt;Type&lt;/i&gt; by mentioning &#39;&lt;i&gt;type&lt;/i&gt;&#39; field in the &lt;i&gt;front matter&lt;/i&gt;&amp;nbsp;of the post(see the content organisation section below).&lt;br /&gt;
&lt;br /&gt;
When listing posts, you would want to list only the &lt;i&gt;summary&lt;/i&gt; information instead of the entire content of the post. The template &lt;i&gt;{{ .Render &quot;summary&quot; }}&lt;/i&gt; is used when you have a separate template - &lt;i&gt;summary.html&lt;/i&gt; defined to display the &lt;i&gt;summary&lt;/i&gt; information. This template could display additional information such as &lt;i&gt;published date&lt;/i&gt;, &lt;i&gt;tags&lt;/i&gt; etc. If you would like to display only the &lt;i&gt;summary&lt;/i&gt; without including any additional template then use the template variable &lt;i&gt;{{ .Summary }}&lt;/i&gt;. Hugo will pick up the first 70 words from the content and display it as the summary of the post. Alternatively, you can insert a jump break by including &amp;lt;!--more--&amp;gt; &amp;nbsp;tag. Hugo will pick up all the content before this tag and display it as the summary of the post.&lt;br /&gt;
&lt;br /&gt;
Let&#39;s take a look at &lt;i&gt;summary.html&lt;/i&gt; defined in _default directory:&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;
Published date: {{ .Date.Format &quot;2 Jan, 2006&quot; }}&lt;br /&gt;
{{ .Summary }}&lt;br /&gt;
{{ if .Truncated }}&lt;br /&gt;
&amp;nbsp; &amp;lt;a href=&quot;{{ .Permalink }}&quot;&amp;gt;Read more &amp;gt;&amp;gt; &amp;lt;/a&amp;gt;&lt;br /&gt;
{{ end}}&lt;br /&gt;
&lt;/code&gt;
&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Here we are using the template variable &lt;i&gt;{{ .Summary }}&lt;/i&gt; to display the summary of the post. Also, we are displaying the published date and providing a link to the post if the content is truncated. The flag &lt;i&gt;Truncated&lt;/i&gt; would be true if there are more than 70 words in the post or a &amp;lt;!--more--&amp;gt; tag is inserted. Any template defined in &#39;&lt;i&gt;layouts/_default&lt;/i&gt;&#39; will be used as a default template to render the content. You can always define a different layout by creating a directory with its name matching the directory name in the content directory.&lt;/div&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;b&gt;On content organisation:&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt; &lt;span style=&quot;font-family: inherit;&quot;&gt;Hugo organises the generated content in the same way as it&#39;s defined. However, you can override it by updating some of the fields in the front matter of the post. You can specify additional fields - &#39;&lt;/span&gt;&lt;i style=&quot;font-family: inherit;&quot;&gt;slug&#39;&lt;/i&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;, &#39;&lt;/span&gt;&lt;i style=&quot;font-family: inherit;&quot;&gt;type&#39;&lt;/i&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;, &#39;&lt;/span&gt;&lt;i style=&quot;font-family: inherit;&quot;&gt;path&#39;&lt;/i&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt; and &#39;&lt;/span&gt;&lt;i style=&quot;font-family: inherit;&quot;&gt;url&#39;&lt;/i&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt; to override the default.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt; &lt;span style=&quot;font-family: inherit;&quot;&gt;For example, if you have written a couple of posts at &#39;&lt;i&gt;posts/blog-post-1.md&lt;/i&gt;&#39; and &#39;&lt;i&gt;posts/blog-post-2.md&lt;/i&gt;&#39;, Hugo will generate the content in public directory at &amp;nbsp;&lt;/span&gt;&#39;&lt;i&gt;posts/blog-post-1/index.html&lt;/i&gt;&#39; and &#39;&lt;i&gt;posts/blog-post-2/index.html&lt;/i&gt;&#39;.&amp;nbsp;&lt;span style=&quot;font-family: inherit;&quot;&gt;If you would like to rename &#39;&lt;i&gt;blog-post-1&lt;/i&gt;&#39; and &#39;&lt;i&gt;blog-post-2&lt;/i&gt;&#39; to something else specify the &#39;&lt;i&gt;slug&lt;/i&gt;&#39; field in the front matter:&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt; &lt;code&gt;+++&lt;br /&gt;
date = &quot;2016-12-05T20:08:38+05:30&quot;&lt;br /&gt;
draft = true&lt;br /&gt;
title = &quot;blog post 2&quot;&lt;br /&gt;
&lt;b&gt;slug = &quot;first-post&quot;&lt;/b&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;/span&gt;&lt;br /&gt;
+++&lt;br /&gt;
&lt;/code&gt;
&lt;br /&gt;
This post now can be accessed at &#39;&lt;i&gt;&amp;lt;site&amp;gt;/posts/first-post&lt;/i&gt;&#39;.&lt;br /&gt;
&lt;br /&gt;
You can also specify the &#39;&lt;i&gt;url&#39;&lt;/i&gt;&amp;nbsp;field in the front matter and this will render the page at the given &#39;&lt;i&gt;url&lt;/i&gt;&#39;.&amp;nbsp;For example, if you have top level pages defined under pages directory - &#39;&lt;i&gt;pages/about-us&lt;/i&gt;&#39; and &#39;&lt;i&gt;pages/contact-us&lt;/i&gt;&#39; and want to render them at the top level i.e. at &#39;&lt;i&gt;/about-us&lt;/i&gt;&#39; and &#39;&lt;i&gt;/contact-us&#39;&lt;/i&gt;:&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;
+++&lt;br /&gt;
date = &quot;2016-12-05T20:08:38+05:30&quot;&lt;br /&gt;
draft = true&lt;br /&gt;
title = &quot;about us&quot;&lt;br /&gt;
&lt;b&gt;url = &quot;/about-us&quot;&lt;/b&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;/span&gt;&lt;br /&gt;
+++&lt;br /&gt;
&lt;/code&gt;
&lt;br /&gt;
If both &lt;i&gt;slug&lt;/i&gt; and &lt;i class=&quot;&quot;&gt;url&lt;/i&gt;&amp;nbsp;are specified then, &lt;i class=&quot;&quot;&gt;url&lt;/i&gt;&amp;nbsp;would take precedence. The &lt;i class=&quot;&quot;&gt;url&lt;/i&gt; field in the&amp;nbsp;front matter would take precedence over any other field.&lt;br /&gt;
&lt;br /&gt;
As mentioned earlier, you can specify the &lt;i&gt;type&lt;/i&gt; field in the front matter to override the default type assigned to the post. Consider you are writing a series of post on a particular topic and you have created a directory &#39;&lt;i&gt;series-topic&lt;/i&gt;&#39; under &#39;&lt;i&gt;posts&lt;/i&gt;&#39;. Here you can add the field &#39;&lt;i&gt;type&lt;/i&gt;&#39; in the&amp;nbsp;front matter and provide a value say &#39;&lt;i&gt;posts-series&lt;/i&gt;&#39;. Using this type information you can easily get to the set of posts and display content as necessary.&lt;br /&gt;
&lt;br /&gt;
Example source code can be found here -&amp;nbsp;&lt;a href=&quot;https://github.com/sagar-ganatra/hugo_example&quot;&gt;https://github.com/sagar-ganatra/hugo_example&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.sagarganatra.com/feeds/4389149698595560239/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.sagarganatra.com/2016/12/hugo-on-layouts-and-content-organization.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8417810603086728638/posts/default/4389149698595560239'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8417810603086728638/posts/default/4389149698595560239'/><link rel='alternate' type='text/html' href='http://www.sagarganatra.com/2016/12/hugo-on-layouts-and-content-organization.html' title='Hugo - On layouts and content organization'/><author><name>Sagar Ganatra</name><uri>http://www.blogger.com/profile/15129859862786257527</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhoO56BqdUmSACmPZKwemvyzRtEm1xJVsPVudy1_Tc2U4vafHustJn0_oFtUkKVcz1oGe_p2woZN3j04yI3Sf_xsTrrlcdno6mLnN1Qz380TamkT3P919jIRjh1acuRGA/s220/Mypic.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8417810603086728638.post-3167529543062238139</id><published>2016-12-04T23:28:00.001+05:30</published><updated>2016-12-04T23:28:22.235+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="Hugo"/><category scheme="http://www.blogger.com/atom/ns#" term="Static Site Generator"/><title type='text'>On Static Site Generator - Hugo</title><content type='html'>&lt;span style=&quot;font-family: inherit;&quot;&gt;Over the last few weeks, I&#39;ve been looking into a Static Site Generator - Hugo. A Static Site Generator is useful if you&#39;re building an application which does not require dynamic data to be served. A blog can be considered as a service which serves static content. Instead of storing the content in a database field, the content is stored in a file (HTML file). Thus when a page is requested the content is served immediately instead of it being generated on demand; resulting in accelerated response times and thus better user experience.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;Hugo helps in generating a static site. It has got several features such as defining layouts for various types of content, displaying a list of related content, tagging content (taxonomies), using themes and also generating content from data in JSON, YAML or TOML files.&lt;br /&gt;
&lt;br /&gt;
Hugo provides a Command Line Interface to generate content. After installing Hugo &lt;span style=&quot;font-family: monospace;&quot;&gt;(brew install hugo)&lt;/span&gt;, create a new site using the command&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;&lt;/code&gt; &lt;code&gt;hugo new site hugo_bootstrap_example&amp;nbsp;&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
Hugo creates a directory structure as detailed below:&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;
--archtypes&lt;br /&gt;
--content&lt;br /&gt;
--data&lt;br /&gt;
--layouts&lt;br /&gt;
--static&lt;br /&gt;
--themes&lt;br /&gt;
&lt;/code&gt;
&lt;br /&gt;
&lt;br /&gt;
All content should be present in the &#39;&lt;i&gt;content&lt;/i&gt;&#39; directory. If you are considering to build a blog, then this directory would contain all the blog posts. To create a new post use the command:&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;hugo new posts/blog-post-1.md&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
This will create a markdown file &lt;i&gt;blog-post-1.md&lt;/i&gt;&amp;nbsp;under &#39;&lt;i&gt;content/posts&lt;/i&gt;&#39; directory. The directory &#39;&lt;i&gt;posts&lt;/i&gt;&#39; is created if it doesn&#39;t exist. When you open the file, you&#39;ll notice that it contains some meta-data in it, it&#39;s called &lt;i&gt;front matter&lt;/i&gt;. By default the front matter contains &#39;&lt;i&gt;date&lt;/i&gt;&#39; and&amp;nbsp;&#39;&lt;i&gt;title&lt;/i&gt;&#39;, &amp;nbsp;here&amp;nbsp;date being the created date and title being the file name:&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;
+++&lt;br /&gt;
date = &quot;2016-12-04T16:13:35+05:30&quot;&lt;br /&gt;
title = &quot;blog post 1&quot;&lt;br /&gt;
&lt;br /&gt;
+++&lt;/code&gt;&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
The &lt;i&gt;front matter&lt;/i&gt; is enclosed in &lt;i&gt;+++&lt;/i&gt;, any text that follows after the last &#39;&lt;i&gt;+++&lt;/i&gt;&#39; will constitute the content or the body of the post. Hugo organises the output in the same way as it is declared i.e. to view the post you can access the URL &lt;i&gt;&amp;lt;site&amp;gt;/post/blog-post-1&lt;/i&gt;. This can be changed by updating the &lt;i&gt;front matter &lt;/i&gt;to include &lt;i&gt;section&lt;/i&gt;, &lt;i&gt;path&lt;/i&gt; and &lt;i&gt;slug&lt;/i&gt; fields (more on this in the next post).&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;On Layouts:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Once you have defined the type of content that you want to render, you need to define how this content will be rendered. For example, if you have created two different types of content - &#39;&lt;i&gt;posts&lt;/i&gt;&#39; and &#39;&lt;i&gt;pages&lt;/i&gt;&#39; then you need to define views for &#39;&lt;i&gt;posts&lt;/i&gt;&#39; and &#39;&lt;i&gt;pages&lt;/i&gt;&#39; in the &#39;&lt;i&gt;layouts&lt;/i&gt;&#39; directory. This is required because Hugo does not know how to render the content. It took me some time to understand how Hugo does this; it looks up for templates defined in the layout directory and generates static files based on the number of files present in the &#39;&lt;i&gt;content&lt;/i&gt;&#39; directory. This also means that if you have defined content but the corresponding layout is missing, then no static file is generated for that type of content.&lt;br /&gt;
&lt;br /&gt;
Note: If you would like to use the same layout for all types of content, then create a directory &#39;_default&#39; under layouts and then define the view templates under it.&lt;br /&gt;
&lt;br /&gt;
Let&#39;s create a template for &#39;&lt;i&gt;posts&lt;/i&gt;&#39;:&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;
--layouts&lt;br /&gt;
&amp;nbsp; --posts&lt;br /&gt;
&amp;nbsp; &amp;nbsp; --single.html&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
Here &lt;i&gt;single.html&lt;/i&gt; is a template file, that defines how the post would look like when the user accesses the URL &lt;i&gt;&amp;lt;site&amp;gt;/posts/blog-post-1&lt;/i&gt;. In addition to displaying the &lt;i&gt;title&lt;/i&gt; and the &lt;i&gt;content&lt;/i&gt; of the post, you can display the &lt;i&gt;date&lt;/i&gt; on which the post was published:&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;title&amp;gt;{{ .Title }}&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;h1&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;lt;a href=&quot;{{ .Permalink }}&quot;&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; {{ .Title }}&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;/h1&amp;gt;&lt;br /&gt;
&amp;nbsp; {{ .Content }}&lt;br /&gt;
&amp;nbsp; &amp;lt;h6&amp;gt;Published on: {{ .Date.Format &quot;Mon 2, Jan 2016&quot; }}&amp;lt;/h6&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;/code&gt;&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Hugo uses GO templates to generate the content. In the above example, &#39;&lt;i&gt;Title&lt;/i&gt;&#39;, &#39;&lt;i&gt;Permalink&lt;/i&gt;&#39;, &#39;&lt;i&gt;Content&lt;/i&gt;&#39; and &#39;&lt;i&gt;Date&lt;/i&gt;&#39; are template variables, which are used to generate static files based on the &lt;i&gt;front matter&lt;/i&gt; and the content defined in the file &#39;&lt;i&gt;blog-post-1.md&lt;/i&gt;&#39;.&lt;br /&gt;
&lt;br /&gt;
In addition to defining &lt;i&gt;single&lt;/i&gt; post view, you can also define a &lt;i&gt;list view&lt;/i&gt; (li.html) - a view to display a&amp;nbsp;list of content posts instead of one single post and a &lt;i&gt;summary view&lt;/i&gt; (summary.html) - to view only a part of the content.&lt;/div&gt;
&lt;br /&gt;
&lt;b&gt;Rendering the site using Hugo server:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Before we get to rendering the content on the browser, Hugo requires some configuration to display the content. This configuration contains site information such as the &#39;&lt;i&gt;baseUrl&lt;/i&gt;&#39;, &#39;&lt;i&gt;title&lt;/i&gt;&#39;, &#39;&lt;i&gt;languageCode&lt;/i&gt;&#39; and &#39;&lt;i&gt;theme&lt;/i&gt;&#39;. When you generate the site, you&#39;ll have the file &#39;&lt;i&gt;config.toml&lt;/i&gt;&#39; created, which contains the above configuration fields. All that is required is to provide the values for the above fields. Here&#39;s the example &#39;&lt;i&gt;config.toml&lt;/i&gt;&#39; file content:&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;
baseurl = &quot;localhost:1313&quot;&lt;br /&gt;
title = &quot;My New Hugo Site&quot;&lt;br /&gt;
languageCode = &quot;en-us&quot;&lt;br /&gt;
theme = &quot;ex_bootstrap_theme&quot;&lt;br /&gt;
&lt;/code&gt;
&lt;br /&gt;
Hugo comes with a built-in web server and you can start it using the command:&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;hugo server&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
It starts the server at port &lt;i&gt;1313&lt;/i&gt; and you can try the URL&amp;nbsp;&lt;i&gt;localhost:1313&lt;/i&gt;. This command will generate the static content and will watch for the file changes in directories generated by the &lt;i&gt;hugo new site&lt;/i&gt; command.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;On Themes:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
A Theme, like Layouts, is used to define templates. There&#39;s not much difference between a theme and a layout, except that a theme should be created if you want to reuse it for a different site. This will enable you to encapsulate the look and feel of the site along with behaviour (JavaScript) and share it with others who can then follow the same convention to build the site.&lt;br /&gt;
&lt;br /&gt;
I&#39;m inclined towards using a theme over layouts only for the sole reason that it can be shared with other users.&lt;br /&gt;
&lt;br /&gt;
Hugo does not ship with a default theme, however, a theme is required to run the server. You can download one of the many themes available at&amp;nbsp;&lt;a href=&quot;http://themes.gohugo.io/&quot;&gt;http://themes.gohugo.io/&lt;/a&gt; or create your own theme using the command:&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;hugo new theme &amp;lt;theme_name&amp;gt;&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Summary:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
I really liked Hugo and I&#39;m getting used to GO templates. There are tonnes of options available to customise the site and I&#39;m still exploring these options. The biggest selling point is it&#39;s performance when generating static content. I haven&#39;t tested the site containing several pages, but it takes say about 12ms to generate a very small site with 4 pages in it, which is extremely fast.&lt;br /&gt;
&lt;br /&gt;
Hugo does not dictate how your site should be styled, however, it provides a directory &#39;&lt;i&gt;static&lt;/i&gt;&#39; where all your CSS, Images and JavaScript files should be placed.&lt;/div&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.sagarganatra.com/feeds/3167529543062238139/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.sagarganatra.com/2016/12/on-static-site-generator-hugo.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8417810603086728638/posts/default/3167529543062238139'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8417810603086728638/posts/default/3167529543062238139'/><link rel='alternate' type='text/html' href='http://www.sagarganatra.com/2016/12/on-static-site-generator-hugo.html' title='On Static Site Generator - Hugo'/><author><name>Sagar Ganatra</name><uri>http://www.blogger.com/profile/15129859862786257527</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhoO56BqdUmSACmPZKwemvyzRtEm1xJVsPVudy1_Tc2U4vafHustJn0_oFtUkKVcz1oGe_p2woZN3j04yI3Sf_xsTrrlcdno6mLnN1Qz380TamkT3P919jIRjh1acuRGA/s220/Mypic.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8417810603086728638.post-2237852363806068108</id><published>2016-02-17T20:01:00.001+05:30</published><updated>2016-02-17T20:01:41.724+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="ES6"/><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript/jQuery"/><title type='text'>Learning ES6 - Arrow functions and the visibility of this and arguments scope in it</title><content type='html'>Last week I looked at the use of &lt;a href=&quot;http://www.sagarganatra.com/2016/02/learning-es6-let-const-temporal-dead-zone.html&quot; target=&quot;_blank&quot;&gt;&lt;i&gt;let and const keywords in ES6&lt;/i&gt;&lt;/a&gt;. This week I have been looking at Arrow function expressions, which enable you to create functions without using the &lt;i&gt;function&lt;/i&gt; keyword. They provide a shorter syntax to represent a function. I assumed that arrow functions only provide syntax sugar and all function expressions can be replaced with the new syntax. However, the scopes -&amp;nbsp;&lt;i&gt;this&lt;/i&gt; and &lt;i&gt;arguments&lt;/i&gt; refers to the enclosing scope and not that of the caller.&lt;br /&gt;
&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;b&gt;Shorter syntax:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Functions with only a return statement can now be represented using a shorter syntax:&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;divCF&quot;&gt;
[1, 2, 3].map(x =&amp;gt; x*x)
(() =&amp;gt; [1, 4, 9])()
&lt;/div&gt;
&lt;br /&gt;
In the first example, the arrow function expression takes only one parameter (x) and returns the square of that parameter. Notice that the expression does not have parentheses and does not use function brackets({}) or the return statement. To represent the expression &#39;x =&amp;gt; x*x&#39; in ES5, you would write:&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;divCF&quot;&gt;
function (x) {
    return x*x;
}
&lt;/div&gt;
&lt;br /&gt;
In the next example, the arrow function expression does not take any parameters and thus you will need to specify empty parentheses followed by the fat arrow (=&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
In a case where more than one parameter is present then it is mandatory to use parentheses:&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;divCF&quot;&gt;
((x, y) =&amp;gt; x + y)(3, 4)
&lt;/div&gt;
&lt;br /&gt;
In a case where the return value is represented using the object literal notation then the return value will have to be wrapped in a set of parentheses:&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;divCF&quot;&gt;
((x, y) =&amp;gt; ({x, y}))(1, 2)
&lt;/div&gt;
&lt;br /&gt;
Notice that the return object is represented as {x, y} instead of {x: x, y: y}. This is another addition to language; here {x, y} translates to {x: x, y: y}. It is mandatory to specify parentheses because the object literal notation would be considered as start of the function body with the use of &#39;{&#39; and that would result in a syntax error.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Default value for parameters:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Arrow function expressions and functions now allow you to specify default values to the parameters:&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;divCF&quot;&gt;
((x=1, y=2) =&amp;gt; x + y)(10);
((x=1, y=2) =&amp;gt; x + y)(undefined, 10);
&lt;/div&gt;
&lt;br /&gt;
The default value for the second parameter &amp;nbsp;- &#39;&lt;i&gt;y&lt;/i&gt;&#39; is 2 and when the function is invoked without specifying the second parameter then the default value is assigned to the parameter.
In a case where the value for the first parameter is unknown then one has to specify &#39;&lt;i&gt;undefined&lt;/i&gt;&#39; when invoking the function. &lt;br /&gt;
&lt;br /&gt;
The &lt;i&gt;rest&lt;/i&gt; parameter allows you to design functions with variable parameters. Here&#39;s the signature of the function:&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;divCF&quot;&gt;
((x, y, ...rest) =&amp;gt; rest.length)(1, 2, 3, 4, 5);
&lt;/div&gt;
&lt;br /&gt;
The &#39;...&amp;lt;param_name&amp;gt;&#39; notation is used to capture extra arguments passed to the function. Notice that it&#39;s different from the &lt;i&gt;arguments&lt;/i&gt; scope; the rest parameter stores the remaining parameters whereas arguments scope would refer to all the parameters passed to the function.
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;i&gt;this&lt;/i&gt; and &lt;i&gt;arguments&lt;/i&gt; scope inside arrow function expression:&lt;/b&gt;&lt;br /&gt;
&lt;param_name&gt;&lt;br /&gt;&lt;/param_name&gt;
Although, it may appear that every function expression can now be replaced with an arrow function expression, be careful when you use &lt;i&gt;this&lt;/i&gt;, &lt;i&gt;arguments&lt;/i&gt; and &lt;i&gt;super&lt;/i&gt; in it. Instead of referring to the caller, scopes - &lt;i&gt;this&lt;/i&gt; and &lt;i&gt;arguments&lt;/i&gt; would refer to the enclosing function scope.&lt;br /&gt;
&lt;br /&gt;
Consider this example:&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;divCF&quot;&gt;
var obj = {x: 1};
    
obj.getObjV1 = function () {
    console.log(this.x); //prints value of x
};
    
obj.getObjV2 = (() =&amp;gt; {
    console.log(this.x); //this is undefined
    console.log(arguments); //arguments that the parent function is called with
});
    
obj.getObjV1();
obj.getObjV2();
&lt;/div&gt;
Using the function expression you would notice that &lt;i&gt;this&lt;/i&gt; scope is available. However, inside the body of an arrow function &lt;i&gt;this&lt;/i&gt; scope is undefined and thus would result in an error.

An arrow function refers to enclosing function&#39;s &lt;i&gt;this&lt;/i&gt; and &lt;i&gt;arguments&lt;/i&gt; scope:&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;divCF&quot;&gt;
function Foo(x, y) {
    this.a = 1;

    setTimeout((x, y) =&amp;gt; {
        console.log(this.a); //referrence to this is available.
        console.log(arguments); //prints 10, 11
    })(5, 6);
};

var bar = new Foo(10, 11);
&lt;/div&gt;
&lt;br /&gt;
I would use arrow function expressions in callback functions where reference to &lt;i&gt;this&lt;/i&gt; scope is to be obtained from it&#39;s enclosing function scope. In may scenarios I would have written &lt;i&gt;var self = this;&lt;/i&gt; and use self to refer to &lt;i&gt;this&lt;/i&gt; scope inside the callback function. This was a hack and now it&#39;s no longer required.</content><link rel='replies' type='application/atom+xml' href='http://www.sagarganatra.com/feeds/2237852363806068108/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.sagarganatra.com/2016/02/learning-es6-arrow-functions-this-arguments-scopes.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8417810603086728638/posts/default/2237852363806068108'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8417810603086728638/posts/default/2237852363806068108'/><link rel='alternate' type='text/html' href='http://www.sagarganatra.com/2016/02/learning-es6-arrow-functions-this-arguments-scopes.html' title='Learning ES6 - Arrow functions and the visibility of this and arguments scope in it'/><author><name>Sagar Ganatra</name><uri>http://www.blogger.com/profile/15129859862786257527</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhoO56BqdUmSACmPZKwemvyzRtEm1xJVsPVudy1_Tc2U4vafHustJn0_oFtUkKVcz1oGe_p2woZN3j04yI3Sf_xsTrrlcdno6mLnN1Qz380TamkT3P919jIRjh1acuRGA/s220/Mypic.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8417810603086728638.post-5173386192952516937</id><published>2016-02-11T19:21:00.001+05:30</published><updated>2016-02-12T23:55:49.462+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="ES6"/><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript/jQuery"/><title type='text'>Learning ES6 - using let, const and Temporal Dead Zone</title><content type='html'>I&#39;ve finally started to learn EcmaScript 6 (ES2015) and thought it would be good to start writing about it as I learn. There are a bunch of features in ES6 and a good place to start would be to learn the use of &lt;i&gt;let&lt;/i&gt; and &lt;i&gt;const&lt;/i&gt;. I haven&#39;t deep dived into all the features yet, but I eventually will. This post is about the use of &lt;i&gt;let&lt;/i&gt; and &lt;i&gt;const&lt;/i&gt; keywords to create variables. I&#39;m a big fan &lt;i&gt;var&lt;/i&gt; scope, but I think I&#39;m going to abdicate &lt;i&gt;var&lt;/i&gt; scoped variables in favor of &lt;i&gt;let&lt;/i&gt; and &lt;i&gt;const&lt;/i&gt;.&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
The primary difference between &lt;i&gt;var&lt;/i&gt; and &lt;i&gt;let&lt;/i&gt; scoped variables is it&#39;s visibility. A &lt;i&gt;var&lt;/i&gt; scoped variable is visible throughout the function where as &lt;i&gt;let&lt;/i&gt; scoped variable is visible only inside the block in which it is declared. Thinking about block scope now, I realize that many times I write if statements and declare variables as required. With &lt;i&gt;var&lt;/i&gt; scope, the variable would be visible throughout the function where as with &lt;i&gt;let&lt;/i&gt; scope, the visibility is limited to the block in which it&#39;s declared:&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/sagar-ganatra/d9c7cb78629b7cadfbe5.js&quot;&gt;&lt;/script&gt;

&lt;br /&gt;
A &lt;i&gt;let&lt;/i&gt; scoped variable is visible in the block in which it&#39;s declared and also in child blocks, unless the same named variable is declared in the child block as well. In this example, the variable &#39;&lt;i&gt;a&lt;/i&gt;&#39; (with value 10) is visible throughout the function but not inside function &lt;i&gt;test&lt;/i&gt;. Inside function &lt;i&gt;test&lt;/i&gt;, a variable with the same name is &lt;i&gt;let&lt;/i&gt; scoped, thus overriding the visibility of variable &#39;&lt;i&gt;a&lt;/i&gt;&#39; at the parent function level. Notice that the &lt;i&gt;let&lt;/i&gt; scoped variables are visible only in the block in which they are declared. The variables declared in the inner blocks will cease to exist once the execution crosses the block.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;On Temporal Dead Zone (TDZ):&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Variables declared with &lt;i&gt;var&lt;/i&gt; scope are hoisted and return undefined when one tries to access it before it&#39;s definition. In case of &lt;i&gt;let&lt;/i&gt; scoped variables, a &lt;i&gt;ReferenceError&lt;/i&gt; is thrown. Although, this infers that the &lt;i&gt;let&lt;/i&gt; scoped variables are not hoisted but they are indeed hoisted. See the note here:&amp;nbsp;&lt;a href=&quot;https://people.mozilla.org/~jorendorff/es6-draft.html#sec-let-and-const-declarations&quot;&gt;https://people.mozilla.org/~jorendorff/es6-draft.html#sec-let-and-const-declarations&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
It mentions that:&lt;br /&gt;
&lt;br /&gt;
&quot;The variables are created when their containing Lexical Environment is instantiated but may not be accessed in any way until the variable’s LexicalBinding is evaluated.&quot;&lt;br /&gt;
&lt;br /&gt;
From the above statement, a &lt;i&gt;let&lt;/i&gt; scoped variable is instantiated meaning that the variable is hoisted but it&#39;s not available until a value is assigned to it. Another example, would be:&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;divCF&quot;&gt;
let a = b, b = 1;&lt;/div&gt;
&lt;br /&gt;
Again a &lt;i&gt;ReferenceError&lt;/i&gt; is thrown mentioning that &#39;&lt;i&gt;b is not defined&lt;/i&gt;&#39;. The Temporal Dead Zone starts when the block containing the &lt;i&gt;let&lt;/i&gt; scoped variable is encountered and it ends when the definition of the variable is found. In TDZ, the variables would throw a &lt;i&gt;ReferenceError&lt;/i&gt; even if the same variable is present in it&#39;s enclosing block i.e. the parent block.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;On const:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
A &lt;i&gt;const&lt;/i&gt; scoped variable is similar to a &lt;i&gt;let&lt;/i&gt; scoped variable except that it mandates a value to be assigned to it. Any attempt made to change the value of the variable would result in an error. For example, when you use a &lt;i&gt;const&lt;/i&gt; variable in a for loop, an error is thrown when you try to increment the value:&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;divCF&quot;&gt;
for (const i=0; i &amp;lt; 3; i++) {
&amp;nbsp; &amp;nbsp; &amp;nbsp;console.log(i);
}&lt;/div&gt;
&lt;br /&gt;
One of the pitfalls I have observed with &lt;i&gt;const&lt;/i&gt; scoped variables is that the value that it is bound to is not a constant:&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;divCF&quot;&gt;
const a = {x: 1};
a.y = 2; //valid 

const b = [1, 2, 3];
b.push(4); //valid&lt;/div&gt;
&lt;br /&gt;
I&#39;m not sure whether this is the right thing for constants. Although, one can make it non-writeable by using Object.freeze.&lt;br /&gt;
&lt;br /&gt;
Going forward, I would use &lt;i&gt;const&lt;/i&gt; for constant variables and for functions which are &lt;i&gt;var&lt;/i&gt; scoped by default. Also, &lt;i&gt;let&lt;/i&gt; seems to be a good choice over &lt;i&gt;var&lt;/i&gt; for scoping variables.</content><link rel='replies' type='application/atom+xml' href='http://www.sagarganatra.com/feeds/5173386192952516937/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.sagarganatra.com/2016/02/learning-es6-let-const-temporal-dead-zone.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8417810603086728638/posts/default/5173386192952516937'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8417810603086728638/posts/default/5173386192952516937'/><link rel='alternate' type='text/html' href='http://www.sagarganatra.com/2016/02/learning-es6-let-const-temporal-dead-zone.html' title='Learning ES6 - using let, const and Temporal Dead Zone'/><author><name>Sagar Ganatra</name><uri>http://www.blogger.com/profile/15129859862786257527</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhoO56BqdUmSACmPZKwemvyzRtEm1xJVsPVudy1_Tc2U4vafHustJn0_oFtUkKVcz1oGe_p2woZN3j04yI3Sf_xsTrrlcdno6mLnN1Qz380TamkT3P919jIRjh1acuRGA/s220/Mypic.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8417810603086728638.post-5766026085854962651</id><published>2015-07-01T17:57:00.000+05:30</published><updated>2015-07-01T17:57:00.706+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="AngularJS"/><category scheme="http://www.blogger.com/atom/ns#" term="CSS"/><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript/jQuery"/><category scheme="http://www.blogger.com/atom/ns#" term="Material Design"/><title type='text'>On choosing Material Design for Angular over UI Bootstrap</title><content type='html'>There are many UI frameworks out there - Bootstrap, Foundation, Semantic UI etc. I have used Bootstrap in the past, however I&#39;m very much inclined towards using Material Design for Angular. There are many good reasons to use Material Design over Bootstrap or any other framework that you might consider.&lt;br /&gt;
&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;When I say Material Design, I&#39;m referring to Material Design for Angular - &lt;a href=&quot;https://material.angularjs.org/&quot;&gt;https://material.angularjs.org/&lt;/a&gt;. I have been using Angular in my applications and I&#39;ve made that as a defacto framework to use for any front-end work I get. I don&#39;t consider any library to use in my project unless it also has an Angular implementation. Material Design for Angular and UI bootstrap, both are such libraries. So why choose Material Design over Bootstrap? I did search for this and couldn&#39;t see the comparison in terms of pros and cons or why one framework is more suited over the other. Thus, I&#39;m jotting down my thoughts on why Material Design wins over Bootstrap.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;User Experience&lt;/b&gt;:&lt;br /&gt;
&lt;br /&gt;
Material Design delivers the wow effect; the click of a button, or selecting a checkbox, entering form details and everything else in the specification delivers great user experience. Bootstrap on the other hand is good if you are building very simple applications that look like they are made only to deliver the functionality and great user experience is not of high priority.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;FlexBox:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
CSS3 introduced FlexBox, which allows you to create layouts with ease. Even if I&#39;m not inclined towards great user experience, I would chose Material Design for this feature only. Bootstrap uses floats for its grid system. I hate floats; floats were designed to wrap text around images. Floats come with a clear fix and adding more mark up or CSS for clear fix is like carrying extra luggage. Using display: inline-block is another alternative, but it expects you to write the markup in a certain way or add margin-left: -4px.&lt;br /&gt;
&lt;br /&gt;
FlexBox should be used instead of floats or inline-blocks. I can&#39;t imagine writing my applications using anything other than FlexBox.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Syntax:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Material design provides several directives for managing layout, creating drop downs, form fields etc. The syntax used here is more semantic. Consider this code snippet:&lt;br /&gt;
&lt;br /&gt;
&lt;!-- HTML generated using hilite.me --&gt;&lt;br /&gt;
&lt;div style=&quot;background: #f8f8f8; border-width: .1em .1em .1em .1em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;&quot;&gt;
&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;&lt;span style=&quot;color: #204a87; font-weight: bold;&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span style=&quot;color: #c4a000;&quot;&gt;layout=&lt;/span&gt;&lt;span style=&quot;color: #4e9a06;&quot;&gt;&quot;row&quot;&lt;/span&gt;
     &lt;span style=&quot;color: #c4a000;&quot;&gt;layout-align=&lt;/span&gt;&lt;span style=&quot;color: #4e9a06;&quot;&gt;&quot;center center&quot;&lt;/span&gt;&lt;span style=&quot;color: #204a87; font-weight: bold;&quot;&gt;&amp;gt;&lt;/span&gt;

   &lt;span style=&quot;color: #204a87; font-weight: bold;&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span style=&quot;color: #c4a000;&quot;&gt;flex&lt;/span&gt;&lt;span style=&quot;color: #204a87; font-weight: bold;&quot;&gt;&amp;gt;&lt;/span&gt;
   &lt;span style=&quot;color: #204a87; font-weight: bold;&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span style=&quot;color: #c4a000;&quot;&gt;flex&lt;/span&gt;&lt;span style=&quot;color: #204a87; font-weight: bold;&quot;&gt;&amp;gt;&lt;/span&gt;
   &lt;span style=&quot;color: #204a87; font-weight: bold;&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span style=&quot;color: #c4a000;&quot;&gt;flex&lt;/span&gt;&lt;span style=&quot;color: #204a87; font-weight: bold;&quot;&gt;&amp;gt;&lt;/span&gt;
 
&lt;span style=&quot;color: #204a87; font-weight: bold;&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
The above code snippet declares that you are creating a row and it has three elements with attribute &#39;flex&#39; added to it. This will create a three column equal width layout. Please note, there&#39;s no extra CSS or class added to this. The markup is clean and who doesn&#39;t like clean markup.&lt;br /&gt;
&lt;br /&gt;
In case of Bootstrap one will have to add classes to build the layout, I wouldn&#39;t like to copy the code and paste it, you can see it for yourself here -&lt;a href=&quot;http://getbootstrap.com/css/#grid&quot; target=&quot;_blank&quot;&gt;&amp;nbsp;http://getbootstrap.com/css/#grid&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Responsive:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Whilst both Material Design and Bootstrap provide you the ways to create responsive layouts, I prefer using Material Design. You only have to add certain attributes to the markup to change how it looks on different devices. For instance the above row based layout can be converted to a column based layout for a mobile device by adding layout-sm attribute:&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;background: #f8f8f8; border-width: .1em .1em .1em .1em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;&quot;&gt;
&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;&lt;span style=&quot;color: #204a87; font-weight: bold;&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span style=&quot;color: #c4a000;&quot;&gt;layout=&lt;/span&gt;&lt;span style=&quot;color: #4e9a06;&quot;&gt;&quot;row&quot;&lt;/span&gt;
     &lt;span style=&quot;color: #c4a000;&quot;&gt;layout-align=&lt;/span&gt;&lt;span style=&quot;color: #4e9a06;&quot;&gt;&quot;center center&quot;&lt;/span&gt;
     &lt;span style=&quot;color: #c4a000;&quot;&gt;layout-sm=&lt;/span&gt;&lt;span style=&quot;color: #4e9a06;&quot;&gt;&quot;column&quot;&lt;/span&gt;&lt;span style=&quot;color: #204a87; font-weight: bold;&quot;&gt;&amp;gt;&lt;/span&gt;
 
&lt;span style=&quot;color: #204a87; font-weight: bold;&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
Bootstrap uses classes instead.&lt;br /&gt;
&lt;br /&gt;
Many would rather complain saying that Bootstrap is widely used and Material Design is not. That&#39;s true, because Material Design is new and you can&#39;t expect every Bootstrap website to be converted to Material Design in no time. The other reason that I&#39;ve heard on not using Material Design is that one will have to learn it before becoming productive and it involves a big learning curve. I&#39;m of the opinion that this is not true, it didn&#39;t even take me a day to get started with Material Design. Also, if you take a look at the syntax it&#39;s almost the same except that you would use directives instead of classes in Material Design.&lt;br /&gt;
&lt;br /&gt;
When choosing a technology or a framework, there&#39;s no right or wrong. There are opinions and perspectives. As a developer you should have the freedom to chose what you like. However, I would advise that don&#39;t be afraid to try out something new. Don&#39;t constraint yourself to one library; it&#39;s always fun and a good learning experience when trying out different libraries.</content><link rel='replies' type='application/atom+xml' href='http://www.sagarganatra.com/feeds/5766026085854962651/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.sagarganatra.com/2015/07/on-choosing-material-design-for-angular.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8417810603086728638/posts/default/5766026085854962651'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8417810603086728638/posts/default/5766026085854962651'/><link rel='alternate' type='text/html' href='http://www.sagarganatra.com/2015/07/on-choosing-material-design-for-angular.html' title='On choosing Material Design for Angular over UI Bootstrap'/><author><name>Sagar Ganatra</name><uri>http://www.blogger.com/profile/15129859862786257527</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhoO56BqdUmSACmPZKwemvyzRtEm1xJVsPVudy1_Tc2U4vafHustJn0_oFtUkKVcz1oGe_p2woZN3j04yI3Sf_xsTrrlcdno6mLnN1Qz380TamkT3P919jIRjh1acuRGA/s220/Mypic.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8417810603086728638.post-12024981460759855</id><published>2015-05-28T16:02:00.000+05:30</published><updated>2015-05-28T16:02:17.574+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="AngularJS"/><category scheme="http://www.blogger.com/atom/ns#" term="Design Patterns"/><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript/jQuery"/><category scheme="http://www.blogger.com/atom/ns#" term="RequireJS"/><title type='text'>Improvising Angular + Require template</title><content type='html'>Sometime back I wrote a post on using &lt;a href=&quot;http://www.sagarganatra.com/2015/03/angular-require-project-template.html&quot; target=&quot;_blank&quot;&gt;&lt;i&gt;&lt;span id=&quot;goog_456106791&quot;&gt;&lt;/span&gt;Angular and Require to create a project template&lt;/i&gt;&lt;span id=&quot;goog_456106792&quot;&gt;&lt;/span&gt;&lt;/a&gt;. The idea was to make the application more modular and broken down into multiple components that can be easily reused. I have made some more modifications to the template, especially the naming conventions used for files and minor changes to the structure of the project.&lt;br /&gt;
&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;Here&#39;s the snapshot of the directory structure:&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;background: #ffffff; border-width: .1em .1em .1em .1em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;&quot;&gt;
&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;/&lt;/span&gt;components
   &lt;span style=&quot;color: #333333;&quot;&gt;/&lt;/span&gt;login
      login&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;directive&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;js
      login&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;html
      login&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;module&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;js
      login&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;scss

&lt;span style=&quot;color: #333333;&quot;&gt;/&lt;/span&gt;domain
      domain&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;module&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;js
      Players&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;js
      User&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;js

&lt;span style=&quot;color: #333333;&quot;&gt;/&lt;/span&gt;services
      backendUrlsProvider&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;js
      common&lt;span style=&quot;color: #333333;&quot;&gt;-&lt;/span&gt;services&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;module&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;js
&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
The major change has been moving the stylesheets (&lt;i&gt;scss&lt;/i&gt; files) for the various components inside the &lt;i&gt;components&lt;/i&gt; directory and create &lt;i&gt;&amp;lt;component&amp;gt;.module.js&lt;/i&gt; file inside the same directory. I have removed the modules directory which listed all the module files for the application. This change enables reusing the component by copying one single directory instead of copying multiple directories (scripts and styles).&lt;br /&gt;
&lt;br /&gt;
The next change was to create a module for the models listed under &lt;i&gt;domain&lt;/i&gt; directory. These models were associated with components but that didn&#39;t encourage reusability. By having one domain module that lists all domain services, it can be used across the application. Also, the idea is to have components being agnostic of the services. The components are responsible for rendering the views and they delegate the responsibility of calling a service to the parent controllers which are listed under pages directory (see previous post).&lt;br /&gt;
&lt;br /&gt;
The services directory would contain a set of common services that can be used by components or services. I have added backendUrlsProvider.js file which is a constant service, providing a map between the service and the corresponding URLs:&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;background: #f8f8f8; border-width: .1em .1em .1em .1em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;&quot;&gt;
&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;&lt;span style=&quot;color: #204a87; font-weight: bold;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: black; font-weight: bold;&quot;&gt;{&lt;/span&gt;
    &lt;span style=&quot;color: black;&quot;&gt;login&lt;/span&gt;&lt;span style=&quot;color: black; font-weight: bold;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #4e9a06;&quot;&gt;&#39;/user/login&#39;&lt;/span&gt;&lt;span style=&quot;color: black; font-weight: bold;&quot;&gt;,&lt;/span&gt;
    &lt;span style=&quot;color: black;&quot;&gt;register&lt;/span&gt;&lt;span style=&quot;color: black; font-weight: bold;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #4e9a06;&quot;&gt;&#39;/user/register&#39;&lt;/span&gt;&lt;span style=&quot;color: black; font-weight: bold;&quot;&gt;,&lt;/span&gt;
    &lt;span style=&quot;color: black;&quot;&gt;players&lt;/span&gt;&lt;span style=&quot;color: black; font-weight: bold;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #4e9a06;&quot;&gt;&#39;/players&#39;&lt;/span&gt;
&lt;span style=&quot;color: black; font-weight: bold;&quot;&gt;};&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
If there&#39;s a change in the URL then it would be updated here and no changes would be required to be made in the services files.&lt;br /&gt;
&lt;br /&gt;
A new addition to the template is the use of the Gulp to generate the build. The build generation steps include: cleaning the dist directory, running jshint, compiling and minifying stylesheets, annotating Angular files using&amp;nbsp;@ngInject, minifying HTML files, minifying JavaScript files using r.js optimizer, adding a new revision, using html-replace to inject JavaScript files and CSS stylesheets, removing mock modules reference when a Production build is generated.&lt;br /&gt;
&lt;br /&gt;
Take a look at the code on Github:&amp;nbsp;&lt;a href=&quot;https://github.com/sagar-ganatra/angular-require-template&quot;&gt;&lt;i&gt;https://github.com/sagar-ganatra/angular-require-template&lt;/i&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.sagarganatra.com/feeds/12024981460759855/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.sagarganatra.com/2015/05/improvising-angular-require-template.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8417810603086728638/posts/default/12024981460759855'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8417810603086728638/posts/default/12024981460759855'/><link rel='alternate' type='text/html' href='http://www.sagarganatra.com/2015/05/improvising-angular-require-template.html' title='Improvising Angular + Require template'/><author><name>Sagar Ganatra</name><uri>http://www.blogger.com/profile/15129859862786257527</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhoO56BqdUmSACmPZKwemvyzRtEm1xJVsPVudy1_Tc2U4vafHustJn0_oFtUkKVcz1oGe_p2woZN3j04yI3Sf_xsTrrlcdno6mLnN1Qz380TamkT3P919jIRjh1acuRGA/s220/Mypic.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8417810603086728638.post-7076850302812836402</id><published>2015-03-24T18:44:00.003+05:30</published><updated>2015-03-24T18:44:36.450+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="AngularJS"/><category scheme="http://www.blogger.com/atom/ns#" term="Design Patterns"/><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript/jQuery"/><category scheme="http://www.blogger.com/atom/ns#" term="RequireJS"/><title type='text'>Angular + Require project template</title><content type='html'>I&#39;ve been working on an Angular project for good number months. There&#39;s a lot that I&#39;ve learned and I&#39;ve realized that the code I wrote could have been structured in a better way. I wanted to write this post sometime back, however I thought it would be better to create an application structure first and then post my learnings. I have posted all the code on github here -&amp;nbsp;&lt;a href=&quot;https://github.com/sagar-ganatra/angular-require-template&quot;&gt;https://github.com/sagar-ganatra/angular-require-template&lt;/a&gt;. The template is still a work in progress, however the basic structure of the template is in place.&lt;br /&gt;
&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
&lt;b&gt;Motivation:&lt;/b&gt;&lt;br /&gt;
I always visualized a web page broken down into multiple components that are completely decoupled and components that can be reused. For example, a component or a widget that displays a chart does not have to know about the navbar in the page. It would however provide an interface through which external components would interact or change the state of it.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Why RequireJS?&lt;/b&gt;&lt;br /&gt;
In my Angular application&#39;s index.html file, I had included various script blocks that looked like this:&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;background: #f8f8f8; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;&quot;&gt;
&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;&lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;script &lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;src=&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;../bower_components/jquery/jquery.js&quot;&lt;/span&gt;&lt;span style=&quot;color: #007700;&quot;&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;script &lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;src=&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;../bower_components/angular/angular.js&quot;&lt;/span&gt;&lt;span style=&quot;color: #007700;&quot;&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;script &lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;src=&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;../bower_components/angular-bootstrap/ui-bootstrap-tpls.js&quot;&lt;/span&gt;&lt;span style=&quot;color: #007700;&quot;&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;script &lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;src=&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;../bower_components/angular-cookies/angular-cookies.js&quot;&lt;/span&gt;&lt;span style=&quot;color: #007700;&quot;&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: #007700;&quot;&gt;&amp;lt;script &lt;/span&gt;&lt;span style=&quot;color: #0000cc;&quot;&gt;src=&lt;/span&gt;&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;../bower_components/angular-route/angular-route.js&quot;&lt;/span&gt;&lt;span style=&quot;color: #007700;&quot;&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
Here the script tags are included in such a way that the dependent files come first and then the others are listed. Every time I added a new script file in the project, I had to update the index.html file and ensure that the dependencies are always included first. Instead, I could use a RequireJS shim to declare the dependencies:&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;background: #f8f8f8; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;&quot;&gt;
&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;shim&lt;span style=&quot;color: #666666;&quot;&gt;:&lt;/span&gt; {
    angular&lt;span style=&quot;color: #666666;&quot;&gt;:&lt;/span&gt; {
        deps&lt;span style=&quot;color: #666666;&quot;&gt;:&lt;/span&gt; [&lt;span style=&quot;color: #ba2121;&quot;&gt;&#39;jquery&#39;&lt;/span&gt;],
        exports&lt;span style=&quot;color: #666666;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #ba2121;&quot;&gt;&#39;angular&#39;&lt;/span&gt;
    },
        
    angularMocks&lt;span style=&quot;color: #666666;&quot;&gt;:&lt;/span&gt; {
        deps&lt;span style=&quot;color: #666666;&quot;&gt;:&lt;/span&gt; [&lt;span style=&quot;color: #ba2121;&quot;&gt;&#39;angular&#39;&lt;/span&gt;]  
    },
        
    angularCookies&lt;span style=&quot;color: #666666;&quot;&gt;:&lt;/span&gt; {
        deps&lt;span style=&quot;color: #666666;&quot;&gt;:&lt;/span&gt; [&lt;span style=&quot;color: #ba2121;&quot;&gt;&#39;angular&#39;&lt;/span&gt;]
    },
        
    uirouter&lt;span style=&quot;color: #666666;&quot;&gt;:&lt;/span&gt; {
        deps&lt;span style=&quot;color: #666666;&quot;&gt;:&lt;/span&gt; [&lt;span style=&quot;color: #ba2121;&quot;&gt;&#39;angular&#39;&lt;/span&gt;]
    }
}
&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
This is more declarative and less prone to errors.&lt;br /&gt;
&lt;br /&gt;
This is not the only reason I would use RequireJS in my project, one of the other factors and the most important one is to provide structure to the application. I want my components to be independent or individual widgets that can be reused. When creating components I would make use of the directive interface which can then be included anywhere in the project. For example, the interface for a navbar could look like:&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;background: #f8f8f8; overflow: auto; padding: .2em .6em; width: auto;&quot;&gt;
&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;&lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;navbar&lt;/span&gt; &lt;span style=&quot;color: #7d9029;&quot;&gt;title=&lt;/span&gt;&lt;span style=&quot;color: #ba2121;&quot;&gt;&quot;{{title}}&quot;&lt;/span&gt;&lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;gt;&amp;lt;/navbar&amp;gt;&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
Here the &lt;i&gt;&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;navbar&lt;/span&gt;&lt;/i&gt; element has the &lt;i&gt;&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;title&lt;/span&gt;&lt;/i&gt; attribute which would then become a scope variable for the &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;navbar&lt;/span&gt; directive. Essentially everything on the page would be a collection of directives which would then be compiled and the resultant HTML markup would be injected into the DOM:&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgY6r7P4xTozeVpgfvXyT9b9NGuyFy_tZZp7Q4ArfviYKp6gzsExmkGMUxp1dXuVAEBgF1XFVOikWHMBfKs6SXAvGLzcl2rhM3km9WPwrdbsijw6ay4b3mELMXa29pfd8VTXvXCK0j00OeA/s1600/14271808121503.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgY6r7P4xTozeVpgfvXyT9b9NGuyFy_tZZp7Q4ArfviYKp6gzsExmkGMUxp1dXuVAEBgF1XFVOikWHMBfKs6SXAvGLzcl2rhM3km9WPwrdbsijw6ay4b3mELMXa29pfd8VTXvXCK0j00OeA/s1600/14271808121503.png&quot; height=&quot;320&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Here the directive serves as a gateway to the service that we are trying to add to the application. A directive is an individual widget which is not aware of other directives used in the page and it&#39;s service agnostic. Here in our example, the &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;playersList&lt;/span&gt; directive would consume list of players and perform some action when a player is selected. The directive would provide an interface and the page that wants to use the directive can then provide the data:&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;background: #f8f8f8; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;&quot;&gt;
&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;&lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span style=&quot;color: #7d9029;&quot;&gt;players-list&lt;/span&gt;
     &lt;span style=&quot;color: #7d9029;&quot;&gt;players=&lt;/span&gt;&lt;span style=&quot;color: #ba2121;&quot;&gt;&quot;players&quot;&lt;/span&gt;
     &lt;span style=&quot;color: #7d9029;&quot;&gt;on-player-select=&lt;/span&gt;&lt;span style=&quot;color: #ba2121;&quot;&gt;&quot;showPlayerStats(playerId)&quot;&lt;/span&gt;
     &lt;span style=&quot;color: #7d9029;&quot;&gt;selected-player=&lt;/span&gt;&lt;span style=&quot;color: #ba2121;&quot;&gt;&quot;selectedPlayerId&quot;&lt;/span&gt;&lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
Here the values provided to various attributes are defined in the controller scope. In this way, the directive remains agnostic of the data or the service that it should talk to.&lt;br /&gt;
&lt;br /&gt;
In my project template, I&#39;ve create a module for each directive. In this example, we would have two modules - &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;navbarModule&lt;/span&gt;, &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;playersStatsModule&lt;/span&gt;. I would include playersList and playerDetails directive into one single module because they serve as one entity. However, they are completely decoupled and don&#39;t interact with each other directly. The idea is to create modules that represent one single entity, which in this case is &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;playerStats&lt;/span&gt;. The module definition would look like this:&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;background: #f8f8f8; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;&quot;&gt;
&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;define([
    &lt;span style=&quot;color: #ba2121;&quot;&gt;&#39;angular&#39;&lt;/span&gt;,
    &lt;span style=&quot;color: #ba2121;&quot;&gt;&#39;components/playerStats/directives/playersListDirective&#39;&lt;/span&gt;,
    &lt;span style=&quot;color: #ba2121;&quot;&gt;&#39;components/playerStats/directives/playersDetailDirective&#39;&lt;/span&gt;,
    &lt;span style=&quot;color: #ba2121;&quot;&gt;&#39;domain/Players&#39;&lt;/span&gt;
],  &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;function&lt;/span&gt;(ng, playersListDirective, playersDetailDirective, Players) {
        &lt;span style=&quot;color: #ba2121;&quot;&gt;&#39;use strict&#39;&lt;/span&gt;;
        
        &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;return&lt;/span&gt; ng.module(&lt;span style=&quot;color: #ba2121;&quot;&gt;&#39;playerStatsModule&#39;&lt;/span&gt;, [])
                 .directive(&lt;span style=&quot;color: #ba2121;&quot;&gt;&#39;playersList&#39;&lt;/span&gt;, playersListDirective)
                 .directive(&lt;span style=&quot;color: #ba2121;&quot;&gt;&#39;playersDetail&#39;&lt;/span&gt;, playersDetailDirective) 
                 .service(&lt;span style=&quot;color: #ba2121;&quot;&gt;&#39;Players&#39;&lt;/span&gt;, Players);
                 
    }
);
&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
Notice that there&#39;s one file &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;playerStatsModule.js&lt;/span&gt; which declares dependency on the directives and the service. Also, the name is to the directive here in the module definition. This approach is the flip side of the approach that is generally followed when defining directives. Generally one would create a module first and then use the module reference in their directive definition; but the approach that I mentioned above makes the code more cleaner. Here&#39;s how the definition of the &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;playersList&lt;/span&gt; directive would look like:&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;background: #f8f8f8; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;&quot;&gt;
&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;define(&lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;function&lt;/span&gt;() {
    &lt;span style=&quot;color: #ba2121;&quot;&gt;&#39;use strict&#39;&lt;/span&gt;;
    
    &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;function&lt;/span&gt; () {
        &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;return&lt;/span&gt; {
            restrict&lt;span style=&quot;color: #666666;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #ba2121;&quot;&gt;&#39;AE&#39;&lt;/span&gt;,
            templateUrl&lt;span style=&quot;color: #666666;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #ba2121;&quot;&gt;&#39;./components/playerStats/partials/playersList.html&#39;&lt;/span&gt;,
            scope&lt;span style=&quot;color: #666666;&quot;&gt;:&lt;/span&gt; {
                onPlayerSelect&lt;span style=&quot;color: #666666;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #ba2121;&quot;&gt;&#39;&amp;amp;&#39;&lt;/span&gt;,
                players&lt;span style=&quot;color: #666666;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #ba2121;&quot;&gt;&#39;=&#39;&lt;/span&gt;,
                selectedPlayer&lt;span style=&quot;color: #666666;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #ba2121;&quot;&gt;&#39;=&#39;&lt;/span&gt;
            }
        };
    };
});
&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
It returns a function and then in the module a name is assigned to the directive.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Application structure:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;background: #f8f8f8; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;&quot;&gt;
&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;/app&lt;/pre&gt;
&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;  - app.js&lt;/pre&gt;
&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;  - main.js&lt;/pre&gt;
&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;  - bootstrap.js&lt;/pre&gt;
&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;  - index.html
  /components
      /auth
      /login
      /navbar
      /playerStats
           /directives
                - playersDetailsDirective.js
                - playersListDirective.js
           /partials
                - playersDetails.html
                - playersList.html
  /domain
       -  Players.js
       -  User.js
  /modules
        - authModule.js
        - loginModule.js
        - navbarModule.js
        - pagesModule.js
        - playerStatsModule.js
  /pages
      /home
          /controllers
               - playersListController.js
               - playersStatsController.js
          /partials
               - playersList.html
               - playersStats.html
      /login
&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
Notice that the services responsible for sending requests to the server are listed under domain. The pages directory lists various pages in the application and the partials listed under each page contain references to these components. In this way, pages handle the application logic (events, querying the service, etc) and individual component directives handle rendering logic.&lt;br /&gt;
&lt;br /&gt;
In &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;app.js&lt;/span&gt;, a module for the application is created. This module will declare dependency on various other modules in the source code in addition to third party modules:&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;background: #f8f8f8; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;&quot;&gt;
&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;define([
    &lt;span style=&quot;color: #ba2121;&quot;&gt;&#39;angular&#39;&lt;/span&gt;,
    &lt;span style=&quot;color: #408080; font-style: italic;&quot;&gt;/*mock module*/&lt;/span&gt;
    &lt;span style=&quot;color: #ba2121;&quot;&gt;&#39;mockModule&#39;&lt;/span&gt;,
    &lt;span style=&quot;color: #ba2121;&quot;&gt;&#39;mockServices&#39;&lt;/span&gt;,
    &lt;span style=&quot;color: #408080; font-style: italic;&quot;&gt;/* user defined modules */&lt;/span&gt;
    &lt;span style=&quot;color: #ba2121;&quot;&gt;&#39;modules/authModule&#39;&lt;/span&gt;,
    &lt;span style=&quot;color: #ba2121;&quot;&gt;&#39;modules/loginModule&#39;&lt;/span&gt;,
    &lt;span style=&quot;color: #ba2121;&quot;&gt;&#39;modules/navbarModule&#39;&lt;/span&gt;,
    &lt;span style=&quot;color: #ba2121;&quot;&gt;&#39;modules/playerStatsModule&#39;&lt;/span&gt;,
    &lt;span style=&quot;color: #408080; font-style: italic;&quot;&gt;/* pages module */&lt;/span&gt;
    &lt;span style=&quot;color: #ba2121;&quot;&gt;&#39;modules/pagesModule&#39;&lt;/span&gt;,
    &lt;span style=&quot;color: #408080; font-style: italic;&quot;&gt;/* include vendor dependencies here */&lt;/span&gt;
    &lt;span style=&quot;color: #ba2121;&quot;&gt;&#39;angularCookies&#39;&lt;/span&gt;,
    &lt;span style=&quot;color: #ba2121;&quot;&gt;&#39;angularMessages&#39;&lt;/span&gt;,
    &lt;span style=&quot;color: #ba2121;&quot;&gt;&#39;uirouter&#39;&lt;/span&gt;,
    &lt;span style=&quot;color: #ba2121;&quot;&gt;&#39;lumx&#39;&lt;/span&gt;,
], &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;function&lt;/span&gt; (ng) {
    &lt;span style=&quot;color: #ba2121;&quot;&gt;&#39;use strict&#39;&lt;/span&gt;;
    
    &lt;span style=&quot;color: green; font-weight: bold;&quot;&gt;var&lt;/span&gt; app &lt;span style=&quot;color: #666666;&quot;&gt;=&lt;/span&gt; ng.module(&lt;span style=&quot;color: #ba2121;&quot;&gt;&#39;playersApp&#39;&lt;/span&gt;, [
        &lt;span style=&quot;color: #ba2121;&quot;&gt;&#39;ngCookies&#39;&lt;/span&gt;,
        &lt;span style=&quot;color: #ba2121;&quot;&gt;&#39;ui.router&#39;&lt;/span&gt;,
        &lt;span style=&quot;color: #ba2121;&quot;&gt;&#39;lumx&#39;&lt;/span&gt;,
        &lt;span style=&quot;color: #ba2121;&quot;&gt;&#39;mockModule&#39;&lt;/span&gt;,
        &lt;span style=&quot;color: #ba2121;&quot;&gt;&#39;authModule&#39;&lt;/span&gt;,
        &lt;span style=&quot;color: #ba2121;&quot;&gt;&#39;loginModule&#39;&lt;/span&gt;,
        &lt;span style=&quot;color: #ba2121;&quot;&gt;&#39;navbarModule&#39;&lt;/span&gt;,
        &lt;span style=&quot;color: #ba2121;&quot;&gt;&#39;playerStatsModule&#39;&lt;/span&gt;,
        &lt;span style=&quot;color: #ba2121;&quot;&gt;&#39;pagesModule&#39;&lt;/span&gt;
    ]);
});
&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
The &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;main.js&lt;/span&gt; file declares the shim configuration (mentioned before) and &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;bootstrap.js&lt;/span&gt; would bootstrap the application by calling &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;angular.bootstrap&lt;/span&gt; on the document object.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Other Goodies:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
I&#39;m taking help from lumx to implement Material design, Angular UI router to define states/routes in the application, Angular Mocks to mock services and Gulp for build.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Pending:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Unit testing using Jasmine and Karma.&lt;br /&gt;
Structure styles (CSS/SCSS).&lt;br /&gt;
Refine Gulp build system.&lt;br /&gt;
CI/travis.yaml&lt;br /&gt;
&lt;br /&gt;
You can clone the repository and see how the application is structured and how it is currently styled.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.sagarganatra.com/feeds/7076850302812836402/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.sagarganatra.com/2015/03/angular-require-project-template.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8417810603086728638/posts/default/7076850302812836402'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8417810603086728638/posts/default/7076850302812836402'/><link rel='alternate' type='text/html' href='http://www.sagarganatra.com/2015/03/angular-require-project-template.html' title='Angular + Require project template'/><author><name>Sagar Ganatra</name><uri>http://www.blogger.com/profile/15129859862786257527</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhoO56BqdUmSACmPZKwemvyzRtEm1xJVsPVudy1_Tc2U4vafHustJn0_oFtUkKVcz1oGe_p2woZN3j04yI3Sf_xsTrrlcdno6mLnN1Qz380TamkT3P919jIRjh1acuRGA/s220/Mypic.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgY6r7P4xTozeVpgfvXyT9b9NGuyFy_tZZp7Q4ArfviYKp6gzsExmkGMUxp1dXuVAEBgF1XFVOikWHMBfKs6SXAvGLzcl2rhM3km9WPwrdbsijw6ay4b3mELMXa29pfd8VTXvXCK0j00OeA/s72-c/14271808121503.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8417810603086728638.post-3184948830765113992</id><published>2014-08-19T15:36:00.000+05:30</published><updated>2014-08-19T15:36:02.161+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="AngularJS"/><category scheme="http://www.blogger.com/atom/ns#" term="Design Patterns"/><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript/jQuery"/><category scheme="http://www.blogger.com/atom/ns#" term="RequireJS"/><title type='text'>Lazy loading AngularJS components using Providers</title><content type='html'>I&#39;ve been working on an Angular project for sometime now and I usually run across issues when building the application. In most of the example applications that I&#39;ve seen, all application script files are loaded upfront i.e. all JavaScript files are loaded when the user accesses application. I get annoyed by this approach; why should all the components be loaded upfront when the probability of user accessing the entire application is very less. How does one architect a multi-page application using Angular? What would be the size of the application after minifying all the JavaScript files. Most importantly how does one load the components lazily. I&#39;ve used RequireJS in my previous projects and it allows you to load components on demand; the idea is to load components based on the selected route. I&#39;ve tried a similar approach with Angular using &#39;&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;resolve&lt;/span&gt;&#39; property in the &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;$routeProvider&lt;/span&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;The &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&#39;resolve&#39;&lt;/span&gt; property in Angular can be used to resolve services but essentially it&#39;s a promise object that gets resolved. In my previous post, I&#39;ve explained how the &lt;a href=&quot;http://www.sagarganatra.com/2014/06/angularjs-resolving-data-services.html&quot; target=&quot;_blank&quot;&gt;resolve property is used to invoke a route only after resolving a $http service&lt;/a&gt;. Similarly, you can load the controller and service components (JavaScript files) before invoking the route. In this example, I&#39;ve used RequireJS to load the controller and service components:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/sagar-ganatra/0368945ab947f35c373b.js&quot;&gt;&lt;/script&gt;

In the above code snippet, files &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&#39;components/login/controllers/loginController&#39;&lt;/span&gt; and &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&#39;components/login/services/loginService&#39;&lt;/span&gt; are loaded using RequireJS. Once these files are loaded, the &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;$rootScope.$apply&lt;/span&gt; function is called and the promise object is resolved in the callback handler. Although this seemed like a direct approach to resolving dependencies, Angular throws an error when you access the route. It throws &#39;function got undefined&#39; error. The reason to this is, when Angular initializes or bootstraps the application, functions - controller, service etc,. are available on the module instance. Here, we are lazy loading the components and the functions are not available at a later point; therefore we must use the various provider functions and register these components. The providers are available only in the config method and hence we will have to store a reference of these providers in the config function when the application is initialized:
&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/sagar-ganatra/2fee6afecccca7ffe0ee.js&quot;&gt;&lt;/script&gt;

Here a reference to the &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;$controllerProvider.register&lt;/span&gt; and &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;$provide.service&lt;/span&gt; are stored in the &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&#39;app.components&#39;&lt;/span&gt; object. Now when you create components, these reference variables should be used. For example, to create a &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&#39;loginController&#39;&lt;/span&gt; component, the function signature would be:&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;app.components.controller(&#39;loginController&#39;);

&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
At run-time the components are registered by Angular using the various provider services. Next step in refining this example is to use modules in r.js (RequireJS optimizer) to create single JavaScript files that define all the dependencies for the page.&lt;br /&gt;
&lt;br /&gt;
Take a look at this git repo which contains two pages and components are loaded on demand -&lt;a href=&quot;https://github.com/sagar-ganatra/angular-require-resolve/&quot; target=&quot;_blank&quot;&gt;&amp;nbsp;https://github.com/sagar-ganatra/angular-require-resolve/&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.sagarganatra.com/feeds/3184948830765113992/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.sagarganatra.com/2014/08/lazy-loading-angularjs-components-using-providers.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8417810603086728638/posts/default/3184948830765113992'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8417810603086728638/posts/default/3184948830765113992'/><link rel='alternate' type='text/html' href='http://www.sagarganatra.com/2014/08/lazy-loading-angularjs-components-using-providers.html' title='Lazy loading AngularJS components using Providers'/><author><name>Sagar Ganatra</name><uri>http://www.blogger.com/profile/15129859862786257527</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhoO56BqdUmSACmPZKwemvyzRtEm1xJVsPVudy1_Tc2U4vafHustJn0_oFtUkKVcz1oGe_p2woZN3j04yI3Sf_xsTrrlcdno6mLnN1Qz380TamkT3P919jIRjh1acuRGA/s220/Mypic.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8417810603086728638.post-7466721153673364979</id><published>2014-06-30T18:19:00.000+05:30</published><updated>2014-06-30T18:19:07.841+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="AngularJS"/><category scheme="http://www.blogger.com/atom/ns#" term="Design Patterns"/><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript/jQuery"/><category scheme="http://www.blogger.com/atom/ns#" term="REST"/><title type='text'>AngularJS - Resolving data services before instantiating the Controller and Template</title><content type='html'>I have been working on an Angular application for sometime now and I have started to like this approach to client-side development. It&#39;s a different approach when compared to developing applications using Backbone and Require. I was looking at routing in Angular and came across the &#39;resolve&#39; property which can be used to resolve services before instantiating the Controller and it&#39;s corresponding template i.e. the domain models that are required for the View components are resolved first.&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
Look at a scenario where you are using a Search service to get a collection of objects that contain the search string. You can specify the route which will display the search results. When only the &lt;i&gt;&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;template &lt;/span&gt;&lt;/i&gt;and &lt;i&gt;&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;controller&lt;/span&gt; &lt;/i&gt;properties are specified, both are instantiated and the ng-view is updated with the specified template. The&amp;nbsp;&lt;i&gt;&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;controller&lt;/span&gt;&amp;nbsp; &lt;/i&gt;would specify&amp;nbsp;&lt;span style=&quot;font-family: inherit;&quot;&gt;dependency on the&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;SearchService,&lt;/span&gt;use this service to query the back-end and then update one of the $scope variables with the response data.&lt;br /&gt;
&lt;br /&gt;
While the &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;SearchService &lt;/span&gt;is fetching results, you would see that the template being displayed inside the ng-view container with template variables and the same getting updated when the service returns data. This is not ideal; the search results should be available before you load the &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;controller;&lt;/span&gt;&amp;nbsp;and the template should display data instead of showing template variables. The &#39;&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;resolve&lt;/span&gt;&#39; property in the &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;$routeProvider&lt;/span&gt; mentions a set of promises that should be resolved before instantiating the &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;controller &lt;/span&gt;and the &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;template&lt;/span&gt;.

Only when all the promises are resolved, the &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;controller &lt;/span&gt;and the &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;template &lt;/span&gt;are instantiated. Also the promise reference is injected into the &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;controller &lt;/span&gt;as a dependency. Using this promise one can directly update the values in the &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;template &lt;/span&gt;instead of sending a request to the Search service.&lt;br /&gt;
&lt;br /&gt;
Here&#39;s the code for the routeProvider :&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;http://gist-it.appspot.com/github/sagar-ganatra/angular-route-resolve/blob/master/js/app.js&quot;&gt;&lt;/script&gt;
Here the route &#39;/search/:searchString&#39;, specifies the &#39;resolve&#39; object which includes a promise - &#39;searchResults&#39;. It queries the searchService and returns a promise. When the service is resolved the Controller - &#39;searchController&#39; and the template - &#39;partials/search.html&#39; are instantiated. The Controller gets the promise object:&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;http://gist-it.appspot.com/github/sagar-ganatra/angular-route-resolve/blob/master/js/searchController.js&quot;&gt;&lt;/script&gt;
Notice that the promise - &#39;searchResults&#39; is injected into the Controller and it contains the response data. This can then be used to render the template.

</content><link rel='replies' type='application/atom+xml' href='http://www.sagarganatra.com/feeds/7466721153673364979/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.sagarganatra.com/2014/06/angularjs-resolving-data-services.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8417810603086728638/posts/default/7466721153673364979'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8417810603086728638/posts/default/7466721153673364979'/><link rel='alternate' type='text/html' href='http://www.sagarganatra.com/2014/06/angularjs-resolving-data-services.html' title='AngularJS - Resolving data services before instantiating the Controller and Template'/><author><name>Sagar Ganatra</name><uri>http://www.blogger.com/profile/15129859862786257527</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhoO56BqdUmSACmPZKwemvyzRtEm1xJVsPVudy1_Tc2U4vafHustJn0_oFtUkKVcz1oGe_p2woZN3j04yI3Sf_xsTrrlcdno6mLnN1Qz380TamkT3P919jIRjh1acuRGA/s220/Mypic.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8417810603086728638.post-1457213645453310855</id><published>2014-06-29T12:36:00.000+05:30</published><updated>2014-06-29T12:36:31.876+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="Announcements"/><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript/jQuery"/><category scheme="http://www.blogger.com/atom/ns#" term="Kendo UI"/><title type='text'>My second book - &#39;Kendo UI Cookbook&#39; released!!</title><content type='html'>&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEigJP_5JD29iNuRw8JAI41Q9xpTVIXT-BmgOGCMW9-xHoHP9XTDNUYOzCf9r9bsPUzpt195AmWyAg_Ysr8BFTpoT9Wk27DPhb_81aG_n5zzw4xxkVGXCWrk4JSpqTybz72sYilA0NPAXgIv/s1600/0000OS_Kendo+UI+Cookbook_Maxi.jpg&quot; imageanchor=&quot;1&quot; style=&quot;float: left; margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEigJP_5JD29iNuRw8JAI41Q9xpTVIXT-BmgOGCMW9-xHoHP9XTDNUYOzCf9r9bsPUzpt195AmWyAg_Ysr8BFTpoT9Wk27DPhb_81aG_n5zzw4xxkVGXCWrk4JSpqTybz72sYilA0NPAXgIv/s1600/0000OS_Kendo+UI+Cookbook_Maxi.jpg&quot; height=&quot;320&quot; width=&quot;259&quot; /&gt;&lt;/a&gt;The title says it all. My second book titled &#39;Kendo UI Cookbook&#39; was released last week. I have written over 50 recipes focusing on the Kendo UI application framework, widgets and data visualization components.&lt;/div&gt;
&lt;br /&gt;
Here&#39;s the link from where you can buy the book -&amp;nbsp;&lt;a href=&quot;http://www.packtpub.com/kendo-ui-cookbook/book&quot;&gt;http://www.packtpub.com/kendo-ui-cookbook/book&lt;/a&gt;&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.sagarganatra.com/feeds/1457213645453310855/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.sagarganatra.com/2014/06/my-second-book-kendo-ui-cookbook.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8417810603086728638/posts/default/1457213645453310855'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8417810603086728638/posts/default/1457213645453310855'/><link rel='alternate' type='text/html' href='http://www.sagarganatra.com/2014/06/my-second-book-kendo-ui-cookbook.html' title='My second book - &#39;Kendo UI Cookbook&#39; released!!'/><author><name>Sagar Ganatra</name><uri>http://www.blogger.com/profile/15129859862786257527</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhoO56BqdUmSACmPZKwemvyzRtEm1xJVsPVudy1_Tc2U4vafHustJn0_oFtUkKVcz1oGe_p2woZN3j04yI3Sf_xsTrrlcdno6mLnN1Qz380TamkT3P919jIRjh1acuRGA/s220/Mypic.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEigJP_5JD29iNuRw8JAI41Q9xpTVIXT-BmgOGCMW9-xHoHP9XTDNUYOzCf9r9bsPUzpt195AmWyAg_Ysr8BFTpoT9Wk27DPhb_81aG_n5zzw4xxkVGXCWrk4JSpqTybz72sYilA0NPAXgIv/s72-c/0000OS_Kendo+UI+Cookbook_Maxi.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8417810603086728638.post-1300247984061893426</id><published>2014-04-29T16:11:00.000+05:30</published><updated>2014-04-29T16:11:11.589+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript/jQuery"/><category scheme="http://www.blogger.com/atom/ns#" term="PageJS"/><title type='text'>On using PageJS as a Router and handling page refresh with pushState enabled</title><content type='html'>I have been looking at PageJS as a Routing solution for my Backbone applications. PageJS allows you to specify multiple callback functions for a particular route and creates a context object based on the current state of the application. The context object contains valuable information that can be used in constructing View components and in triggering business work flows.&lt;br /&gt;

&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
Let&#39;s consider a simple application that lists Customers and Orders; also the application provides a functionality to search for customers based on the given ID. In this example application, there would be three routes - orders, customers and search. Using PageJS you can specify the routes using the &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;page&lt;/span&gt; function:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/sagar-ganatra/11391067.js&quot;&gt;&lt;/script&gt;

Here,&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt; page.base&lt;/span&gt; is used to set the base path. This is required if your application is in a particular directory under the web root. The other set of lines define the various routes in the application. The first argument is the path mapping and it is followed by callback functions that should be triggered when the route is encountered. In my application, I would like to load the page first which includes loading several View components, triggering an Ajax request to get data from a RESTful service etc. Once this is complete, I would like components on the page to get a notification about the page change. The path mapping &#39;*&#39; is executed when none of the above routes match. This is useful if you want to redirect the user to an error document or a 404 page. Let&#39;s see the callback functions:&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/sagar-ganatra/11391534.js&quot;&gt;&lt;/script&gt;

Notice that the first function &#39;loadPage&#39; takes two arguments; the context object &#39;ctx&#39; and the next callback function &#39;next&#39;. The loadPage function then tries to load the corresponding page assets by calling a function loadPage on the PageManager module. The last line calls the function &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;next&lt;/span&gt;; this would ask PageJS to trigger the next callback function. In this example the function &#39;triggerPageChangeEvent&#39; is called.&lt;br /&gt;
&lt;br /&gt;
The loadPage function uses the information available in the context (ctx) object to make decision on which page to load. The context object contains the following fields:&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;background-color: #cccccc; font-family: Helvetica Neue, Arial, Helvetica, sans-serif;&quot;&gt;- canonicalPath: &quot;/backbone-router/search&quot;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: #cccccc; font-family: Helvetica Neue, Arial, Helvetica, sans-serif;&quot;&gt;- hash: &quot;&quot;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: #cccccc; font-family: Helvetica Neue, Arial, Helvetica, sans-serif;&quot;&gt;- params: Array[0]&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: #cccccc; font-family: Helvetica Neue, Arial, Helvetica, sans-serif;&quot;&gt;- path: &quot;/search&quot;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: #cccccc; font-family: Helvetica Neue, Arial, Helvetica, sans-serif;&quot;&gt;- pathname: &quot;/backbone-router/search&quot;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: #cccccc; font-family: Helvetica Neue, Arial, Helvetica, sans-serif;&quot;&gt;- querystring: &quot;&quot;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: #cccccc; font-family: Helvetica Neue, Arial, Helvetica, sans-serif;&quot;&gt;- state: Object&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: #cccccc; font-family: Helvetica Neue, Arial, Helvetica, sans-serif;&quot;&gt;&amp;nbsp; - path: &quot;/backbone-router/search&quot;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: #cccccc; font-family: Helvetica Neue, Arial, Helvetica, sans-serif;&quot;&gt;- title: &quot;Backbone Router example&quot;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
A Context object is constructed at runtime when you navigate to a particular route. The &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;state&lt;/span&gt; object is the &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;pushState&lt;/span&gt; object and is available to the user to store application state variables. For example, if the user has searched for a Customer with ID 100, we can add this to the context&#39;s state:&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Helvetica Neue, Arial, Helvetica, sans-serif;&quot;&gt;context.state.selectedCustomer = this.model.toJSON();&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Helvetica Neue, Arial, Helvetica, sans-serif;&quot;&gt;context.save();&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
The save function will save the state of the application. If you look at the implementation in PageJS it uses &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;replaceState&lt;/span&gt; function on the &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;history&lt;/span&gt; object to save the state:&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Helvetica Neue, Arial, Helvetica, sans-serif;&quot;&gt;Context.prototype.save = function(){&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Helvetica Neue, Arial, Helvetica, sans-serif;&quot;&gt;&amp;nbsp; &amp;nbsp; history.replaceState(this.state, this.title, this.canonicalPath);&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Helvetica Neue, Arial, Helvetica, sans-serif;&quot;&gt;};&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
When the user clicks on the back or forward button, the Context&#39;s state would be available. An Internal function in PageJS - &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;onpopstate&lt;/span&gt; is called in this case. However, when the user explicitly triggers the page change by clicking on the link then a new Context object is created.&lt;br /&gt;
&lt;br /&gt;
When working on this application I ran into a problem, wherein on clicking on the refresh button the application would not load. For example, if your URL reads &#39;/backbone-router/customers&#39; and you click the refresh button, the application would not load, which is a correct behavior. The web server would not be able to find the directory &#39;customers&#39; under &#39;backbone-router&#39; and the default error document would be shown. This can be handled by redirecting the user to the parent directory i.e. &#39;/backbone-router&#39; and loading the application. I use Apache web server and I can include a &#39;.htaccess&#39; file in the same directory and specify the redirection rules:&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Helvetica Neue, Arial, Helvetica, sans-serif;&quot;&gt;&amp;lt;ifModule mod_rewrite.c&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Helvetica Neue, Arial, Helvetica, sans-serif;&quot;&gt;&amp;nbsp; &amp;nbsp; RewriteEngine On&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Helvetica Neue, Arial, Helvetica, sans-serif;&quot;&gt;&amp;nbsp; &amp;nbsp; RewriteCond %{REQUEST_FILENAME} !-f&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Helvetica Neue, Arial, Helvetica, sans-serif;&quot;&gt;&amp;nbsp; &amp;nbsp; RewriteCond %{REQUEST_FILENAME} !-d&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Helvetica Neue, Arial, Helvetica, sans-serif;&quot;&gt;&amp;nbsp; &amp;nbsp; RewriteCond %{REQUEST_URI} !index&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Helvetica Neue, Arial, Helvetica, sans-serif;&quot;&gt;&amp;nbsp; &amp;nbsp; RewriteRule (.*) index.html [L]&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Helvetica Neue, Arial, Helvetica, sans-serif;&quot;&gt;&amp;lt;/ifModule&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
The above redirection rule instructs the web server to redirect the user to&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt; index.html &lt;/span&gt;page if the file or the directory is not found. Now when you click on the refresh button, the index.html file would be loaded and the Context object would have the path field set to &#39;customers&#39;. This will then load the required page.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.sagarganatra.com/feeds/1300247984061893426/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.sagarganatra.com/2014/04/on-using-pagejs-as-router-and-handling.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8417810603086728638/posts/default/1300247984061893426'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8417810603086728638/posts/default/1300247984061893426'/><link rel='alternate' type='text/html' href='http://www.sagarganatra.com/2014/04/on-using-pagejs-as-router-and-handling.html' title='On using PageJS as a Router and handling page refresh with pushState enabled'/><author><name>Sagar Ganatra</name><uri>http://www.blogger.com/profile/15129859862786257527</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhoO56BqdUmSACmPZKwemvyzRtEm1xJVsPVudy1_Tc2U4vafHustJn0_oFtUkKVcz1oGe_p2woZN3j04yI3Sf_xsTrrlcdno6mLnN1Qz380TamkT3P919jIRjh1acuRGA/s220/Mypic.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8417810603086728638.post-7050861903320956153</id><published>2014-02-12T12:51:00.000+05:30</published><updated>2014-02-12T12:57:02.963+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="RequireJS"/><title type='text'>RequireJS - Busting the browser cache with every deployment using Grunt targethtml plugin</title><content type='html'>The projects that I work on have deployments to the QA very often; testing out the bug fixes and new features. Every time after the deployment, I ask the QA to clear the cache, since all JavaScript files are cached by the browser. This is really frustrating to QA and I needed someway to clear the cache with every deployment. This would be same in a continuous delivery project, wherein the client would be required to clear the browser cache.&lt;br /&gt;
&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;I use RequireJS to bind the dependencies between various modules. Also, I use Grunt to manage the deployment workflow. The JavaScript code is optimized using RequireJS optimizer, which minifies and combines all the dependencies.&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;
I referred to the RequireJS documentation and found that one can use &lt;a href=&quot;http://requirejs.org/docs/api.html#config-urlArgs&quot; target=&quot;_blank&quot;&gt;&#39;urlArgs&#39; property to bust the browser cache&lt;/a&gt;. If you refer to that example code, it uses the JavaScript Date object and assigns the time-stamp value to the &amp;nbsp;&lt;i&gt;urlArgs &lt;/i&gt;parameter. This works fine if you never want the Require modules to be cached by the browser. However, in a workflow where you would like these files to cleared from the cache only when there is a deployment then you can use a Grunt plugin - &lt;a href=&quot;https://npmjs.org/package/grunt-targethtml&quot; target=&quot;_blank&quot;&gt;grunt-targethtml&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
The target-html plugin parses the source html file and generates the content accordingly. In your source html file, you need to specify target tags that will be processed when Grunt is run:&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/sagar-ganatra/8931390.js&quot;&gt;&lt;/script&gt;

Here, the target html code that will be processed by the Grunt plugin is included in a comment. It has an &#39;If statement&#39; which declares that if the grunt build is being run with &#39;dist&#39; as an option then include the below code. Notice that the script block also specifies a template variable - &#39;bustVersion&#39;. When the html content is being generated this would be treated as string that needs to be replaced with a value.&lt;br /&gt;
&lt;br /&gt;
In your target html configuration (in Gruntfile.js) you need to provide the value that will be assigned to this variable:&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/sagar-ganatra/8931286.js&quot;&gt;&lt;/script&gt;

Here, the &#39;curlyTags&#39; configuration includes a template string &#39;bustVersion&#39; whose value is a scriptlet &#39;&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;i&gt;&amp;lt;%= grunt.template.today(&quot;yyyymmdd&quot;) %&amp;gt;&lt;/i&gt;&#39;. Also, the files configuration includes the mapping between the destination file and the source file. Here &#39;dist/index.html&#39; is the destination file and &#39;dev/index.html&#39; is the source file that will be processed.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
When &#39;grunt dist&#39; is run, the template string {{bustVersion}} is replaced with today&#39;s date (in &#39;yyyymmdd&#39; format). The destination file will now have script tag specifying the RequireJS configuration - &#39;urlArgs&#39; with the date generated using the scriptlet.&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://www.sagarganatra.com/feeds/7050861903320956153/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.sagarganatra.com/2014/02/requirejs-busting-browser-cache-with-every-deployment-using-grunt-targethtml-plugin.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8417810603086728638/posts/default/7050861903320956153'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8417810603086728638/posts/default/7050861903320956153'/><link rel='alternate' type='text/html' href='http://www.sagarganatra.com/2014/02/requirejs-busting-browser-cache-with-every-deployment-using-grunt-targethtml-plugin.html' title='RequireJS - Busting the browser cache with every deployment using Grunt targethtml plugin'/><author><name>Sagar Ganatra</name><uri>http://www.blogger.com/profile/15129859862786257527</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhoO56BqdUmSACmPZKwemvyzRtEm1xJVsPVudy1_Tc2U4vafHustJn0_oFtUkKVcz1oGe_p2woZN3j04yI3Sf_xsTrrlcdno6mLnN1Qz380TamkT3P919jIRjh1acuRGA/s220/Mypic.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8417810603086728638.post-2574721818172885451</id><published>2014-01-23T18:27:00.000+05:30</published><updated>2014-01-23T18:27:49.379+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="BackboneJS"/><category scheme="http://www.blogger.com/atom/ns#" term="Design Patterns"/><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript/jQuery"/><title type='text'>More on MVVM with Backbone Stickit plugin</title><content type='html'>In my last post, I mentioned about two way binding a.k.a &lt;a href=&quot;http://www.sagarganatra.com/2013/11/mvvm-in-backbonejs-using-backbonestickit.html&quot; target=&quot;_blank&quot;&gt;MVVM in Backbone using Backbone.Stickit plugin&lt;/a&gt;. The Stickit plugin does provide awesome two way binding, but in addition it includes several features that are very much apt when modifying state of model or the view. I&#39;ve been using these features in my project regularly.&lt;br /&gt;
&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;The bindings configuration is used to specify the binding between the view and model. When you specify this configuration, the model changes are observed and view is updated whenever there is a change and similarly any changes in the view would update the model. There are many scenarios where in the format of the model or view has to be changed. For example, the model stores a date in a specific format and the view has to display the same in a different format. The Stickit plugin provides methods - &lt;i&gt;onGet&lt;/i&gt; and &lt;i&gt;onSet&lt;/i&gt; which can be used in such scenarios:&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/sagar-ganatra/8469947.js&quot;&gt;&lt;/script&gt;

&lt;br /&gt;
&lt;br /&gt;
Here, instead of providing a one to one mapping between the view element and the model attribute, an object containing the binding configuration is specified. The configuration has three attributes - &lt;i&gt;observe&lt;/i&gt;, &lt;i&gt;onGet&lt;/i&gt; and &lt;i&gt;onSet&lt;/i&gt;. The &#39;&lt;i&gt;observe&lt;/i&gt;&#39; attribute specifies the model attribute that the view element should be mapped to. Before the view element is updated, the &#39;&lt;i&gt;onGet&lt;/i&gt;&#39; function is called, here the function formats the date value present in the model and the view is updated with the formatted value. Now when you change the date in the view, the &#39;&lt;i&gt;onSet&lt;/i&gt;&#39; method is invoked before updating the model. The &#39;&lt;i&gt;onSet&lt;/i&gt;&#39; method, formats the input date and updates the model. These two methods intercept the update of view and model; helping you to format data correctly.&lt;br /&gt;
&lt;br /&gt;
The other feature that I use regularly when working with authorization piece is the use of &#39;&lt;i&gt;visible&lt;/i&gt;&#39; and &#39;&lt;i&gt;visibleFn&lt;/i&gt;&#39;. In a scenario where, based on the logged in user&#39;s credentials some part of the page would be hidden or shown to the user; this feature comes very handy.&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/sagar-ganatra/8506654.js&quot;&gt;&lt;/script&gt;

&lt;br /&gt;
Here the function assigned to &#39;&lt;i&gt;visible&lt;/i&gt;&#39; attribute is executed to check whether the logged in user is an &#39;admin&#39;. It returns a boolean value and based on the whether it is true or false, the view element would be shown or hidden. The &#39;&lt;i&gt;visibleFn&lt;/i&gt;&#39; is optional, by default if &#39;&lt;i&gt;visible&lt;/i&gt;&#39; is true then the view element would have the style attribute &#39;&lt;i&gt;display&lt;/i&gt;&#39; set to &#39;&lt;i&gt;block&lt;/i&gt;&#39; and if false, the element would have &#39;&lt;i&gt;display&lt;/i&gt;&#39; property set to &#39;&lt;i&gt;none&lt;/i&gt;&#39;. If you want change the &#39;&lt;i&gt;display&lt;/i&gt;&#39; property from &#39;&lt;i&gt;block&lt;/i&gt;&#39; to say &#39;&lt;i&gt;inline-block&lt;/i&gt;&#39; or if you want perform an animation before hiding the element, then the &#39;&lt;i&gt;visibleFn&lt;/i&gt;&#39; should be specified.&lt;br /&gt;
&lt;br /&gt;
Another feature that I have used in my projects is the use of &#39;&lt;i&gt;selectOptions&lt;/i&gt;&#39;. This feature is used to populate a &#39;select&#39; element in the form with &#39;option&#39; tags using a collection of objects.&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/sagar-ganatra/8572631.js&quot;&gt;&lt;/script&gt;

Here &#39;&lt;i&gt;selectOptions&lt;/i&gt;&#39; specifies the collection attribute which contains an array of objects, each object with properties &#39;&lt;i&gt;timeZoneName&lt;/i&gt;&#39; and &#39;&lt;i&gt;timeZoneId&lt;/i&gt;&#39;. These properties are assigned to &#39;&lt;i&gt;labelPath&lt;/i&gt;&#39; and &#39;&lt;i&gt;valuePath&lt;/i&gt;&#39; attributes. When &#39;&lt;i&gt;option&lt;/i&gt;&#39; tags are generated, the label name and value of the option tag would be referencing these properties. The &#39;&lt;i&gt;defaultOption&lt;/i&gt;&#39; configuration is used to either specify the default value or define a placeholder for the select element. When you select an element from the &#39;select&#39; drop down, the model attribute &#39;&lt;i&gt;timezone&lt;/i&gt;&#39; would be updated.&lt;br /&gt;
&lt;br /&gt;
There are several other features in the Stickit plugin, like adding custom handlers, selectively updating the model or view -&lt;a href=&quot;http://nytimes.github.io/backbone.stickit/&quot; target=&quot;_blank&quot;&gt; http://nytimes.github.io/backbone.stickit/&amp;nbsp;&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.sagarganatra.com/feeds/2574721818172885451/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.sagarganatra.com/2014/01/more-on-mvvm-with-backbone-stickit.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8417810603086728638/posts/default/2574721818172885451'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8417810603086728638/posts/default/2574721818172885451'/><link rel='alternate' type='text/html' href='http://www.sagarganatra.com/2014/01/more-on-mvvm-with-backbone-stickit.html' title='More on MVVM with Backbone Stickit plugin'/><author><name>Sagar Ganatra</name><uri>http://www.blogger.com/profile/15129859862786257527</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhoO56BqdUmSACmPZKwemvyzRtEm1xJVsPVudy1_Tc2U4vafHustJn0_oFtUkKVcz1oGe_p2woZN3j04yI3Sf_xsTrrlcdno6mLnN1Qz380TamkT3P919jIRjh1acuRGA/s220/Mypic.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8417810603086728638.post-1415567445918128596</id><published>2013-11-11T18:17:00.000+05:30</published><updated>2013-11-11T18:17:16.223+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="AngularJS"/><category scheme="http://www.blogger.com/atom/ns#" term="BackboneJS"/><category scheme="http://www.blogger.com/atom/ns#" term="Design Patterns"/><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript/jQuery"/><title type='text'>MVVM in BackboneJS using Backbone.Stickit</title><content type='html'>I have been looking into various design patterns and trying to architect client side applications using it. More often than not the MVC pattern fits the requirement in most of the applications. However, I have found myself using MVVM (Model View - View Model) pattern along with MVC. I use MVVM pattern particularly when I have to maintain the state of the model on the client side. AngularJS provides great support by allowing you to extend the markup and tying the model right within the view (the markup). It also provides components that can be used to structure the application the MVC way and hence it&#39;s appropriately termed as MVW or MV* framework. However, I use BackboneJS in most of my applications and I have been able to maintain the state of the model using the &lt;a href=&quot;http://nytimes.github.io/backbone.stickit/&quot; target=&quot;_blank&quot;&gt;Backbone.Stickit&lt;/a&gt; plugin.&lt;br /&gt;
&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;When working with Backbone applications, the View&#39;s sole responsibility would be to render the model data and also re-render the parts of the view when the state of the model changes. The View listens to the model changes and executes a callback function when the state of the model has changed:&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/sagar-ganatra/6921966.js&quot;&gt;&lt;/script&gt;

&lt;br /&gt;
Here in the Backbone View&#39;s initialize method, the View is listening to the change in one the model&#39;s attribute and it executes the &#39;updateView&#39; method whenever the &#39;modelAttribute&#39; is updated. The &#39;updateView&#39; function then refers to one of the nodes in the View and updates it with the value in &#39;modelAttribute&#39;. This pattern can be repeated for various attributes in the model and the view can have several functions whose only responsibility is to update a DOM node in the View.&lt;br /&gt;
&lt;br /&gt;
Similarly, when the user inputs data in form elements the same should be reflected in the model. To do that the View will have to declare event handlers:&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/sagar-ganatra/7387519.js&quot;&gt;&lt;/script&gt;

This has to be repeated for other View elements and developer will be required to write boilerplate code. An alternative to this is to use a Backbone plugin called &#39;Stickit&#39;. Backbone.Stickit abstracts the above functionality and provides a more cleaner way to bind the View&#39;s elements to the model&#39;s attributes. In a Backbone View you can define the binding between the model&#39;s attributes with the elements in the markup using the &#39;bindings&#39; object:&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/sagar-ganatra/7386914.js&quot;&gt;&lt;/script&gt;

Here in the bindings object, the keys are the View elements and the attributes in the model are specified as values. For example, the view element &#39;.js-full-name&#39; is bound to the model attribute &#39;fullName&#39;. The bindings object provides a two way binding between the View elements and Model attributes. This means that whenever the user inputs some value in the form elements the Model attributes are updated and whenever the Model attribute is updated by some part of the application or by a service call the View elements are updated.&lt;br /&gt;
&lt;br /&gt;
Once the View has compiled the client-side template and rendered it, the View elements should be bound to the Model&#39;s attributes. To do that invoke the &lt;i&gt;stickit &lt;/i&gt;method on the view object (&lt;i&gt;view.stickit()&lt;/i&gt;). I generally use the &lt;i&gt;postRender &lt;/i&gt;method and invoke it after the render method has been executed. As the name suggests, the postRender method would execute a set of actions after rendering the template. In this case, call &lt;i&gt;stickit &lt;/i&gt;on the view object -&lt;i&gt; this.stickit()&lt;/i&gt;; where &lt;i&gt;this &lt;/i&gt;refers to the current view.&lt;br /&gt;
&lt;br /&gt;
The Stickit plugin provides several options to configure the bindings. I&#39;ll explain those in my next post.</content><link rel='replies' type='application/atom+xml' href='http://www.sagarganatra.com/feeds/1415567445918128596/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.sagarganatra.com/2013/11/mvvm-in-backbonejs-using-backbonestickit.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8417810603086728638/posts/default/1415567445918128596'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8417810603086728638/posts/default/1415567445918128596'/><link rel='alternate' type='text/html' href='http://www.sagarganatra.com/2013/11/mvvm-in-backbonejs-using-backbonestickit.html' title='MVVM in BackboneJS using Backbone.Stickit'/><author><name>Sagar Ganatra</name><uri>http://www.blogger.com/profile/15129859862786257527</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhoO56BqdUmSACmPZKwemvyzRtEm1xJVsPVudy1_Tc2U4vafHustJn0_oFtUkKVcz1oGe_p2woZN3j04yI3Sf_xsTrrlcdno6mLnN1Qz380TamkT3P919jIRjh1acuRGA/s220/Mypic.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8417810603086728638.post-6685394182033303836</id><published>2013-10-04T19:26:00.001+05:30</published><updated>2013-10-04T19:26:54.829+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="Announcements"/><category scheme="http://www.blogger.com/atom/ns#" term="Books"/><category scheme="http://www.blogger.com/atom/ns#" term="Kendo UI"/><category scheme="http://www.blogger.com/atom/ns#" term="Misc"/><title type='text'>Win a Free e-Book copy of my book - &#39;Instant Kendo UI Mobile&#39;</title><content type='html'>I&#39;m giving away two copies of my book &#39;&lt;a href=&quot;http://www.packtpub.com/kendo-user-interface-mobile/book&quot; target=&quot;_blank&quot;&gt;Instant Kendo UI Mobile&lt;/a&gt;&#39;. All you need to do is to send me a message through the &#39;Contact Me&#39; form, let me know how this book will benefit you and whether you can post a review as well. You can also message me on &lt;a href=&quot;https://twitter.com/sagarganatra&quot; target=&quot;_blank&quot;&gt;Twitter &lt;/a&gt;or &lt;a href=&quot;https://www.facebook.com/sagar.shg&quot; target=&quot;_blank&quot;&gt;Facebook&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
You can find out about the book here -&amp;nbsp;&lt;a href=&quot;http://www.packtpub.com/kendo-user-interface-mobile/book&quot;&gt;&lt;b&gt;http://www.packtpub.com/kendo-user-interface-mobile/book&lt;/b&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.sagarganatra.com/feeds/6685394182033303836/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.sagarganatra.com/2013/10/win-free-e-book-copy-of-my-book-instant-kendo-ui-mobile.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8417810603086728638/posts/default/6685394182033303836'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8417810603086728638/posts/default/6685394182033303836'/><link rel='alternate' type='text/html' href='http://www.sagarganatra.com/2013/10/win-free-e-book-copy-of-my-book-instant-kendo-ui-mobile.html' title='Win a Free e-Book copy of my book - &#39;Instant Kendo UI Mobile&#39;'/><author><name>Sagar Ganatra</name><uri>http://www.blogger.com/profile/15129859862786257527</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhoO56BqdUmSACmPZKwemvyzRtEm1xJVsPVudy1_Tc2U4vafHustJn0_oFtUkKVcz1oGe_p2woZN3j04yI3Sf_xsTrrlcdno6mLnN1Qz380TamkT3P919jIRjh1acuRGA/s220/Mypic.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8417810603086728638.post-6657959371695822872</id><published>2013-07-29T20:15:00.000+05:30</published><updated>2013-07-29T20:15:20.766+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="Announcements"/><category scheme="http://www.blogger.com/atom/ns#" term="Books"/><category scheme="http://www.blogger.com/atom/ns#" term="HTML5"/><category scheme="http://www.blogger.com/atom/ns#" term="Kendo UI"/><title type='text'>My first book titled &#39;Kendo UI Mobile&#39; is here!!</title><content type='html'>&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj__WsmkamqGV2QvD1ypOmd1bmzkqtKLteS_PiFg3kuon_4FcPez4uTUNyy-XNkyxq8SdIkbj12sqioXPuXXhpV6K467BIMd26NmG9NDeRt6UEsPJ0Cz9ltQbxaJAhiNbAHLbZXQQSEDoQe/s1600/9112OT.jpg&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj__WsmkamqGV2QvD1ypOmd1bmzkqtKLteS_PiFg3kuon_4FcPez4uTUNyy-XNkyxq8SdIkbj12sqioXPuXXhpV6K467BIMd26NmG9NDeRt6UEsPJ0Cz9ltQbxaJAhiNbAHLbZXQQSEDoQe/s320/9112OT.jpg&quot; width=&quot;259&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
The title says it all. I had posted a couple of entries on Kendo UI earlier and was approached by Packt publishing to write on &#39;Kendo UI Mobile&#39;. Writing a book was both a personal and a professional goal that I had set for myself. Today I have realized it and I feel accomplished. For almost everyone, first things are very special. Be it their first job, paycheck, girlfriend\boyfriend, marriage, first kid and anything that happens for the first time in their life. This is my baby and I&#39;m going to celebrate my win today.&lt;br /&gt;
&lt;br /&gt;
If you are planning to build a mobile website or an app using Kendo UI Mobile, this book should get you up and running. Here&#39;s the link to the page, from where you can learn about the book and buy it -&lt;a href=&quot;http://www.packtpub.com/kendo-user-interface-mobile/book&quot; target=&quot;_blank&quot;&gt; &lt;b&gt;http://www.packtpub.com/kendo-user-interface-mobile/book&lt;/b&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.sagarganatra.com/feeds/6657959371695822872/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.sagarganatra.com/2013/07/my-first-book-titled-kendo-ui-mobile-is-here.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8417810603086728638/posts/default/6657959371695822872'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8417810603086728638/posts/default/6657959371695822872'/><link rel='alternate' type='text/html' href='http://www.sagarganatra.com/2013/07/my-first-book-titled-kendo-ui-mobile-is-here.html' title='My first book titled &#39;Kendo UI Mobile&#39; is here!!'/><author><name>Sagar Ganatra</name><uri>http://www.blogger.com/profile/15129859862786257527</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhoO56BqdUmSACmPZKwemvyzRtEm1xJVsPVudy1_Tc2U4vafHustJn0_oFtUkKVcz1oGe_p2woZN3j04yI3Sf_xsTrrlcdno6mLnN1Qz380TamkT3P919jIRjh1acuRGA/s220/Mypic.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj__WsmkamqGV2QvD1ypOmd1bmzkqtKLteS_PiFg3kuon_4FcPez4uTUNyy-XNkyxq8SdIkbj12sqioXPuXXhpV6K467BIMd26NmG9NDeRt6UEsPJ0Cz9ltQbxaJAhiNbAHLbZXQQSEDoQe/s72-c/9112OT.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8417810603086728638.post-3719306671634851638</id><published>2013-06-25T15:18:00.000+05:30</published><updated>2013-06-25T15:18:04.925+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="BackboneJS"/><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript/jQuery"/><title type='text'>Backbone Collections do not emit &#39;reset&#39; event after fetch</title><content type='html'>I recently upgraded my Backbone application to the 1.0 version of the library. When I ran the application, the Backbone View was not rendering anything on the browser screen. I noticed the XHR request being sent in the Network tab of Chrome Dev Tools. This meant that the Collection was fetching the data from the server. However, the &#39;render&#39; function defined in Backbone View was not being called, which was attached as a callback handler for the &#39;reset&#39; event on the Collection.&lt;br /&gt;
&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;
Here&#39;s the sample code:&lt;br /&gt;&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/sagar-ganatra/5856377.js&quot;&gt;&lt;/script&gt;
I had a quick look at the Backbone documentation and came across the section &#39;&lt;a href=&quot;http://backbonejs.org/#upgrading&quot; target=&quot;_blank&quot;&gt;Upgrading to 1.0&lt;/a&gt;&#39;. The very first point there mentions that the &#39;reset&#39; event is not triggered by default when the Collection is populated with data. One has to pass the key - &#39;reset&#39; with value true when making a fetch call on the Collection. Now I had to update the code at places where the fetch call was being made. However, this can be avoided by making changes in the Collection. There are two ways of doing this: overriding the fetch method and resetting the collection in parse method. Let&#39;s see both of them:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Overriding the fetch method:&amp;nbsp;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/sagar-ganatra/5856402.js&quot;&gt;&lt;/script&gt;
&lt;div&gt;
The fetch method is overridden here and as you can see from the above code, the &#39;reset&#39; key is added to options and then the fetch method defined on the Backbone Collection&#39;s prototype is called.&lt;/div&gt;
&lt;div&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;Resetting the Collection in parse:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/sagar-ganatra/5856389.js&quot;&gt;&lt;/script&gt;
Whenever a response is received from the server, the parse method is called before sending a notification to the listeners. Here you can call the reset method passing the response as an argument. The Collection now has been reset with the data received from the server and View will receive a reset event.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.sagarganatra.com/feeds/3719306671634851638/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.sagarganatra.com/2013/06/backbone-collections-do-not-emit-reset-event-after-fetch.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8417810603086728638/posts/default/3719306671634851638'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8417810603086728638/posts/default/3719306671634851638'/><link rel='alternate' type='text/html' href='http://www.sagarganatra.com/2013/06/backbone-collections-do-not-emit-reset-event-after-fetch.html' title='Backbone Collections do not emit &#39;reset&#39; event after fetch'/><author><name>Sagar Ganatra</name><uri>http://www.blogger.com/profile/15129859862786257527</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhoO56BqdUmSACmPZKwemvyzRtEm1xJVsPVudy1_Tc2U4vafHustJn0_oFtUkKVcz1oGe_p2woZN3j04yI3Sf_xsTrrlcdno6mLnN1Qz380TamkT3P919jIRjh1acuRGA/s220/Mypic.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8417810603086728638.post-428078794480575320</id><published>2013-06-19T12:25:00.000+05:30</published><updated>2013-06-19T17:56:25.474+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="CSS"/><category scheme="http://www.blogger.com/atom/ns#" term="HTML5"/><category scheme="http://www.blogger.com/atom/ns#" term="Kiss My App"/><title type='text'>Para - Para - Parallax</title><content type='html'>I was listening to ColdPlay while developing a Parallax scrolling application and hence the title. Anyway, I was very much intrigued by the parallax scrolling model and wanted to try my hand on building one. The idea here was to show images of different transparency levels in such a way that when the user scrolls, one image would blend over the previous one.&lt;br&gt;
&lt;br&gt;
Take a look at the application &lt;b&gt;&lt;a href=&quot;http://demos-sagarganatra.appspot.com/parallax/index.html&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;&lt;/b&gt;.&lt;br&gt;
&lt;div&gt;
&lt;br&gt;&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://www.sagarganatra.com/feeds/428078794480575320/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.sagarganatra.com/2013/06/para-para-parallax.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8417810603086728638/posts/default/428078794480575320'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8417810603086728638/posts/default/428078794480575320'/><link rel='alternate' type='text/html' href='http://www.sagarganatra.com/2013/06/para-para-parallax.html' title='Para - Para - Parallax'/><author><name>Sagar Ganatra</name><uri>http://www.blogger.com/profile/15129859862786257527</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhoO56BqdUmSACmPZKwemvyzRtEm1xJVsPVudy1_Tc2U4vafHustJn0_oFtUkKVcz1oGe_p2woZN3j04yI3Sf_xsTrrlcdno6mLnN1Qz380TamkT3P919jIRjh1acuRGA/s220/Mypic.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8417810603086728638.post-339019092886585695</id><published>2013-05-23T17:32:00.002+05:30</published><updated>2013-06-19T12:11:34.431+05:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="HTML5"/><category scheme="http://www.blogger.com/atom/ns#" term="Kiss My App"/><category scheme="http://www.blogger.com/atom/ns#" term="WebRTC"/><title type='text'>WebRTC experiment - Recognizing hand gestures</title><content type='html'>I have created a web application that recognizes hand gestures using WebRTC&#39;s &lt;b&gt;&lt;i&gt;getUserMedia &lt;/i&gt;&lt;/b&gt;API. Here&#39;s how it works: when you launch the application the browser will prompt you for the permission to access the camera. Click on &#39;Accept&#39;,and then swipe your hand from right to left and vice versa. You would see that the next image&amp;nbsp; (or the previous image if you swipe from left to right) in the gallery slides through.&lt;br /&gt;
&lt;br /&gt;
You can access the application &lt;a href=&quot;http://demos-sagarganatra.appspot.com/gesto/index.html&quot; target=&quot;_blank&quot;&gt;&lt;b&gt;here&lt;/b&gt;&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Please note, I have tested this application on Chrome only and not on other browsers. Also, I have used five images in this demo and it is obvious that no image would be shown if you swipe from right to left when the last image is being shown or when you swipe from left to right when the first image is shown. I have codenamed this application as &#39;Gesto&#39; and hence the name in the URL of the application.&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.sagarganatra.com/feeds/339019092886585695/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.sagarganatra.com/2013/05/webrtc-expirement-recognizing-hand-gestures.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8417810603086728638/posts/default/339019092886585695'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8417810603086728638/posts/default/339019092886585695'/><link rel='alternate' type='text/html' href='http://www.sagarganatra.com/2013/05/webrtc-expirement-recognizing-hand-gestures.html' title='WebRTC experiment - Recognizing hand gestures'/><author><name>Sagar Ganatra</name><uri>http://www.blogger.com/profile/15129859862786257527</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhoO56BqdUmSACmPZKwemvyzRtEm1xJVsPVudy1_Tc2U4vafHustJn0_oFtUkKVcz1oGe_p2woZN3j04yI3Sf_xsTrrlcdno6mLnN1Qz380TamkT3P919jIRjh1acuRGA/s220/Mypic.jpg'/></author><thr:total>0</thr:total></entry></feed>