<?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-3311430580289688408</id><updated>2026-06-22T14:27:02.518-07:00</updated><category term="JavaScript"/><category term="NodeJS"/><category term="Azure"/><category term="Opinion"/><category term="React"/><category term="node"/><category term="ES6"/><category term="JSPM"/><category term="TypeScript"/><category term="Angular"/><category term="Babel"/><category term="Express"/><category term="GraphQL"/><category term="Karma"/><category term="dotnet"/><category term="API"/><category term="Angular 6"/><category term="Angular Material"/><category term="AngularJS"/><category term="Asynchronous"/><category term="CRA"/><category term="DNS"/><category term="Functions"/><category term="Gulp"/><category term="IIS"/><category term="Jasmine"/><category term="Jest"/><category term="Md2"/><category term="Microsoft Windows Workflow Foundation"/><category term="Mongo"/><category term="Mongoose"/><category term="MongooseTS"/><category term="PWA"/><category term="Pester"/><category term="PowerShell"/><category term="Python"/><category term="React-router"/><category term="Redux"/><category term="Unit Testing"/><category term="VSCode"/><category term="Visual Studio Code"/><category term="Webpack"/><category term="Yarn"/><category term="excel"/><title type='text'>G&#39;s Technical Blog</title><subtitle type='html'>Keeping things accessible in the ever-evolving world of web development</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://garethscode.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3311430580289688408/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://garethscode.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/3311430580289688408/posts/default?start-index=26&amp;max-results=25&amp;redirect=false'/><author><name>trujillo42</name><uri>http://www.blogger.com/profile/09625726405492153186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>29</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-3311430580289688408.post-9130367767968898701</id><published>2024-08-21T16:09:00.000-07:00</published><updated>2024-08-22T03:33:38.640-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="dotnet"/><category scheme="http://www.blogger.com/atom/ns#" term="IIS"/><title type='text'>Hosting a .NET Core 3.1 App in an IIS Virtual Directory</title><content type='html'>&lt;p&gt;Virtual Directories are useful if you wish to host multiple sites on different sub paths. Like localhost/client1website or localhost/client2website.&lt;/p&gt;&lt;p&gt;I was getting 500 error when trying to host a .NET 3.1 application on IIS.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Suggestions were&lt;/p&gt;&lt;p&gt;1) app pool - yep I had checked and checked again, it was defitely set to &quot;No Managed Code&quot;&lt;/p&gt;&lt;p&gt;2) Check the IIS Logs - see below - calling Get to [virtualdirectory1]/[virtualdirectory2] on port 80 gets me a 500&lt;/p&gt;&lt;p&gt;&lt;/p&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/a/AVvXsEhPbdhnmdTibfx5fnJ2nFG_UMHLk0umtFtotjz72vyLQp0gtBpcT0IqtzPa896tkvOkF8wsw94rkCUbhOLs2MiLz6qA9R0b9PWla8CHN_TN9wa5963vJrRUiK8Wp7PAZqYKjwErXgOOZ_6XR592Qx5XwFFt-wtc2CIYzyyTpeMzhbBb7oauzuIyi4GBNvg&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;136&quot; data-original-width=&quot;925&quot; height=&quot;47&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEhPbdhnmdTibfx5fnJ2nFG_UMHLk0umtFtotjz72vyLQp0gtBpcT0IqtzPa896tkvOkF8wsw94rkCUbhOLs2MiLz6qA9R0b9PWla8CHN_TN9wa5963vJrRUiK8Wp7PAZqYKjwErXgOOZ_6XR592Qx5XwFFt-wtc2CIYzyyTpeMzhbBb7oauzuIyi4GBNvg&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;3) Check the permissions. IIS_IUSRS has read and execute permissions&lt;/div&gt;&lt;br /&gt;4) Check that the web.config has what it should have and nothing else. - yup checked that&lt;p&gt;&lt;/p&gt;&lt;p&gt;5) Check the application logs - Attribute &#39;ProcessPath&#39; is required&lt;/p&gt;&lt;p&gt;&lt;/p&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/a/AVvXsEjn-DwfP6RRNzGk5PeAUzLZV0tf_ln248qQew2v3-McI21YZa6v95OkDDgtHHJLKxJd5zzEgTl1Lmmsks6bzW9KcLQiBT9_ddjNAoUI9781Qjt2PLtgyOTGNkEHxX7G4igmIXY3WAg-eJ7NqG6J5cKiigHVBUoFIMy1kb6YVY68deecvH0H8pZkHwinnB8&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;146&quot; data-original-width=&quot;776&quot; height=&quot;60&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEjn-DwfP6RRNzGk5PeAUzLZV0tf_ln248qQew2v3-McI21YZa6v95OkDDgtHHJLKxJd5zzEgTl1Lmmsks6bzW9KcLQiBT9_ddjNAoUI9781Qjt2PLtgyOTGNkEHxX7G4igmIXY3WAg-eJ7NqG6J5cKiigHVBUoFIMy1kb6YVY68deecvH0H8pZkHwinnB8&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;At this point getting closer with the app log message. Was there something up with how I installed dotnet? Am I missing a path variable?&lt;/p&gt;I found someone saying that you should really have dotnet SDK as well as the hosting package so I installed the SDK. Nope&lt;p&gt;&lt;/p&gt;&lt;p&gt;I set the dotnet path variable to &quot;C:\Program Files\dotnet\dotnet.exe&quot;, Nope&lt;/p&gt;&lt;p&gt;Then I googled &quot;.net core 3.1 process path error&quot;.&lt;/p&gt;&lt;p&gt;You get a lot, but third one on Stack Overflow --&amp;nbsp;&lt;/p&gt;&lt;p&gt;&#39;Make sure you right click on your Virtual Directory and select &quot;Convert to app&quot;.&#39;&amp;nbsp;&lt;/p&gt;&lt;p&gt;I really dislike IIS more than usual today :). But hey, I made it!&lt;/p&gt;&lt;p&gt;Attributions&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://stackoverflow.com/questions/62194917/hosting-a-net-core-application-in-iis-could-not-load-configuration-attribute&quot; target=&quot;_blank&quot;&gt;Load configuration attribute QA on Stack Overflow&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://garethscode.blogspot.com/feeds/9130367767968898701/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://garethscode.blogspot.com/2024/08/hosting-net-core-31-app-in-iis.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3311430580289688408/posts/default/9130367767968898701'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3311430580289688408/posts/default/9130367767968898701'/><link rel='alternate' type='text/html' href='http://garethscode.blogspot.com/2024/08/hosting-net-core-31-app-in-iis.html' title='Hosting a .NET Core 3.1 App in an IIS Virtual Directory'/><author><name>trujillo42</name><uri>http://www.blogger.com/profile/09625726405492153186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/a/AVvXsEhPbdhnmdTibfx5fnJ2nFG_UMHLk0umtFtotjz72vyLQp0gtBpcT0IqtzPa896tkvOkF8wsw94rkCUbhOLs2MiLz6qA9R0b9PWla8CHN_TN9wa5963vJrRUiK8Wp7PAZqYKjwErXgOOZ_6XR592Qx5XwFFt-wtc2CIYzyyTpeMzhbBb7oauzuIyi4GBNvg=s72-c" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3311430580289688408.post-1147512365816333167</id><published>2021-12-16T07:48:00.000-08:00</published><updated>2021-12-16T07:48:48.593-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="node"/><category scheme="http://www.blogger.com/atom/ns#" term="NodeJS"/><category scheme="http://www.blogger.com/atom/ns#" term="React"/><category scheme="http://www.blogger.com/atom/ns#" term="React-router"/><title type='text'>React Router and NodeJS</title><content type='html'>&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Hosting your React app is usually as simple as copying over the files to a &quot;public&quot; or &quot;static&quot; directory.&lt;/div&gt;&lt;div&gt;&amp;nbsp;&lt;/div&gt;&lt;div&gt;You could simply paste the files onto an IIS or Apache Server and this article could still help you if you are using sub directories. However, I have written this to tackle the situation where a pre-existing web application will host, in this scenario the host application is written in NodeJS.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Generally, all you need to worry about is serving the &quot;index.html&quot; file that comes in the production build bundle at the right time, something like:&amp;nbsp;&lt;/div&gt;&lt;div&gt;
  &lt;pre style=&quot;background-color: #1e1e1e; border-radius: 4px; border: 1px solid rgb(204, 204, 204); box-sizing: border-box; line-height: 1.42857; margin-bottom: 10px; overflow-wrap: break-word; overflow: auto; padding: 9.5px; word-break: break-all;&quot;&gt;&lt;span style=&quot;font-family: consolas; font-size: x-small;&quot;&gt;&lt;div style=&quot;color: #d4d4d4; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 14px; line-height: 19px;&quot;&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;router.&lt;span style=&quot;color: #dcdcaa;&quot;&gt;get&lt;/span&gt;(&lt;span style=&quot;color: #ce9178;&quot;&gt;&#39;/myroute&#39;&lt;/span&gt;,&amp;nbsp;&lt;span style=&quot;color: #569cd6;&quot;&gt;async&lt;/span&gt;&amp;nbsp;(req,&amp;nbsp;res)&amp;nbsp;&lt;span style=&quot;color: #569cd6;&quot;&gt;=&amp;gt;&lt;/span&gt;&amp;nbsp;{&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;color: #d4d4d4; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 14px; line-height: 19px;&quot;&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #c586c0;&quot;&gt;return&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;res&lt;/span&gt;.&lt;span style=&quot;color: #dcdcaa;&quot;&gt;sendFile&lt;/span&gt;(path.&lt;span style=&quot;color: #dcdcaa;&quot;&gt;join&lt;/span&gt;(&lt;span style=&quot;color: #9cdcfe;&quot;&gt;__dirname&lt;/span&gt;&amp;nbsp;+&amp;nbsp;&lt;span style=&quot;color: #ce9178;&quot;&gt;&#39;/public/client/index.html&#39;&lt;/span&gt;));&lt;/div&gt;&lt;div style=&quot;color: #d4d4d4; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 14px; line-height: 19px;&quot;&gt;}&lt;/div&gt;&lt;div style=&quot;color: #d4d4d4; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 14px; line-height: 19px;&quot;&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;color: #d4d4d4; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 14px; line-height: 19px;&quot;&gt;&lt;div style=&quot;line-height: 19px;&quot;&gt;&lt;span style=&quot;color: #6a9955;&quot;&gt;//&amp;nbsp;later&amp;nbsp;on&amp;nbsp;make&amp;nbsp;the&amp;nbsp;public&amp;nbsp;directory&amp;nbsp;accessible&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style=&quot;color: #d4d4d4; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 14px; line-height: 19px;&quot;&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;app&lt;/span&gt;.&lt;span style=&quot;color: #dcdcaa;&quot;&gt;use&lt;/span&gt;(&lt;span style=&quot;color: #ce9178;&quot;&gt;&#39;/public&#39;&lt;/span&gt;,&amp;nbsp;&lt;span style=&quot;color: #dcdcaa;&quot;&gt;express&lt;/span&gt;.&lt;span style=&quot;color: #dcdcaa;&quot;&gt;static&lt;/span&gt;(&lt;span style=&quot;color: #9cdcfe;&quot;&gt;__dirname&lt;/span&gt;&amp;nbsp;+&amp;nbsp;&lt;span style=&quot;color: #ce9178;&quot;&gt;&#39;/public&#39;&lt;/span&gt;));&lt;/div&gt;&lt;/span&gt;&lt;/pre&gt;
  
  &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;However, in this case I want to use &lt;a href=&quot;https://reactrouter.com/web/api&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;React Router&lt;/a&gt;&amp;nbsp;to navigate to sub pages. e.g. myroute/ home, myroute/user etc...&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The way to do it is to use a wildcard off of your main route so that your React app will load on every child route of &quot;myroute&quot;:&lt;/div&gt;
&lt;pre style=&quot;background-color: #1e1e1e; border-radius: 4px; border: 1px solid rgb(204, 204, 204); box-sizing: border-box; line-height: 1.42857; margin-bottom: 10px; overflow-wrap: break-word; overflow: auto; padding: 9.5px; word-break: break-all;&quot;&gt;&lt;span style=&quot;font-family: consolas; font-size: x-small;&quot;&gt;&lt;div style=&quot;color: #d4d4d4; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 14px; line-height: 19px;&quot;&gt;&lt;div&gt;&lt;span style=&quot;color: #6a9955;&quot;&gt;// this&amp;nbsp;is&amp;nbsp;required&amp;nbsp;to&amp;nbsp;support&amp;nbsp;any&amp;nbsp;client&amp;nbsp;side&amp;nbsp;routing&amp;nbsp;written&amp;nbsp;in&amp;nbsp;react.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;router&lt;/span&gt;.&lt;span style=&quot;color: #dcdcaa;&quot;&gt;get&lt;/span&gt;(&lt;span style=&quot;color: #ce9178;&quot;&gt;&#39;/myroute/*&#39;&lt;/span&gt;,&amp;nbsp;(&lt;span style=&quot;color: #9cdcfe;&quot;&gt;req&lt;/span&gt;,&amp;nbsp;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;res&lt;/span&gt;)&amp;nbsp;&lt;span style=&quot;color: #569cd6;&quot;&gt;=&amp;gt;&lt;/span&gt;&amp;nbsp;{&amp;nbsp;&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;res&lt;/span&gt;.&lt;span style=&quot;color: #dcdcaa;&quot;&gt;sendFile&lt;/span&gt;(path.&lt;span style=&quot;color: #dcdcaa;&quot;&gt;join&lt;/span&gt;(&lt;span style=&quot;color: #9cdcfe;&quot;&gt;__dirname&lt;/span&gt;&amp;nbsp;+&amp;nbsp;&lt;span style=&quot;color: #ce9178;&quot;&gt;&#39;/public/client/index.html&#39;&lt;/span&gt;));&lt;/div&gt;&lt;div&gt;});&lt;/div&gt;&lt;/div&gt;&lt;/span&gt;&lt;/pre&gt;

On the React application side the &quot;basename&quot; property of the Router wrapper component (in &lt;a href=&quot;https://reactrouter.com/web&quot;&gt;React Router 5+&lt;/a&gt;) needs to be set. In my case I set &quot;base&quot; when in production mode to &quot;/myroute&quot;. This will mean React router will look for &quot;/myroute/new&quot; to render the Start component rather than just &quot;/new&quot;.&lt;br /&gt;
&lt;pre style=&quot;background-color: #1e1e1e; border-radius: 4px; border: 1px solid rgb(204, 204, 204); box-sizing: border-box; line-height: 1.42857; margin-bottom: 10px; overflow-wrap: break-word; overflow: auto; padding: 9.5px; word-break: break-all;&quot;&gt;&lt;div style=&quot;color: #d4d4d4; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 14px; line-height: 19px;&quot;&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;const&lt;/span&gt;&amp;nbsp;base&amp;nbsp;=&amp;nbsp;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;process&lt;/span&gt;.env.NODE_ENV&amp;nbsp;===&amp;nbsp;&lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;production&quot;&lt;/span&gt;&amp;nbsp;?&amp;nbsp;&lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;/myroute&quot;&lt;/span&gt;&amp;nbsp;:&amp;nbsp;&lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;/&quot;&lt;/span&gt;;&lt;/div&gt;&lt;div style=&quot;color: #d4d4d4; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 14px; line-height: 19px;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;color: #d4d4d4; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 14px; line-height: 19px;&quot;&gt;&lt;div style=&quot;line-height: 19px;&quot;&gt;&lt;div&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;Router&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;basename&lt;/span&gt;=&lt;span style=&quot;color: #569cd6;&quot;&gt;{&lt;/span&gt;base&lt;span style=&quot;color: #569cd6;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;Switch&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;Route&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;exact&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;path&lt;/span&gt;=&lt;span style=&quot;color: #ce9178;&quot;&gt;&#39;/new&#39;&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;Start&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color: grey;&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;Route&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;color: grey;&quot;&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;Switch&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;div style=&quot;line-height: 19px;&quot;&gt;&lt;div&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;Router&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/pre&gt;

&lt;div&gt;It is also worth mentioning that it is considered best practice to add a href meta tag to you index.html page.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;u&gt;References&lt;/u&gt;&lt;/div&gt;&lt;div&gt;react-router | https://reactrouter.com/web&lt;/div&gt;&lt;div&gt;medium | https://dev-listener.medium.com/react-routes-nodejs-routes-2875f148065b&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://garethscode.blogspot.com/feeds/1147512365816333167/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://garethscode.blogspot.com/2021/12/react-router-and-nodejs.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3311430580289688408/posts/default/1147512365816333167'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3311430580289688408/posts/default/1147512365816333167'/><link rel='alternate' type='text/html' href='http://garethscode.blogspot.com/2021/12/react-router-and-nodejs.html' title='React Router and NodeJS'/><author><name>trujillo42</name><uri>http://www.blogger.com/profile/09625726405492153186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3311430580289688408.post-1331556879015152380</id><published>2020-10-09T09:18:00.009-07:00</published><updated>2021-02-04T06:01:20.234-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="GraphQL"/><category scheme="http://www.blogger.com/atom/ns#" term="Mongo"/><category scheme="http://www.blogger.com/atom/ns#" term="Mongoose"/><category scheme="http://www.blogger.com/atom/ns#" term="MongooseTS"/><category scheme="http://www.blogger.com/atom/ns#" term="TypeScript"/><title type='text'>Generating a Schema for GraphQL</title><content type='html'>&lt;p&gt;&lt;b&gt;When writing the schema that you just defined elsewhere gets a little old....&lt;/b&gt;&lt;/p&gt;&lt;p&gt;I have been working on a graphql instance where the main data source is, currently at least, a mongo database. As you may have seen in my last blog post about defining graphql schema&#39;s, I was able to include a more useful set of scalar types to make my graph API easier to consume.&lt;/p&gt;&lt;p&gt;I did this using the merge tools in the graphql-tools library. Well, I found another use for those tools in my next TypeScript/Mongo/GraphQL adventure!&lt;/p&gt;&lt;p&gt;First of all I should point out that the process for using graphql-compose-mongoose is well documented in the readme of the library. To summarise, once a mongoose model has been defined it is necessary to define a detailed schema definition and resolvers for graphql. The schema definition and associated resolvers for graphql are a lot of work to write and maintain manually. Here is where this library steps in and helps you generate the types, input types, enumerations and resolvers. It really is quite the life-saver!&lt;/p&gt;&lt;p&gt;I was curious however, as to whether I could include it on top of the schema that I had already defined (see previous blog post). After googling around for a way to merge schemas I found out that it was available from the graphql-tools library that I was already using. So I was able to really easily.&lt;/p&gt;
&lt;pre style=&quot;border-radius: 4px; border: 1px solid rgb(204, 204, 204); box-sizing: border-box; line-height: 1.42857; margin-bottom: 10px; overflow-wrap: break-word; overflow: auto; padding: 9.5px; word-break: break-all;&quot;&gt;&lt;span style=&quot;font-family: consolas; font-size: x-small;&quot;&gt;import gqlTools from &#39;graphql-tools&#39;;
import gqlCompose from &#39;graphql-compose&#39;;
import monCompose from &#39;graphql-compose-mongoose&#39;;
&lt;/span&gt;&lt;/pre&gt;&lt;pre style=&quot;border-radius: 4px; border: 1px solid rgb(204, 204, 204); box-sizing: border-box; line-height: 1.42857; margin-bottom: 10px; overflow-wrap: break-word; overflow: auto; padding: 9.5px; word-break: break-all;&quot;&gt;&lt;span style=&quot;font-family: consolas; font-size: x-small;&quot;&gt;const competitionTC = monCompose.composeMongoose(customModel, {});

gqlCompose.schemaComposer.Query.addFields({
	competitions:&lt;/span&gt;&lt;span style=&quot;font-family: consolas;&quot;&gt; &lt;/span&gt;competitionTC.mongooseResolvers.findMany(),&lt;br /&gt;&lt;span style=&quot;font-family: consolas; font-size: x-small;&quot;&gt;});

const graphqlSchemaFromMongoose = gqlCompose.schemaComposer.buildSchema();

const existingSchema = gqlTools.makeExecutableSchema({
        alreadyExistingTypeDefs,
        alreadyExistingResolvers,
    });

const allSchemas = gqlTools.mergeSchemas({
                 schemas: [ existingSchema, graphqlSchemaFromMongoose ] 
             });&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;This code works beautifully, although it almost feels like it shouldn&#39;t. There is a lot going on and I found myself wondering whether it was all necessary.&amp;nbsp;&lt;/p&gt;&lt;p&gt;In the graphql UI the competitionTC now has a much more complete filter than the one I had before and skip, limit and sort also work great.&lt;/p&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/AVvXsEhHnMZQ3vPbCbB6Y_JCeNlXxk_DfKg26rRRr6Td7R_NIcs4CVY7tZZv-ry6IFXkxI0y_udEmoU_T9ibN2M0tqYRWIltUYOv7vmK-JopZfrkWVW9RXUAsSAVt-Y-ZHmFNwgktDvMitZv1ks/s481/competitions.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;454&quot; data-original-width=&quot;481&quot; height=&quot;247&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHnMZQ3vPbCbB6Y_JCeNlXxk_DfKg26rRRr6Td7R_NIcs4CVY7tZZv-ry6IFXkxI0y_udEmoU_T9ibN2M0tqYRWIltUYOv7vmK-JopZfrkWVW9RXUAsSAVt-Y-ZHmFNwgktDvMitZv1ks/w261-h247/competitions.png&quot; width=&quot;261&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;p&gt;But, the code is messy 😉. Do I really need those extra scalar types?&lt;/p&gt;&lt;p&gt;&lt;i&gt;&lt;b&gt;Something went wrong&amp;nbsp; Error: Unknown type &quot;Date&quot;.&lt;/b&gt;&lt;/i&gt;&lt;/p&gt;&lt;p&gt;OK then, turns out this is the best solution for now! It produces really complete GraphQL queries and mutations with very little effort.&lt;/p&gt;&lt;p&gt;Resources and references:&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://hasura.io/blog/the-ultimate-guide-to-schema-stitching-in-graphql-f30178ac0072/#e8ba&quot;&gt;The ultimate guide to schema stitching in GraphQL&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/graphql-compose/graphql-compose-mongoose&quot;&gt;graphql-compose-mongoose&lt;/a&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://garethscode.blogspot.com/feeds/1331556879015152380/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://garethscode.blogspot.com/2020/10/when-writing-schema-for-graphql-gets-old.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3311430580289688408/posts/default/1331556879015152380'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3311430580289688408/posts/default/1331556879015152380'/><link rel='alternate' type='text/html' href='http://garethscode.blogspot.com/2020/10/when-writing-schema-for-graphql-gets-old.html' title='Generating a Schema for GraphQL'/><author><name>trujillo42</name><uri>http://www.blogger.com/profile/09625726405492153186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHnMZQ3vPbCbB6Y_JCeNlXxk_DfKg26rRRr6Td7R_NIcs4CVY7tZZv-ry6IFXkxI0y_udEmoU_T9ibN2M0tqYRWIltUYOv7vmK-JopZfrkWVW9RXUAsSAVt-Y-ZHmFNwgktDvMitZv1ks/s72-w261-h247-c/competitions.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3311430580289688408.post-5565201154111217418</id><published>2020-09-29T14:16:00.004-07:00</published><updated>2020-09-29T14:18:27.439-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="GraphQL"/><category scheme="http://www.blogger.com/atom/ns#" term="TypeScript"/><title type='text'>Defining a GraphQL Schema in TypeScript</title><content type='html'>&lt;h3 style=&quot;text-align: left;&quot;&gt;&lt;u&gt;Basic Example&lt;/u&gt;&lt;/h3&gt;&lt;p&gt;In the documentation you will see something like this:&lt;/p&gt;&lt;p&gt;&lt;u&gt;
  &lt;/u&gt;&lt;/p&gt;&lt;pre style=&quot;border-radius: 4px; border: 1px solid rgb(204, 204, 204); box-sizing: border-box; font-family: consolas; font-size: 13px; line-height: 1.42857; margin-bottom: 10px; overflow-wrap: break-word; overflow: auto; padding: 9.5px; word-break: break-all;&quot;&gt;  import graphQL from &#39;graphql&#39;;
  
  // Construct a schema using GraphQL schema language
  export default graphQL.buildSchema(`
    type Customer {
      dob: String
    }
  `);&lt;/pre&gt;&lt;div&gt;This is great for getting familiar with graphQL initially but what happens when I want to use a type that is not native? For instance, graphQL, out of the box, has only 4 &quot;scalar types&quot; - String, Int, Float and Boolean.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So what if I want to deal with a date from my data source? Well there are a few things to know: regardless of the storage format graphQL will change it to a &quot;Long Seconds&quot; number (actually the number of millisecond&#39;s elapsed since 01-01-1970). Sure you can plug that into new Date on the frontend, but it is a potentially unnecessary cost for the browser in terms of performance and would mean that we must rely on the consuming developer to remember to tidy up our dates.&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;&lt;u&gt;Diving in further&lt;/u&gt;&lt;/h3&gt;&lt;div&gt;Such a limited number of Scalar types in graphQL does seem to invite extension and so we have &quot;graphql-scalars&quot;. It does exactly what we want:&lt;/div&gt;
&lt;pre style=&quot;border-radius: 4px; border: 1px solid rgb(204, 204, 204); box-sizing: border-box; font-family: consolas; font-size: 13px; line-height: 1.42857; margin-bottom: 10px; overflow-wrap: break-word; overflow: auto; padding: 9.5px; word-break: break-all;&quot;&gt;{
    &quot;name&quot;: &quot;Lewis Kinsella&quot;,
    &quot;dob&quot;: &quot;1994-09-02&quot;
}&lt;/pre&gt;
&lt;p&gt;However, further inspection of the docs plus also the common &lt;a href=&quot;https://github.com/Urigo/graphql-scalars/blob/master/tests/Common.test.ts&quot;&gt;use case test in the code base&lt;/a&gt;&amp;nbsp;shows that this library works differently. Instead of using buildSchema we have &quot;makeExecutableSchema&quot; with some typeDefs and resolvers.&lt;/p&gt;
&lt;pre style=&quot;border-radius: 4px; border: 1px solid rgb(204, 204, 204); box-sizing: border-box; line-height: 1.42857; margin-bottom: 10px; overflow-wrap: break-word; overflow: auto; padding: 9.5px; word-break: break-all;&quot;&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;import gqlTools from &#39;graphql-tools&#39;;

const schema = gqlTools.makeExecutableSchema({
	typeDefs,
	resolvers,
});&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;So how do I change my existing work to fit with this?&lt;/p&gt;&lt;p&gt;Let&#39;s start at the end...&lt;/p&gt;&lt;pre style=&quot;border-radius: 4px; border: 1px solid rgb(204, 204, 204); box-sizing: border-box; line-height: 1.42857; margin-bottom: 10px; overflow-wrap: break-word; overflow: auto; padding: 9.5px; word-break: break-all;&quot;&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;app.use(&#39;/graphql&#39;, graphqlHTTP({
	schema
});&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;&lt;p&gt;It looks like resolvers are no longer added as the &quot;root value&quot; argument in the graphqlHTTP object.&lt;/p&gt;&lt;p&gt;Instead we are adding the schema object only. How do we make that?&lt;/p&gt;&lt;pre style=&quot;border-radius: 4px; border: 1px solid rgb(204, 204, 204); box-sizing: border-box; line-height: 1.42857; margin-bottom: 10px; overflow-wrap: break-word; overflow: auto; padding: 9.5px; word-break: break-all;&quot;&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;const schema = gqlTools.makeExecutableSchema({
	typeDefs,
	resolvers,
});&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;The typeDefs here is mostly what we had before except now we need to merge in our extra scalar functionality.&lt;/p&gt;&lt;p&gt;a) resolvers are merged with the scalar tool resolvers.&lt;/p&gt;&lt;pre style=&quot;border-radius: 4px; border: 1px solid rgb(204, 204, 204); box-sizing: border-box; line-height: 1.42857; margin-bottom: 10px; overflow-wrap: break-word; overflow: auto; padding: 9.5px; word-break: break-all;&quot;&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;const resolvers = gqlTools.mergeResolvers([root, scalarResolvers.resolvers]);&lt;/span&gt;&lt;/pre&gt;

and&lt;div&gt;b)&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;pre style=&quot;border-radius: 4px; border: 1px solid rgb(204, 204, 204); box-sizing: border-box; line-height: 1.42857; margin-bottom: 10px; overflow-wrap: break-word; overflow: auto; padding: 9.5px; word-break: break-all;&quot;&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;const typeDefs = merge.mergeTypeDefs([customTypeDefs, ...scalarTypeDefs.typeDefs]);&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;Where customTypeDefs is what we had at the beginning, no need to change it, except to add some extra scalar types!&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;pre style=&quot;border-radius: 4px; border: 1px solid rgb(204, 204, 204); box-sizing: border-box; font-family: consolas; font-size: 13px; line-height: 1.42857; margin-bottom: 10px; overflow-wrap: break-word; overflow: auto; padding: 9.5px; word-break: break-all;&quot;&gt; import graphQL from &#39;graphql&#39;;
  
  // Construct a schema using GraphQL schema language
  export default graphQL.buildSchema(`
    type Customer {
      dob: Date
    }
  `);&lt;/pre&gt;&lt;/div&gt;

Happy graphQL-ing in TypeScript with Scalar types!</content><link rel='replies' type='application/atom+xml' href='http://garethscode.blogspot.com/feeds/5565201154111217418/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://garethscode.blogspot.com/2020/09/defining-graphql-schema-in-typescript.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3311430580289688408/posts/default/5565201154111217418'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3311430580289688408/posts/default/5565201154111217418'/><link rel='alternate' type='text/html' href='http://garethscode.blogspot.com/2020/09/defining-graphql-schema-in-typescript.html' title='Defining a GraphQL Schema in TypeScript'/><author><name>trujillo42</name><uri>http://www.blogger.com/profile/09625726405492153186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3311430580289688408.post-519868115089498723</id><published>2020-09-09T08:08:00.002-07:00</published><updated>2020-09-09T08:08:18.770-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Azure"/><category scheme="http://www.blogger.com/atom/ns#" term="Functions"/><category scheme="http://www.blogger.com/atom/ns#" term="node"/><category scheme="http://www.blogger.com/atom/ns#" term="NodeJS"/><title type='text'>Azure Functions with TypeScript</title><content type='html'>Things to know about using TypeScript with Azure functions:

&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;ol style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Make sure that you have node installed using the latest LTS version (Long Term Support). If you need the latest version for other projects try using&amp;nbsp;&lt;a href=&quot;https://github.com/coreybutler/nvm-windows&quot;&gt;nvm&lt;/a&gt;-windows&amp;nbsp;to manage multiple versions of Node. Install the latest version of nvm using the zip file in assets of the &lt;a href=&quot;https://github.com/coreybutler/nvm-windows/releases&quot;&gt;latest release&lt;/a&gt;. nvm list and then nvm use. Also nvm install v 64/32bit is pretty nifty.&lt;/li&gt;&lt;li&gt;To run Azure functions manually (particularly useful for timers etc.. anything that is not an Http Trigger). http://localhost:&amp;lt;port&amp;gt;/admin/functions/&amp;lt;FunctionName&amp;gt;. Also for &lt;a href=&quot;https://arminreiter.com/2017/02/azure-functions-time-trigger-cron-cheat-sheet/&quot;&gt;CRON timings see this cheatsheet&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;Azure Functions in TypeScript still use CommonJS modules, so while you can use imports and exports in your code the transpiled JS will be using Node style modules. Bear this in mind if you are expecting to be able to use any of your own libraries that compile to anything other than CommonJS. Check your TSConfig.&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;So is TypeScript support any good? So far it seems good, the only problems are with my own libraries. I have also noticed that you cannot use fat-arrows for Azure Index functions (for those not so familiar - the entry point called by Azure infrastructure).&lt;/div&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://garethscode.blogspot.com/feeds/519868115089498723/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://garethscode.blogspot.com/2020/09/azure-functions-with-typescript.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3311430580289688408/posts/default/519868115089498723'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3311430580289688408/posts/default/519868115089498723'/><link rel='alternate' type='text/html' href='http://garethscode.blogspot.com/2020/09/azure-functions-with-typescript.html' title='Azure Functions with TypeScript'/><author><name>trujillo42</name><uri>http://www.blogger.com/profile/09625726405492153186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3311430580289688408.post-605014700139486742</id><published>2020-05-22T11:57:00.001-07:00</published><updated>2020-05-22T11:57:46.976-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="CRA"/><category scheme="http://www.blogger.com/atom/ns#" term="Jest"/><category scheme="http://www.blogger.com/atom/ns#" term="React"/><category scheme="http://www.blogger.com/atom/ns#" term="TypeScript"/><title type='text'>Jest-diff Issue after upgrading react-scripts</title><content type='html'>&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;A project I have been working on recently based on CRA (create-react-app) for TypeScript needed a large jump upgrade (3.1.1 to 3.4.0). Finally after working through a lot of other well documented problems I hit this one:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&#39;=&#39; expected. TS1005&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The error occuring in the file jest-diff line 1:&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;background-color: white; color: #6a737d; font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe UI&amp;quot;, Helvetica, Arial, sans-serif, &amp;quot;Apple Color Emoji&amp;quot;, &amp;quot;Segoe UI Emoji&amp;quot;; font-size: 14px;&quot;&gt;import type { DiffOptions } from &#39;./types&#39;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;background-color: white; color: #6a737d; font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe UI&amp;quot;, Helvetica, Arial, sans-serif, &amp;quot;Apple Color Emoji&amp;quot;, &amp;quot;Segoe UI Emoji&amp;quot;; font-size: 14px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;This was strange to me because I had not changed anything related to jest or my testing setup.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Luckily I was able to find this github issue:&amp;nbsp;&lt;a href=&quot;https://github.com/facebook/jest/issues/9703&quot;&gt;https://github.com/facebook/jest/issues/9703&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The user&amp;nbsp;&lt;a class=&quot;author link-gray-dark css-truncate-target width-fit&quot; data-hovercard-type=&quot;user&quot; data-hovercard-url=&quot;/users/paulconlin/hovercard&quot; data-octo-click=&quot;hovercard-link-click&quot; data-octo-dimensions=&quot;link_type:self&quot; href=&quot;https://github.com/paulconlin&quot; show_full_name=&quot;false&quot; style=&quot;box-sizing: border-box; color: #586069; display: inline-block; font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe UI&amp;quot;, Helvetica, Arial, sans-serif, &amp;quot;Apple Color Emoji&amp;quot;, &amp;quot;Segoe UI Emoji&amp;quot;; font-size: 14px; font-weight: 600; max-width: 125px; overflow: hidden; text-decoration-line: none; text-overflow: ellipsis; vertical-align: top; white-space: nowrap;&quot;&gt;paulconlin&lt;/a&gt;&amp;nbsp;got it spot on- I upgraded to TypeScript 3.8.3 and was able to compile again.&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://garethscode.blogspot.com/feeds/605014700139486742/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://garethscode.blogspot.com/2020/05/jest-diff-issue-after-upgrading-react.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3311430580289688408/posts/default/605014700139486742'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3311430580289688408/posts/default/605014700139486742'/><link rel='alternate' type='text/html' href='http://garethscode.blogspot.com/2020/05/jest-diff-issue-after-upgrading-react.html' title='Jest-diff Issue after upgrading react-scripts'/><author><name>trujillo42</name><uri>http://www.blogger.com/profile/09625726405492153186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3311430580289688408.post-9015058875241887471</id><published>2019-08-20T08:45:00.002-07:00</published><updated>2019-08-21T06:43:17.441-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="dotnet"/><category scheme="http://www.blogger.com/atom/ns#" term="excel"/><category scheme="http://www.blogger.com/atom/ns#" term="VSCode"/><title type='text'>Excel files with .NET Core</title><content type='html'>I found myself needing to quickly manipulate some data in an excel sheet.&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
I had no access to the full blown Visual Studio, no problems I thought, let&#39;s see what VSCode, the command line and .NetCore 2 can do.&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;https://docs.microsoft.com/en-us/dotnet/core/tutorials/with-visual-studio-code&quot;&gt;New project&lt;/a&gt;: &lt;a href=&quot;http://letmegooglethat.com/?q=create+a+new+dotnet+project+from+vscode&quot;&gt;no problem&lt;/a&gt;&lt;/div&gt;
Snideness aside it really is easy - just think of a project folder name...&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;dotnet new console&amp;nbsp;&lt;/li&gt;
&lt;li&gt;dotnet restore&lt;/li&gt;
&lt;li&gt;dotnet run&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;div&gt;
C# 7 has arrived... you no longer need to write this kind of madness:&lt;/div&gt;
&lt;pre style=&quot;border-radius: 4px; border: 1px solid rgb(204, 204, 204); box-sizing: border-box; font-family: consolas; font-size: 13px; line-height: 1.42857; margin-bottom: 10px; overflow-wrap: break-word; overflow: auto; padding: 9.5px; word-break: break-all;&quot;&gt;static Main&lt;span style=&quot;font-family: &amp;quot;consolas&amp;quot; , &amp;quot;courier new&amp;quot; , monospace; font-size: 14px;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: blue; font-family: &amp;quot;consolas&amp;quot; , &amp;quot;courier new&amp;quot; , monospace; font-size: 14px;&quot;&gt;string&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;consolas&amp;quot; , &amp;quot;courier new&amp;quot; , monospace; font-size: 14px;&quot;&gt;[]&lt;/span&gt; &lt;span style=&quot;font-family: &amp;quot;consolas&amp;quot; , &amp;quot;courier new&amp;quot; , monospace; font-size: 14px;&quot;&gt;args&lt;/span&gt;) {
&lt;span style=&quot;background-color: white;&quot;&gt;&amp;nbsp; thingIamDoing.RunAsync().GetAwaiter().GetResult();&amp;nbsp;&lt;/span&gt;
&lt;span style=&quot;background-color: white;&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;
&lt;br /&gt;
&lt;div&gt;
instead:&lt;/div&gt;
&lt;div style=&quot;background: white; border-radius: 4px; border: 1px solid rgb(204, 204, 204); box-sizing: border-box; font-family: consolas; font-size: 13px; line-height: 1.42857; margin-bottom: 10px; overflow-wrap: break-word; overflow: auto; padding: 9.5px; word-break: break-all;&quot;&gt;
&lt;div style=&quot;background-color: #1e1e1e; color: #d4d4d4; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 14px; line-height: 19px;&quot;&gt;
&lt;pre&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #569cd6;&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color: #569cd6;&quot;&gt;async&lt;/span&gt; &lt;span style=&quot;color: #4ec9b0;&quot;&gt;Task&lt;/span&gt; &lt;span style=&quot;color: #dcdcaa;&quot;&gt;Main&lt;/span&gt;(&lt;span style=&quot;color: #569cd6;&quot;&gt;string&lt;/span&gt;[] &lt;span style=&quot;color: #9cdcfe;&quot;&gt;args&lt;/span&gt;)
{
&lt;span style=&quot;color: #569cd6;&quot;&gt;   await&lt;/span&gt; &lt;span style=&quot;color: #9cdcfe;&quot;&gt;thingIamDoing&lt;/span&gt;();
}
&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
pleasing... but a&amp;nbsp;&lt;b&gt;caveat&lt;/b&gt;&amp;nbsp;- you must specify&amp;nbsp;&lt;span style=&quot;background-color: #1e1e1e; color: #569cd6; font-family: &amp;quot;consolas&amp;quot; , &amp;quot;courier new&amp;quot; , monospace; font-size: 14px; white-space: pre;&quot;&gt;LangVersion&lt;/span&gt;&amp;nbsp; in the csproj as latest to use this:&lt;br /&gt;
&lt;br /&gt;
&lt;pre style=&quot;border-radius: 4px; border: 1px solid rgb(204, 204, 204); box-sizing: border-box; font-family: consolas; font-size: 13px; line-height: 1.42857; margin-bottom: 10px; overflow-wrap: break-word; overflow: auto; padding: 9.5px; word-break: break-all;&quot;&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;Project&lt;/span&gt; &lt;span style=&quot;color: #9cdcfe;&quot;&gt;Sdk&lt;/span&gt;=&lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;Microsoft.NET.Sdk&quot;&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: grey;&quot;&gt;  &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;PropertyGroup&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: grey;&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;OutputType&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;gt;&lt;/span&gt;Exe&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;OutputType&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: grey;&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;TargetFramework&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;gt;&lt;/span&gt;netcoreapp2.0&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;TargetFramework&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: grey;&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;LangVersion&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;gt;&lt;/span&gt;latest&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;LangVersion&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: grey;&quot;&gt;  &amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;PropertyGroup&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;Project&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;
&lt;br /&gt;
nuget is yesterdays news... stop using it along with package.config.&lt;br /&gt;
&lt;br /&gt;
instead:&lt;br /&gt;
&lt;pre style=&quot;border-radius: 4px; border: 1px solid rgb(204, 204, 204); box-sizing: border-box; font-family: consolas; font-size: 13px; line-height: 1.42857; margin-bottom: 10px; overflow-wrap: break-word; overflow: auto; padding: 9.5px; word-break: break-all;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;times new roman&amp;quot;; font-size: small; white-space: normal;&quot;&gt;&lt;span style=&quot;background-color: white;&quot;&gt;dotnet add package EPPlus.Core&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
also pleasing... especially as it automatically adds the reference to the csproj:&lt;br /&gt;
&lt;pre&gt;&lt;div style=&quot;background-color: #1e1e1e; color: #d4d4d4; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 14px; line-height: 19px; white-space: pre;&quot;&gt;
&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;ItemGroup&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: grey;&quot;&gt;   &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;PackageReference&lt;/span&gt; &lt;span style=&quot;color: #9cdcfe;&quot;&gt;Include&lt;/span&gt;=&lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;EPPlus.Core&quot;&lt;/span&gt; &lt;span style=&quot;color: #9cdcfe;&quot;&gt;Version&lt;/span&gt;=&lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;1.5.4&quot;&lt;/span&gt; &lt;span style=&quot;color: grey;&quot;&gt;/&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;ItemGroup&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: grey;&quot;&gt;
&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;Project&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;/div&gt;
&lt;/pre&gt;
&lt;br /&gt;
so long package.config&lt;br /&gt;
&lt;br /&gt;
So now I have a library to help me read an xlsx file we can experiment. Can this library tell me how many columns and rows there are?&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;div style=&quot;background-color: #1e1e1e; color: #d4d4d4; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 14px; line-height: 19px; white-space: pre;&quot;&gt;
&lt;span style=&quot;color: #c586c0;&quot;&gt;using&lt;/span&gt; &lt;span style=&quot;color: #4ec9b0;&quot;&gt;System&lt;/span&gt;.&lt;span style=&quot;color: #4ec9b0;&quot;&gt;IO&lt;/span&gt;;
&lt;span style=&quot;color: #c586c0;&quot;&gt;using&lt;/span&gt; &lt;span style=&quot;color: #4ec9b0;&quot;&gt;System&lt;/span&gt;.&lt;span style=&quot;color: #4ec9b0;&quot;&gt;Text&lt;/span&gt;;
&lt;span style=&quot;color: #c586c0;&quot;&gt;using&lt;/span&gt; &lt;span style=&quot;color: #4ec9b0;&quot;&gt;System&lt;/span&gt;.&lt;span style=&quot;color: #4ec9b0;&quot;&gt;Threading&lt;/span&gt;.&lt;span style=&quot;color: #4ec9b0;&quot;&gt;Tasks&lt;/span&gt;;
&lt;span style=&quot;color: #c586c0;&quot;&gt;using&lt;/span&gt; &lt;span style=&quot;color: #4ec9b0;&quot;&gt;OfficeOpenXml&lt;/span&gt;;
...&lt;/div&gt;
&lt;/pre&gt;
&lt;pre style=&quot;border-radius: 4px; border: 1px solid rgb(204, 204, 204); box-sizing: border-box; font-family: consolas; font-size: 13px; line-height: 1.42857; margin-bottom: 10px; overflow-wrap: break-word; overflow: auto; padding: 9.5px; word-break: break-all;&quot;&gt;var sFileName = @&quot;test_file.xlsx&quot;;
FileInfo file = new FileInfo(Path.Combine(&quot;C:\\&quot;, sFileName));
var sb = new StringBuilder();

try
{
  using (ExcelPackage package = new ExcelPackage(file))
  {
    ExcelWorksheet worksheet = package.Workbook.Worksheets[4];
    var rowCount = worksheet.Dimension.Rows;
    var colCount = worksheet.Dimension.Columns;
    sb.Append($&quot;{colCount} rows: {rowCount}&quot;);
  }
} catch (Exception ex) {
  sb.Append($&quot;An error occurred while importing. {ex.Message}&quot;);
}

Console.WriteLine(sb.ToString());
&lt;/pre&gt;
&lt;br /&gt;
This gives me a result of 13 and 55 rows, which is what I expected.&lt;br /&gt;
Interesting to note:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;The API is not zero based, in the example test_file, there really are 4 worksheets&lt;/li&gt;
&lt;li&gt;If the excel spreadsheet is open, expect a file IO/lock error&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
Now I know the number of columns and rows we can simply iterate through the spreadsheet to read the data. e.g.&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre style=&quot;border-radius: 4px; border: 1px solid rgb(204, 204, 204); box-sizing: border-box; font-family: consolas; font-size: 13px; line-height: 1.42857; margin-bottom: 10px; overflow-wrap: break-word; overflow: auto; padding: 9.5px; word-break: break-all;&quot;&gt;var headerPrefix = &quot;headerPrefix_&quot;;

if (hasHeader) {
  headerPrefix = worksheet.Cells[1, col].Value.ToString();
}

for (int row = hasHeader ? 2 : 1; row &amp;lt;= rowCount; row++)
{
  if (worksheet.Cells[row, col].Value == null) continue;
  var newValue = worksheet.Cells[row, col].Value.ToString();
  
  &lt;/pre&gt;
&lt;div&gt;
&lt;br /&gt;
To export:&lt;br /&gt;
&lt;br /&gt;
&lt;pre style=&quot;border-radius: 4px; border: 1px solid rgb(204, 204, 204); box-sizing: border-box; font-family: consolas; font-size: 13px; line-height: 1.42857; margin-bottom: 10px; overflow-wrap: break-word; overflow: auto; padding: 9.5px; word-break: break-all;&quot;&gt;string fileName = @&quot;results.xlsx&quot;;
var exportfile = new FileInfo(Path.Combine(&quot;C:\\Code\\&quot;, fileName));

if (exportfile.Exists)
{
  exportfile.Delete();
  exportfile = new FileInfo(Path.Combine(&quot;C:\\Code\\&quot;, fileName));
}

using (ExcelPackage package = new ExcelPackage(exportfile))
{
  var worksheet = package.Workbook.Worksheets.Add(&quot;results&quot;);
  worksheet.Cells[1, 1].Value = &quot;Column 1&quot;;

  // continue on to fill out row data things here ....
  // once complete - save
  package.Save();
}
&lt;/pre&gt;
&lt;br /&gt;&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://garethscode.blogspot.com/feeds/9015058875241887471/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://garethscode.blogspot.com/2019/08/excel-files-with-net-core.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3311430580289688408/posts/default/9015058875241887471'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3311430580289688408/posts/default/9015058875241887471'/><link rel='alternate' type='text/html' href='http://garethscode.blogspot.com/2019/08/excel-files-with-net-core.html' title='Excel files with .NET Core'/><author><name>trujillo42</name><uri>http://www.blogger.com/profile/09625726405492153186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3311430580289688408.post-4264260160692692806</id><published>2019-08-05T09:54:00.000-07:00</published><updated>2020-02-02T09:56:06.875-08:00</updated><title type='text'>React: Key learning touch points</title><content type='html'>React itself is a powerful framework including a number of key techniques:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Higher Order Components and&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Children to solve prop-drilling&lt;/li&gt;
&lt;li&gt;Portals - modal story&lt;/li&gt;
&lt;li&gt;React Suspense and lazy:&amp;nbsp;&lt;a href=&quot;https://hackernoon.com/magic-of-react-suspense-with-concurrent-react-and-react-lazy-api-e32dc5f30ed1&quot;&gt;https://hackernoon.com/magic-of-react-suspense-with-concurrent-react-and-react-lazy-api-e32dc5f30ed1&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
Redux:&lt;/div&gt;
&lt;div&gt;
&lt;ul&gt;
&lt;li&gt;Saga&#39;s versus thunks... or both?&lt;/li&gt;
&lt;li&gt;Global versus local state... are you over-using redux?&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div&gt;
Other learning:&lt;/div&gt;
&lt;div&gt;
&lt;ul&gt;
&lt;li&gt;Remember that setState() can also take a function as a parameter:&lt;/li&gt;
&lt;code&gt;this.setState((prevState, props) 
              =&amp;gt; ({ ...prevState, answer}));&lt;/code&gt;
&lt;li&gt;setState() is asynchronous, if you call it in the component you cannot guarantee that local state has been updated immediately&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://garethscode.blogspot.com/feeds/4264260160692692806/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://garethscode.blogspot.com/2020/02/react-key-learning-touch-points.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3311430580289688408/posts/default/4264260160692692806'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3311430580289688408/posts/default/4264260160692692806'/><link rel='alternate' type='text/html' href='http://garethscode.blogspot.com/2020/02/react-key-learning-touch-points.html' title='React: Key learning touch points'/><author><name>trujillo42</name><uri>http://www.blogger.com/profile/09625726405492153186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3311430580289688408.post-5396856377430475426</id><published>2019-05-01T09:51:00.000-07:00</published><updated>2020-02-02T09:54:06.646-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript"/><category scheme="http://www.blogger.com/atom/ns#" term="Opinion"/><category scheme="http://www.blogger.com/atom/ns#" term="React"/><category scheme="http://www.blogger.com/atom/ns#" term="Redux"/><title type='text'>React: overkill with Redux and where Portals save the day</title><content type='html'>&lt;br /&gt;
&lt;br /&gt;
Recently I encountered a situation where I needed to overlay a div on top of another div. The standard way to do this is to use CSS and absolute or fixed positioning (&lt;a href=&quot;https://stackoverflow.com/questions/2941189/how-to-overlay-one-div-over-another-div&quot;&gt;https://stackoverflow.com/questions/2941189/how-to-overlay-one-div-over-another-div&lt;/a&gt;).&lt;br /&gt;
&lt;br /&gt;
Sounds simple enough, however I need to do this from within a deep hierarchy of elements:&lt;br /&gt;
&lt;br /&gt;
-&amp;gt; Detail Component&lt;br /&gt;
&amp;nbsp; -&amp;gt; Action Bar Component&lt;br /&gt;
&amp;nbsp; -&amp;gt; Items Component: Loop through and display expandable content divs&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;-&amp;gt; On Click : overlay a component which is a div containing &quot;expandable content&quot;&lt;br /&gt;
&lt;br /&gt;
The &quot;items&quot; component uses a standard bootstrap table to align the elements like so:&lt;br /&gt;
&lt;table style=&quot;border-color: black; width: 85%;&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;border: 1px solid black; padding: 8px 16px;&quot;&gt;item 1
&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; padding: 8px 16px;&quot;&gt;item 2
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;border: 1px solid black; padding: 8px 16px;&quot;&gt;item 3
&lt;/td&gt;
&lt;td style=&quot;border: 1px solid black; padding: 8px 16px;&quot;&gt;item 4
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;br /&gt;
This layout means that when you select the onClick() for &quot;item 1&quot; and you render the expandable component which is essentially just a div, and it is positioned relatively the the content will appear in place of item one in the table.&lt;br /&gt;
&lt;table style=&quot;border-color: black; width: 85%;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;border: 1px solid black; padding: 8px 16px;&quot;&gt;item 1&lt;br /&gt;
(expandable content)&lt;/td&gt;&lt;td style=&quot;border: 1px solid black; padding: 8px 16px;&quot;&gt;item 2&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style=&quot;border: 1px solid black; padding: 8px 16px;&quot;&gt;item 3&lt;/td&gt;&lt;td style=&quot;border: 1px solid black; padding: 8px 16px;&quot;&gt;item 4&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;div&gt;
Cut a long story short, every which way I tried to style the popup unwanted styles would be inherited from the table and other components above it. I also found that I had to place it absolutely to get the effect I was looking for which created a raft of further problems. Finally, it was suggested that this might be a good use case for React Portals which did indeed save the day.&lt;br /&gt;
&lt;br /&gt;
I also learned on this project how much Redux can be over utilized. &quot;When you have a hammer, everything starts to look like a nail&quot;. This was said a lot, and it should be, because when you are deep into the detail of a project it can be hard to see that it has been over-engineered.&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://garethscode.blogspot.com/feeds/5396856377430475426/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://garethscode.blogspot.com/2020/02/react-overkill-with-redux-and-where.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3311430580289688408/posts/default/5396856377430475426'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3311430580289688408/posts/default/5396856377430475426'/><link rel='alternate' type='text/html' href='http://garethscode.blogspot.com/2020/02/react-overkill-with-redux-and-where.html' title='React: overkill with Redux and where Portals save the day'/><author><name>trujillo42</name><uri>http://www.blogger.com/profile/09625726405492153186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3311430580289688408.post-7755054724480950381</id><published>2018-08-06T15:57:00.006-07:00</published><updated>2018-08-29T08:50:34.545-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Angular"/><category scheme="http://www.blogger.com/atom/ns#" term="Angular 6"/><category scheme="http://www.blogger.com/atom/ns#" term="PWA"/><title type='text'>Angular Progressive Web Apps</title><content type='html'>When in doubt refer to the&amp;nbsp;&lt;a href=&quot;https://angular.io/guide/service-worker-getting-started&quot;&gt;Offical docs&lt;/a&gt;.&amp;nbsp;When that doesn&#39;t work - try this manual fix it like I did!&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
Issues with Angular-cli&lt;/h3&gt;
&lt;div&gt;
First it turns out that using ng add, as below, doesn&#39;t work very well.&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;ng add @angular/pwa --project project_name&lt;/pre&gt;
&lt;br /&gt;
I thought that maybe these issues were due a change in the Angular app file hierarchy (I changed &quot;src&quot; to &quot;web&quot;). I don&#39;t think this was the problem because many other people got stuck on the same error &lt;a href=&quot;https://github.com/angular/angular-cli/issues/11640&quot;&gt;here&amp;nbsp;&lt;/a&gt;and &lt;a href=&quot;https://github.com/angular/angular-cli/issues/11666&quot;&gt;here&lt;/a&gt;.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Error highlighted below:&lt;/div&gt;
&lt;div&gt;
&lt;pre style=&quot;background-color: #f6f8fa; border-radius: 3px; box-sizing: border-box; color: #24292e; font-family: SFMono-Regular, Consolas, &amp;quot;Liberation Mono&amp;quot;, Menlo, Courier, monospace; font-size: 11.9px; line-height: 1.45; margin-bottom: 16px; overflow: auto; padding: 16px; word-wrap: normal;&quot;&gt;&lt;code style=&quot;background: transparent; border-radius: 3px; border: 0px; box-sizing: border-box; display: inline; font-family: SFMono-Regular, Consolas, &amp;quot;Liberation Mono&amp;quot;, Menlo, Courier, monospace; line-height: inherit; margin: 0px; overflow: visible; padding: 0px; word-break: normal; word-wrap: normal;&quot;&gt;Installing packages for tooling via npm.
+ @angular/pwa@0.7.2
added 2 packages in 12.443s
Installed packages for tooling via npm.
&lt;b&gt;Path &quot;/ngsw-config.json&quot; already exist.&lt;/b&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;
I was able to get going by looking to see what this process is suppose to do.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Luckily it doesn&#39;t do a great deal and it is possible to find the files by searching your node_module directory then pasting them in before changing the parameters to suit your project - for example: ngsw-config.json to the code root and manifest.json to the /src directory.&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;a href=&quot;https://blog.angulartraining.com/progressive-web-apps-for-angular-6-and-beyond-f7e4b9a2f9fa&quot;&gt;Check out this blog to see the exact steps that are being automated.&lt;/a&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
I was also able to better understand what the process should do by looking closely at this &lt;a href=&quot;https://github.com/yostane/pwa-angular6/commit/d7477911cd26762985941a742525ee20c7a42369&quot;&gt;git commit&lt;/a&gt;. Notice the process adds:&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;pl-s&quot; style=&quot;background-color: #e6ffed; box-sizing: border-box; color: #032f62; font-family: , &amp;quot;consolas&amp;quot; , &amp;quot;liberation mono&amp;quot; , &amp;quot;menlo&amp;quot; , &amp;quot;courier&amp;quot; , monospace; font-size: 12px; white-space: pre-wrap;&quot;&gt;&lt;span class=&quot;pl-pds&quot; style=&quot;box-sizing: border-box;&quot;&gt;&quot;&lt;/span&gt;buildOptimizer&lt;span class=&quot;pl-pds&quot; style=&quot;box-sizing: border-box;&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #e6ffed; color: #24292e; font-family: , &amp;quot;consolas&amp;quot; , &amp;quot;liberation mono&amp;quot; , &amp;quot;menlo&amp;quot; , &amp;quot;courier&amp;quot; , monospace; font-size: 12px; white-space: pre-wrap;&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;pl-c1&quot; style=&quot;background-color: #e6ffed; box-sizing: border-box; color: #005cc5; font-family: , &amp;quot;consolas&amp;quot; , &amp;quot;liberation mono&amp;quot; , &amp;quot;menlo&amp;quot; , &amp;quot;courier&amp;quot; , monospace; font-size: 12px; white-space: pre-wrap;&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;background-color: #e6ffed; color: #24292e; font-family: , &amp;quot;consolas&amp;quot; , &amp;quot;liberation mono&amp;quot; , &amp;quot;menlo&amp;quot; , &amp;quot;courier&amp;quot; , monospace; font-size: 12px; white-space: pre-wrap;&quot;&gt;,&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;pl-s&quot; style=&quot;background-color: #e6ffed; box-sizing: border-box; color: #032f62; font-family: , &amp;quot;consolas&amp;quot; , &amp;quot;liberation mono&amp;quot; , &amp;quot;menlo&amp;quot; , &amp;quot;courier&amp;quot; , monospace; font-size: 12px; white-space: pre-wrap;&quot;&gt;&lt;span class=&quot;pl-pds&quot; style=&quot;box-sizing: border-box;&quot;&gt;&quot;&lt;/span&gt;serviceWorker&lt;span class=&quot;pl-pds&quot; style=&quot;box-sizing: border-box;&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #e6ffed; color: #24292e; font-family: , &amp;quot;consolas&amp;quot; , &amp;quot;liberation mono&amp;quot; , &amp;quot;menlo&amp;quot; , &amp;quot;courier&amp;quot; , monospace; font-size: 12px; white-space: pre-wrap;&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;pl-c1&quot; style=&quot;background-color: #e6ffed; box-sizing: border-box; color: #005cc5; font-family: , &amp;quot;consolas&amp;quot; , &amp;quot;liberation mono&amp;quot; , &amp;quot;menlo&amp;quot; , &amp;quot;courier&amp;quot; , monospace; font-size: 12px; white-space: pre-wrap;&quot;&gt;true&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
to angular.json then adds the manifest.json before referencing it in the index.html:&lt;br /&gt;
&lt;div&gt;
&lt;span style=&quot;background-color: #e6ffed; color: #24292e; font-family: , &amp;quot;consolas&amp;quot; , &amp;quot;liberation mono&amp;quot; , &amp;quot;menlo&amp;quot; , &amp;quot;courier&amp;quot; , monospace; font-size: 12px; white-space: pre-wrap;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;pl-ent&quot; style=&quot;background-color: #e6ffed; box-sizing: border-box; color: #22863a; font-family: , &amp;quot;consolas&amp;quot; , &amp;quot;liberation mono&amp;quot; , &amp;quot;menlo&amp;quot; , &amp;quot;courier&amp;quot; , monospace; font-size: 12px; white-space: pre-wrap;&quot;&gt;link&lt;/span&gt;&lt;span style=&quot;background-color: #e6ffed; color: #24292e; font-family: , &amp;quot;consolas&amp;quot; , &amp;quot;liberation mono&amp;quot; , &amp;quot;menlo&amp;quot; , &amp;quot;courier&amp;quot; , monospace; font-size: 12px; white-space: pre-wrap;&quot;&gt; &lt;/span&gt;&lt;span class=&quot;pl-e&quot; style=&quot;background-color: #e6ffed; box-sizing: border-box; color: #6f42c1; font-family: , &amp;quot;consolas&amp;quot; , &amp;quot;liberation mono&amp;quot; , &amp;quot;menlo&amp;quot; , &amp;quot;courier&amp;quot; , monospace; font-size: 12px; white-space: pre-wrap;&quot;&gt;rel&lt;/span&gt;&lt;span style=&quot;background-color: #e6ffed; color: #24292e; font-family: , &amp;quot;consolas&amp;quot; , &amp;quot;liberation mono&amp;quot; , &amp;quot;menlo&amp;quot; , &amp;quot;courier&amp;quot; , monospace; font-size: 12px; white-space: pre-wrap;&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;pl-s&quot; style=&quot;background-color: #e6ffed; box-sizing: border-box; color: #032f62; font-family: , &amp;quot;consolas&amp;quot; , &amp;quot;liberation mono&amp;quot; , &amp;quot;menlo&amp;quot; , &amp;quot;courier&amp;quot; , monospace; font-size: 12px; white-space: pre-wrap;&quot;&gt;&lt;span class=&quot;pl-pds&quot; style=&quot;box-sizing: border-box;&quot;&gt;&quot;&lt;/span&gt;manifest&lt;span class=&quot;pl-pds&quot; style=&quot;box-sizing: border-box;&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #e6ffed; color: #24292e; font-family: , &amp;quot;consolas&amp;quot; , &amp;quot;liberation mono&amp;quot; , &amp;quot;menlo&amp;quot; , &amp;quot;courier&amp;quot; , monospace; font-size: 12px; white-space: pre-wrap;&quot;&gt; &lt;/span&gt;&lt;span class=&quot;pl-e&quot; style=&quot;background-color: #e6ffed; box-sizing: border-box; color: #6f42c1; font-family: , &amp;quot;consolas&amp;quot; , &amp;quot;liberation mono&amp;quot; , &amp;quot;menlo&amp;quot; , &amp;quot;courier&amp;quot; , monospace; font-size: 12px; white-space: pre-wrap;&quot;&gt;href&lt;/span&gt;&lt;span style=&quot;background-color: #e6ffed; color: #24292e; font-family: , &amp;quot;consolas&amp;quot; , &amp;quot;liberation mono&amp;quot; , &amp;quot;menlo&amp;quot; , &amp;quot;courier&amp;quot; , monospace; font-size: 12px; white-space: pre-wrap;&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;pl-s&quot; style=&quot;background-color: #e6ffed; box-sizing: border-box; color: #032f62; font-family: , &amp;quot;consolas&amp;quot; , &amp;quot;liberation mono&amp;quot; , &amp;quot;menlo&amp;quot; , &amp;quot;courier&amp;quot; , monospace; font-size: 12px; white-space: pre-wrap;&quot;&gt;&lt;span class=&quot;pl-pds&quot; style=&quot;box-sizing: border-box;&quot;&gt;&quot;&lt;/span&gt;manifest.json&lt;span class=&quot;pl-pds&quot; style=&quot;box-sizing: border-box;&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #e6ffed; color: #24292e; font-family: , &amp;quot;consolas&amp;quot; , &amp;quot;liberation mono&amp;quot; , &amp;quot;menlo&amp;quot; , &amp;quot;courier&amp;quot; , monospace; font-size: 12px; white-space: pre-wrap;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;background-color: #e6ffed; color: #24292e; font-family: , &amp;quot;consolas&amp;quot; , &amp;quot;liberation mono&amp;quot; , &amp;quot;menlo&amp;quot; , &amp;quot;courier&amp;quot; , monospace; font-size: 12px; white-space: pre-wrap;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;pl-ent&quot; style=&quot;background-color: #e6ffed; box-sizing: border-box; color: #22863a; font-family: , &amp;quot;consolas&amp;quot; , &amp;quot;liberation mono&amp;quot; , &amp;quot;menlo&amp;quot; , &amp;quot;courier&amp;quot; , monospace; font-size: 12px; white-space: pre-wrap;&quot;&gt;meta&lt;/span&gt;&lt;span style=&quot;background-color: #e6ffed; color: #24292e; font-family: , &amp;quot;consolas&amp;quot; , &amp;quot;liberation mono&amp;quot; , &amp;quot;menlo&amp;quot; , &amp;quot;courier&amp;quot; , monospace; font-size: 12px; white-space: pre-wrap;&quot;&gt; &lt;/span&gt;&lt;span class=&quot;pl-e&quot; style=&quot;background-color: #e6ffed; box-sizing: border-box; color: #6f42c1; font-family: , &amp;quot;consolas&amp;quot; , &amp;quot;liberation mono&amp;quot; , &amp;quot;menlo&amp;quot; , &amp;quot;courier&amp;quot; , monospace; font-size: 12px; white-space: pre-wrap;&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;background-color: #e6ffed; color: #24292e; font-family: , &amp;quot;consolas&amp;quot; , &amp;quot;liberation mono&amp;quot; , &amp;quot;menlo&amp;quot; , &amp;quot;courier&amp;quot; , monospace; font-size: 12px; white-space: pre-wrap;&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;pl-s&quot; style=&quot;background-color: #e6ffed; box-sizing: border-box; color: #032f62; font-family: , &amp;quot;consolas&amp;quot; , &amp;quot;liberation mono&amp;quot; , &amp;quot;menlo&amp;quot; , &amp;quot;courier&amp;quot; , monospace; font-size: 12px; white-space: pre-wrap;&quot;&gt;&lt;span class=&quot;pl-pds&quot; style=&quot;box-sizing: border-box;&quot;&gt;&quot;&lt;/span&gt;theme-color&lt;span class=&quot;pl-pds&quot; style=&quot;box-sizing: border-box;&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #e6ffed; color: #24292e; font-family: , &amp;quot;consolas&amp;quot; , &amp;quot;liberation mono&amp;quot; , &amp;quot;menlo&amp;quot; , &amp;quot;courier&amp;quot; , monospace; font-size: 12px; white-space: pre-wrap;&quot;&gt; &lt;/span&gt;&lt;span class=&quot;pl-e&quot; style=&quot;background-color: #e6ffed; box-sizing: border-box; color: #6f42c1; font-family: , &amp;quot;consolas&amp;quot; , &amp;quot;liberation mono&amp;quot; , &amp;quot;menlo&amp;quot; , &amp;quot;courier&amp;quot; , monospace; font-size: 12px; white-space: pre-wrap;&quot;&gt;content&lt;/span&gt;&lt;span style=&quot;background-color: #e6ffed; color: #24292e; font-family: , &amp;quot;consolas&amp;quot; , &amp;quot;liberation mono&amp;quot; , &amp;quot;menlo&amp;quot; , &amp;quot;courier&amp;quot; , monospace; font-size: 12px; white-space: pre-wrap;&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;pl-s&quot; style=&quot;background-color: #e6ffed; box-sizing: border-box; color: #032f62; font-family: , &amp;quot;consolas&amp;quot; , &amp;quot;liberation mono&amp;quot; , &amp;quot;menlo&amp;quot; , &amp;quot;courier&amp;quot; , monospace; font-size: 12px; white-space: pre-wrap;&quot;&gt;&lt;span class=&quot;pl-pds&quot; style=&quot;box-sizing: border-box;&quot;&gt;&quot;&lt;/span&gt;#1976d2&lt;span class=&quot;pl-pds&quot; style=&quot;box-sizing: border-box;&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #e6ffed; color: #24292e; font-family: , &amp;quot;consolas&amp;quot; , &amp;quot;liberation mono&amp;quot; , &amp;quot;menlo&amp;quot; , &amp;quot;courier&amp;quot; , monospace; font-size: 12px; white-space: pre-wrap;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;h3&gt;
Issues with testing service workers locally (A bad HTTP response code (404) was received when fetching the script)&lt;/h3&gt;
&lt;div&gt;
This is a message you are will most likely see when you are attempting use the angular cli server and PWA. Probably running:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;pre&gt;ng serve --prod&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
This is again a heavily documented issue yet that didn&#39;t stop me scratching my head.&lt;br /&gt;
&lt;br /&gt;
ng serve will not run the required service worker compilation only ng build will do that - &lt;a href=&quot;https://github.com/angular/angular-cli/issues/8779&quot;&gt;see&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
This article also goes on to explain that only secure origins are allowed for service workers. Please consider whether it is worth the time to get this working too. The chances are that the project will work on a secure, encrypted site already now, if deployed.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Finally, you may get &quot;ngsw.json cannot be found&quot; or &quot;manifest.json cannot be found&quot;. This can be remedied in Azure at least by allowing JSON MIME type to be served by the web server. Bear in mind that any other JSON in your dist directory will also be accessible.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;pre&gt;&amp;lt;configuration&amp;gt;
    &amp;lt;system.webServer&amp;gt;
        &amp;lt;staticContent&amp;gt;
            &amp;lt;mimeMap fileExtension=&quot;.json&quot; mimeType=&quot;application/json&quot; /&amp;gt;
     &amp;lt;/staticContent&amp;gt;
    &amp;lt;/system.webServer&amp;gt;
&amp;lt;/configuration&amp;gt; &lt;/pre&gt;
&lt;/div&gt;
&lt;h3&gt;
Is it true that service workers only work with transport layer security (TLS or SSL)&lt;/h3&gt;
&lt;div&gt;
No, you can run locally with a local node instance. You can also run chrome with parameters to tell it to always consider localhost secure if you find issues with that. See the official documentation.&lt;/div&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://garethscode.blogspot.com/feeds/7755054724480950381/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://garethscode.blogspot.com/2018/08/angular-pwa-issue-bad-http-response.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3311430580289688408/posts/default/7755054724480950381'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3311430580289688408/posts/default/7755054724480950381'/><link rel='alternate' type='text/html' href='http://garethscode.blogspot.com/2018/08/angular-pwa-issue-bad-http-response.html' title='Angular Progressive Web Apps'/><author><name>trujillo42</name><uri>http://www.blogger.com/profile/09625726405492153186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3311430580289688408.post-3586441179556063722</id><published>2018-02-19T06:55:00.000-08:00</published><updated>2018-03-02T14:29:43.670-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Angular"/><category scheme="http://www.blogger.com/atom/ns#" term="Angular Material"/><category scheme="http://www.blogger.com/atom/ns#" term="Md2"/><title type='text'>The jump between Angular Material 2 Beta 10 and Material Beta 11+</title><content type='html'>Having just been through this experience I thought I would share some thoughts to help any other early Angular Material adopters navigate their way to the later Beta&#39;s - 11 and 12 as well as the subsequent&amp;nbsp;release candidates.&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;&lt;b&gt;Change 1&lt;/b&gt;&lt;/u&gt;&lt;br /&gt;
Angular Material no longer can be imported into your project as just one module. You must instead select all of the modules which you intend to use in the project.&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;&lt;b&gt;Change 2 - seemingly innocuous..&lt;/b&gt;&lt;/u&gt;&lt;br /&gt;
The problem with upgrading between these two versions is that the Md prefix has been changed to Mat. This unfortunately now clashes with the AngularJS Material implementation... such as Md2.&lt;br /&gt;
&lt;br /&gt;
We were early adopters of Angular Material, so we are still using &lt;a href=&quot;https://github.com/Promact/md2&quot;&gt;Md2 by Promact&lt;/a&gt;. Originally this was used&amp;nbsp;as a stopgap while essential components like the date-picker were being completed by the official Angular Material team. However, now, we wish to use both Md2 and Angular Material side by side. Especially since I was originally putting together the project with Angular 4.0.1 and now wish to upgrade to the latest.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;background-color: white; box-sizing: border-box; color: #24292e; font-family: , &amp;quot;blinkmacsystemfont&amp;quot; , &amp;quot;segoe ui&amp;quot; , &amp;quot;helvetica&amp;quot; , &amp;quot;arial&amp;quot; , sans-serif , &amp;quot;apple color emoji&amp;quot; , &amp;quot;segoe ui emoji&amp;quot; , &amp;quot;segoe ui symbol&amp;quot;; font-size: 14px; font-weight: 600;&quot;&gt;ERROR Error: Uncaught (in promise): Error: The &quot;mat-&quot; prefix cannot be used in ng-material v1 compatibility mode.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
To get around this you must use the&amp;nbsp;&quot;CompatibilityModule&quot; or&amp;nbsp;&quot;NoConflictStyleCompatibilityMode&quot; or something...?&lt;br /&gt;
&lt;div class=&quot;timeline-comment-header clearfix&quot; style=&quot;background-color: #f6f8fa; border-bottom: 1px solid rgb(209, 213, 218); border-top-left-radius: 3px; border-top-right-radius: 3px; box-sizing: border-box; color: #586069; font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe UI&amp;quot;, Helvetica, Arial, sans-serif, &amp;quot;Apple Color Emoji&amp;quot;, &amp;quot;Segoe UI Emoji&amp;quot;, &amp;quot;Segoe UI Symbol&amp;quot;; font-size: 14px; padding-left: 15px; padding-right: 15px;&quot;&gt;
&lt;h3 class=&quot;timeline-comment-header-text f5 text-normal&quot; style=&quot;box-sizing: border-box; font-size: 14px !important; font-weight: 400 !important; margin-bottom: 0px; margin-top: 0px; max-width: 78%; padding-bottom: 10px; padding-top: 10px;&quot;&gt;
&lt;span style=&quot;box-sizing: border-box; font-weight: 600;&quot;&gt;&lt;a class=&quot;author text-inherit&quot; href=&quot;https://github.com/jatkeshave&quot; style=&quot;background-color: transparent; box-sizing: border-box; color: #586069; outline-width: 0px;&quot;&gt;jatkeshave&lt;/a&gt;&amp;nbsp;&lt;/span&gt;commented&amp;nbsp;&lt;a class=&quot;timestamp&quot; href=&quot;https://github.com/Teradata/covalent/issues/923#issuecomment-335595082&quot; style=&quot;background-color: transparent; box-sizing: border-box; text-decoration-line: none; white-space: nowrap;&quot;&gt;on Oct 10, 2017&lt;/a&gt;&lt;/h3&gt;
&lt;/div&gt;
&lt;div class=&quot;edit-comment-hide&quot; style=&quot;box-sizing: border-box; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe UI&amp;quot;, Helvetica, Arial, sans-serif, &amp;quot;Apple Color Emoji&amp;quot;, &amp;quot;Segoe UI Emoji&amp;quot;, &amp;quot;Segoe UI Symbol&amp;quot;; font-size: 14px;&quot;&gt;
&lt;table class=&quot;d-block&quot; style=&quot;border-collapse: collapse; border-spacing: 0px; box-sizing: border-box; display: block !important;&quot;&gt;&lt;tbody class=&quot;d-block&quot; style=&quot;box-sizing: border-box; display: block !important;&quot;&gt;
&lt;tr class=&quot;d-block&quot; style=&quot;box-sizing: border-box; display: block !important;&quot;&gt;&lt;td class=&quot;d-block comment-body markdown-body  js-comment-body&quot; style=&quot;box-sizing: border-box; display: block !important; font-size: 14px; line-height: 1.5; overflow: visible; padding: 15px; width: 698px; word-wrap: break-word;&quot;&gt;&lt;div style=&quot;box-sizing: border-box; margin-bottom: 16px;&quot;&gt;
use compatibility module if you still want to use md- prefix like this&lt;br /&gt;
&lt;code style=&quot;background-color: rgba(27, 31, 35, 0.05); border-radius: 3px; box-sizing: border-box; font-family: SFMono-Regular, Consolas, &amp;quot;Liberation Mono&amp;quot;, Menlo, Courier, monospace; font-size: 11.9px; margin: 0px; padding: 0.2em 0.4em;&quot;&gt;import { CompatibilityModule } from &#39;@angular/material&#39;;&lt;/code&gt;&lt;br /&gt;
and import it in app module&lt;/div&gt;
&lt;div style=&quot;box-sizing: border-box; margin-bottom: 16px;&quot;&gt;
if you want to use new mat- prefix which is good you can&lt;br /&gt;
use NoConflictStyleCompatibilityMode like this&lt;br /&gt;
&lt;code style=&quot;background-color: rgba(27, 31, 35, 0.05); border-radius: 3px; box-sizing: border-box; font-family: SFMono-Regular, Consolas, &amp;quot;Liberation Mono&amp;quot;, Menlo, Courier, monospace; font-size: 11.9px; margin: 0px; padding: 0.2em 0.4em;&quot;&gt;import {NoConflictStyleCompatibilityMode} from &#39;@angular/material&#39;;&lt;/code&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
When I first read this comment I was still confused. I just want my solution to work - what is all this!? This comment further down these thread helped me to understand:&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;https://github.com/Teradata/covalent/issues/923&quot;&gt;Issue 1 thread&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;https://github.com/Promact/md2/issues/290#issuecomment-336530401&quot;&gt;Issue 2 thread and relevent comment&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
I tried importing from material itself but this did not clear the errors.
&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;import { NoConflictStyleCompatibilityMode } from &#39;@angular/material&#39;;
&lt;/pre&gt;
&lt;br /&gt;
Instead the solution seems to be to import and therefore invoke the NoConflictStleCompatibilityMode from MD2.
&lt;br /&gt;
&lt;pre&gt;import { Md2Module, NoConflictStyleCompatibilityMode } from &#39;md2&#39;;
&lt;/pre&gt;
&lt;br /&gt;
This makes sense because the use of mat in an angular/material v1 context can no only be in the&amp;nbsp;MD2 project.</content><link rel='replies' type='application/atom+xml' href='http://garethscode.blogspot.com/feeds/3586441179556063722/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://garethscode.blogspot.com/2018/02/the-upgrade-journeyjump-between-angular.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3311430580289688408/posts/default/3586441179556063722'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3311430580289688408/posts/default/3586441179556063722'/><link rel='alternate' type='text/html' href='http://garethscode.blogspot.com/2018/02/the-upgrade-journeyjump-between-angular.html' title='The jump between Angular Material 2 Beta 10 and Material Beta 11+'/><author><name>trujillo42</name><uri>http://www.blogger.com/profile/09625726405492153186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3311430580289688408.post-4779346181133349984</id><published>2017-04-12T09:45:00.000-07:00</published><updated>2020-02-02T09:46:07.311-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Babel"/><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript"/><category scheme="http://www.blogger.com/atom/ns#" term="React"/><category scheme="http://www.blogger.com/atom/ns#" term="Webpack"/><category scheme="http://www.blogger.com/atom/ns#" term="Yarn"/><title type='text'>Checking Out React</title><content type='html'>I started my journey at the &lt;a href=&quot;https://facebook.github.io/react/tutorial/tutorial.html&quot;&gt;React Tutorial Page&lt;/a&gt;. While reading the introduction and checking out the code example on Codepen, I then had the notion that seeing as it was a Tic-Tac-Toe game, it might be nice to do it more properly and include it on my website.&lt;br /&gt;
&lt;br /&gt;
Once down this road I then decided it would be good to turn it into a mini project to find out more about &lt;a href=&quot;https://yarnpkg.com/&quot;&gt;yarn&lt;/a&gt; and &lt;a href=&quot;https://webpack.github.io/&quot;&gt;webpack&lt;/a&gt;, as these compliment the React world and are the shiny new toys in front-end web development.&lt;br /&gt;
&lt;br /&gt;
This first blog in the series is about the setup.&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;Notes on Yarn and WebPack&lt;/u&gt;&lt;br /&gt;
I have heard that Yarn is better than NPM as a package manager, it is faster and more reliable. Webpack is more complex/flexible than Grunt or Gulp as a builder tool but, like my personal favourite&amp;nbsp;&lt;a href=&quot;https://ilikekillnerds.com/2015/07/jspm-vs-webpack/&quot;&gt;JSPM&lt;/a&gt;&amp;nbsp;(through &lt;a href=&quot;https://github.com/systemjs/systemjs&quot;&gt;systemJS&lt;/a&gt;) it is an excellent JavaScript module loader out of the box. Webpack is much more popular than JSPM within the React community.&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;Back to Tick-Tac-Toe&lt;/u&gt;&lt;br /&gt;
So I used npm to install yarn, ran yarn init and then used it to bring down my dependencies React and React DOM. I was pleased to find that there is no difference in where the modules are stored - it is still in a folder called &quot;node_modules&quot;. I was also aware that I needed to &quot;transpile&quot; the ES2015 React code into ES5 so I installed babel using the &quot;webpack&quot; option on &lt;a href=&quot;https://babeljs.io/docs/setup/#installation&quot;&gt;the babel installation page&lt;/a&gt;.&lt;br /&gt;
&lt;pre class=&quot;highlight&quot; style=&quot;-webkit-font-smoothing: antialiased; background: rgb(253, 250, 235); border-radius: 0px; border: none; box-shadow: none; box-sizing: border-box; color: #323330; font-family: &amp;quot;Operator Mono&amp;quot;, &amp;quot;Fira Code&amp;quot;, &amp;quot;Ubuntu Mono&amp;quot;, &amp;quot;Droid Sans Mono&amp;quot;, &amp;quot;Liberation Mono&amp;quot;, &amp;quot;Source Code Pro&amp;quot;, Menlo, Monaco, Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 13px; line-height: 1.42857; margin-bottom: 10px; overflow: auto; padding: 1em; word-break: break-all; word-wrap: break-word;&quot;&gt;&lt;code style=&quot;-webkit-font-smoothing: antialiased; background-color: transparent; border-radius: 0px; box-sizing: border-box; color: inherit; font-family: &amp;quot;Operator Mono&amp;quot;, &amp;quot;Fira Code&amp;quot;, &amp;quot;Ubuntu Mono&amp;quot;, &amp;quot;Droid Sans Mono&amp;quot;, &amp;quot;Liberation Mono&amp;quot;, &amp;quot;Source Code Pro&amp;quot;, Menlo, Monaco, Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: inherit; padding: 0px; white-space: pre-wrap;&quot;&gt;npm install --save-dev babel-loader babel-core&lt;/code&gt;&lt;/pre&gt;
Notice that this is based on npm, but this was no problem, you can just replace &quot;npm install&quot; with &quot;yarn add&quot; and the command &quot;--save-dev&quot; with &quot;-D&quot;. This was all easy to &lt;a href=&quot;https://yarnpkg.com/en/docs/migrating-from-npm&quot;&gt;find here&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;Using Webpack to transpile ES2015 back down to ES5&lt;/u&gt;&lt;br /&gt;
After some research I have found that the best way to use Webpack with babel, karma and react is to use the following packages:&lt;br /&gt;
&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/AVvXsEgXl-HmPk_4MXNuj8gw3K1nKr0AsxEZsCKibQTGk6C7lfJjaIo0Hf2JFlLmiYufFOdmJ0C8gmWLOZV3SfShKUy0t-RjgQb03js-G6DPgmfBBFVAi4g8vF9e1UDD6vSD-KfnNHQs7MuQTO4/s1600/reactWithwebpackPackages.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;120&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXl-HmPk_4MXNuj8gw3K1nKr0AsxEZsCKibQTGk6C7lfJjaIo0Hf2JFlLmiYufFOdmJ0C8gmWLOZV3SfShKUy0t-RjgQb03js-G6DPgmfBBFVAi4g8vF9e1UDD6vSD-KfnNHQs7MuQTO4/s320/reactWithwebpackPackages.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
With this setup I was able to setup a simple &quot;hello world&quot; example. I will get into more detail with my next post.&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://garethscode.blogspot.com/feeds/4779346181133349984/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://garethscode.blogspot.com/2020/02/checking-out-react.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3311430580289688408/posts/default/4779346181133349984'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3311430580289688408/posts/default/4779346181133349984'/><link rel='alternate' type='text/html' href='http://garethscode.blogspot.com/2020/02/checking-out-react.html' title='Checking Out React'/><author><name>trujillo42</name><uri>http://www.blogger.com/profile/09625726405492153186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXl-HmPk_4MXNuj8gw3K1nKr0AsxEZsCKibQTGk6C7lfJjaIo0Hf2JFlLmiYufFOdmJ0C8gmWLOZV3SfShKUy0t-RjgQb03js-G6DPgmfBBFVAi4g8vF9e1UDD6vSD-KfnNHQs7MuQTO4/s72-c/reactWithwebpackPackages.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3311430580289688408.post-8297753491625368562</id><published>2017-03-09T09:24:00.000-08:00</published><updated>2017-03-09T09:37:20.866-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Azure"/><category scheme="http://www.blogger.com/atom/ns#" term="node"/><title type='text'>Windows Azure and Node - Remember to specify the version</title><content type='html'>I kept finding that my back end code would subtly fail on something once deployed to an Azure site despite working fine in my own environment. Having hit the problem again recently, I again looked through the server logs to try to identify the problem assuming that again Node would be throwing an error over some very simple syntax.&lt;br /&gt;
&lt;br /&gt;
Then I noticed the following:&lt;br /&gt;
&lt;br /&gt;
&quot;The package.json file does not specify node.js engine version constraints&quot;&lt;br /&gt;
&quot;The node.js application will run with the default node.js version 0.10.32&quot;&lt;br /&gt;
&lt;br /&gt;
This is old, in fact to put this into perspective the contemporary node change logs start from 0.12.0 which is the beginning of 2015. I had to go through their archive to find out where this version is from, which is October 2014!&lt;br /&gt;
&lt;br /&gt;
Now I know, the solution is to specify the &lt;a href=&quot;https://docs.microsoft.com/en-us/azure/nodejs-specify-node-version-azure-apps&quot;&gt;node engine that Windows Azure should use&lt;/a&gt;. e.g.&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/AVvXsEgKwx7mXkZYoOUFI1zdfcNPUacb0Ozfar_LhuaeA3NmBzsMdPbwHsSHdIhlUINs4cdRdxDeLAARJ0dR3wn_RnM5uxFWj8-SrE2-9EcOd_Cu3_th4_Au2P-xkSdxU5ZNHbvR06HlL9eDWxE/s1600/packageScreenshot.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/AVvXsEgKwx7mXkZYoOUFI1zdfcNPUacb0Ozfar_LhuaeA3NmBzsMdPbwHsSHdIhlUINs4cdRdxDeLAARJ0dR3wn_RnM5uxFWj8-SrE2-9EcOd_Cu3_th4_Au2P-xkSdxU5ZNHbvR06HlL9eDWxE/s1600/packageScreenshot.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
As soon as I had made this change my problems went away as you may expect. Looking at the latest &quot;how to&quot; guide on the Azure website for node development I notice that this features at step 5. However, for those who have legacy node websites on Azure, this is not so intuitive.</content><link rel='replies' type='application/atom+xml' href='http://garethscode.blogspot.com/feeds/8297753491625368562/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://garethscode.blogspot.com/2017/03/windows-azure-and-nodejs-remember-to.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3311430580289688408/posts/default/8297753491625368562'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3311430580289688408/posts/default/8297753491625368562'/><link rel='alternate' type='text/html' href='http://garethscode.blogspot.com/2017/03/windows-azure-and-nodejs-remember-to.html' title='Windows Azure and Node - Remember to specify the version'/><author><name>trujillo42</name><uri>http://www.blogger.com/profile/09625726405492153186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKwx7mXkZYoOUFI1zdfcNPUacb0Ozfar_LhuaeA3NmBzsMdPbwHsSHdIhlUINs4cdRdxDeLAARJ0dR3wn_RnM5uxFWj8-SrE2-9EcOd_Cu3_th4_Au2P-xkSdxU5ZNHbvR06HlL9eDWxE/s72-c/packageScreenshot.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3311430580289688408.post-8128867433996626303</id><published>2016-11-19T10:29:00.001-08:00</published><updated>2017-02-04T17:32:02.640-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="AngularJS"/><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript"/><category scheme="http://www.blogger.com/atom/ns#" term="NodeJS"/><category scheme="http://www.blogger.com/atom/ns#" term="Opinion"/><category scheme="http://www.blogger.com/atom/ns#" term="React"/><title type='text'>Isomorphic or Universal Javascript</title><content type='html'>&lt;u style=&quot;font-size: 17px;&quot;&gt;Why I have decided to learn about this?&lt;/u&gt;
&lt;br /&gt;
I first truly took note of the term &quot;Isomorphic JavaScript&quot; when a recruiter sent me through a job which I thought looked extremely interesting. At the time I was not looking for a job, but it reminded me about the long standing problem with decent SEO and Single Page Applications (SPAs). I had heard a lot about &lt;a href=&quot;https://github.com/DavidWells/isomorphic-react-example&quot;&gt;React&lt;/a&gt;&amp;nbsp;and Angular 2 providing some way to solve the problem, so I was curious.&lt;br /&gt;
&lt;br /&gt;
Notably, the company in question were listing some other design patterns and technologies which were new to me and were also of interest: &lt;a href=&quot;https://12factor.net/&quot;&gt;12 factor app&lt;/a&gt;, &lt;a href=&quot;https://mesosphere.github.io/marathon/&quot;&gt;Mesos and Marathon&lt;/a&gt;,&amp;nbsp;&lt;a href=&quot;https://circleci.com/&quot;&gt;CircleCI&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;u style=&quot;font-size: 17px;&quot;&gt;Godammit man, what does Isomorphic mean!&lt;/u&gt;
&lt;br /&gt;
Isomorphic means &quot;corresponding or similar in form&quot;. So essentially we are describing some sort of server side rendering to support the client side application.&lt;br /&gt;
&lt;br /&gt;
Or as the &lt;a href=&quot;https://github.com/angular/universal&quot;&gt;AngularJS Universal Repository&lt;/a&gt; puts it: &quot;A JavaScript Application that runs in more environments than just the browser&quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;u style=&quot;font-size: 17px;&quot;&gt;The advantages?&lt;/u&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;The application does not need to rely on JavaScript being turned on in the browser for it to function&lt;/li&gt;
&lt;li&gt;The application does not need to have a loading gif to explain to the user that patience is required&lt;/li&gt;
&lt;li&gt;THE BIG ONE - The application can be more easily crawled by search engines because the page is also available from a static URL.&lt;/li&gt;
&lt;/ul&gt;
&lt;u style=&quot;font-size: 17px;&quot;&gt;Some disadvantages and limitations&lt;/u&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&quot;Uncanny valley&quot; - this is a term used to describe the time between the application appearing to be functioning and available and the time before it is actually responding to the users demands. This can be confusing for the user.&lt;/li&gt;
&lt;li&gt;Loss of separation between back-end and front-end application code. However, I would say, in this API/ Micro-service architecture world, that this actually makes quite a bit of sense. The User Interface will still be separated from Business Logic, we are just blurring the line between server-side &quot;Get&quot; request responses and view rendering.&lt;/li&gt;
&lt;li&gt;This is still just a bootstrapping technique and some SEO issues do still remain.&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
For a more thorough discussion on why Isomorphic JavaScript is &quot;not the answer&quot; take a look at this &lt;a href=&quot;https://news.ycombinator.com/item?id=8957854&quot;&gt;discussion on ycombinator&lt;/a&gt;&amp;nbsp;(at your own risk of course!).&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://garethscode.blogspot.com/feeds/8128867433996626303/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://garethscode.blogspot.com/2016/11/isomorphic-or-universal-javascript.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3311430580289688408/posts/default/8128867433996626303'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3311430580289688408/posts/default/8128867433996626303'/><link rel='alternate' type='text/html' href='http://garethscode.blogspot.com/2016/11/isomorphic-or-universal-javascript.html' title='Isomorphic or Universal Javascript'/><author><name>trujillo42</name><uri>http://www.blogger.com/profile/09625726405492153186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3311430580289688408.post-406534705038573040</id><published>2016-07-24T08:20:00.000-07:00</published><updated>2017-04-04T11:04:40.586-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Jasmine"/><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript"/><category scheme="http://www.blogger.com/atom/ns#" term="JSPM"/><category scheme="http://www.blogger.com/atom/ns#" term="Karma"/><title type='text'>Karma Error: You need to include some adapter that implements __karma__.start method</title><content type='html'>&lt;div style=&quot;background-color: white; box-sizing: border-box;&quot;&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/AVvXsEhEf01X-ZSNY0Frfccbx__D4RmjKWFGlz_KJVCMw9lA7Y0NwSe8cZhpQS5jhgoy92eH9tn8VV7GaLw7JqH3qQ7QQZ0OVLVqVg6czHNiWN3AlPqIEaLEmHpbYzzc9L2Y4vMhieVtWcI82Kg/s1600/Karma+Error.png&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;60&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhEf01X-ZSNY0Frfccbx__D4RmjKWFGlz_KJVCMw9lA7Y0NwSe8cZhpQS5jhgoy92eH9tn8VV7GaLw7JqH3qQ7QQZ0OVLVqVg6czHNiWN3AlPqIEaLEmHpbYzzc9L2Y4vMhieVtWcI82Kg/s320/Karma+Error.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div style=&quot;color: #333333; font-size: 16px; line-height: 24px;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;color: #333333; font-size: 16px; line-height: 24px;&quot;&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
An error message which means very little. Something has gone wrong with Karma and it is affecting mine!&lt;/div&gt;
&lt;div style=&quot;color: #333333; font-size: 16px; line-height: 24px;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;color: #333333; font-size: 16px; line-height: 24px;&quot;&gt;
It looks like some breaking changes made in Karma-Runner 1.0.0 have really screwed over all the plugin projects such as Karma-Jasmine which I very much rely upon.&lt;/div&gt;
&lt;div style=&quot;color: #333333; font-size: 16px; line-height: 24px;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;color: #333333; font-size: 16px; line-height: 24px;&quot;&gt;
The only way around it at the moment is to downgrade Karma to 0.13.22 until Karma-Jasmine is compatible with v1.x.x versions of Karma.&lt;/div&gt;
&lt;div style=&quot;color: #333333; font-size: 16px; line-height: 24px;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;hr /&gt;
&lt;br /&gt;
&lt;h1 class=&quot;release-title&quot; style=&quot;background-color: white; box-sizing: border-box; color: #333333; font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe UI&amp;quot;, Roboto, Helvetica, Arial, sans-serif, &amp;quot;Apple Color Emoji&amp;quot;, &amp;quot;Segoe UI Emoji&amp;quot;, &amp;quot;Segoe UI Symbol&amp;quot;; font-size: 32px; margin: 0px 60px 0px 0px;&quot;&gt;
&lt;a href=&quot;https://github.com/karma-runner/karma/releases/tag/v1.0.0&quot; style=&quot;background-color: transparent; box-sizing: border-box; color: #4078c0; text-decoration: none;&quot;&gt;v1.0.0&lt;/a&gt;&lt;/h1&gt;
&lt;div class=&quot;release-authorship&quot; style=&quot;background-color: white; box-sizing: border-box; color: #767676; font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe UI&amp;quot;, Roboto, Helvetica, Arial, sans-serif, &amp;quot;Apple Color Emoji&amp;quot;, &amp;quot;Segoe UI Emoji&amp;quot;, &amp;quot;Segoe UI Symbol&amp;quot;; font-size: 14px; line-height: 21px; margin-bottom: 20px; margin-top: 5px;&quot;&gt;
&lt;img alt=&quot;@dignifiedquire&quot; class=&quot;avatar&quot; height=&quot;20&quot; src=&quot;https://avatars3.githubusercontent.com/u/790842?v=3&amp;amp;s=40&quot; style=&quot;border-radius: 3px; border-style: none; box-sizing: border-box; display: inline-block; line-height: 1; overflow: hidden; vertical-align: middle;&quot; width=&quot;20&quot; /&gt;&amp;nbsp;&lt;a href=&quot;https://github.com/dignifiedquire&quot; style=&quot;background-color: transparent; box-sizing: border-box; color: #666666; font-weight: bold; text-decoration: none;&quot;&gt;dignifiedquire&lt;/a&gt;&amp;nbsp;released this&amp;nbsp;&lt;relative-time datetime=&quot;2016-06-23T18:40:11Z&quot; style=&quot;box-sizing: border-box;&quot; title=&quot;Jun 23, 2016, 7:40 PM GMT+1&quot;&gt;on Jun 23&lt;/relative-time&gt;&lt;/div&gt;
&lt;h3 style=&quot;background-color: white; box-sizing: border-box; color: #333333; font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe UI&amp;quot;, Roboto, Helvetica, Arial, sans-serif, &amp;quot;Apple Color Emoji&amp;quot;, &amp;quot;Segoe UI Emoji&amp;quot;, &amp;quot;Segoe UI Symbol&amp;quot;; font-size: 1.25em; line-height: 1.25; margin-bottom: 16px; margin-top: 24px;&quot;&gt;
BREAKING CHANGES&lt;/h3&gt;
&lt;ul style=&quot;background-color: white; box-sizing: border-box; color: #333333; font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe UI&amp;quot;, Roboto, Helvetica, Arial, sans-serif, &amp;quot;Apple Color Emoji&amp;quot;, &amp;quot;Segoe UI Emoji&amp;quot;, &amp;quot;Segoe UI Symbol&amp;quot;; font-size: 16px; line-height: 24px; margin-bottom: 16px; margin-top: 0px; padding-left: 2em;&quot;&gt;
&lt;li style=&quot;box-sizing: border-box;&quot;&gt;context: Our&amp;nbsp;&lt;code style=&quot;background-color: rgba(0, 0, 0, 0.0392157); border-radius: 3px; box-sizing: border-box; font-family: Consolas, &amp;quot;Liberation Mono&amp;quot;, Menlo, Courier, monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0px;&quot;&gt;context.html&lt;/code&gt;&amp;nbsp;and&amp;nbsp;&lt;code style=&quot;background-color: rgba(0, 0, 0, 0.0392157); border-radius: 3px; box-sizing: border-box; font-family: Consolas, &amp;quot;Liberation Mono&amp;quot;, Menlo, Courier, monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0px;&quot;&gt;debug.html&lt;/code&gt;&amp;nbsp;structures have changed to lean on&amp;nbsp;&lt;code style=&quot;background-color: rgba(0, 0, 0, 0.0392157); border-radius: 3px; box-sizing: border-box; font-family: Consolas, &amp;quot;Liberation Mono&amp;quot;, Menlo, Courier, monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0px;&quot;&gt;context.js&lt;/code&gt;&amp;nbsp;and&lt;code style=&quot;background-color: rgba(0, 0, 0, 0.0392157); border-radius: 3px; box-sizing: border-box; font-family: Consolas, &amp;quot;Liberation Mono&amp;quot;, Menlo, Courier, monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0px;&quot;&gt;debug.js&lt;/code&gt;. This is in preparation for deeper&amp;nbsp;&lt;code style=&quot;background-color: rgba(0, 0, 0, 0.0392157); border-radius: 3px; box-sizing: border-box; font-family: Consolas, &amp;quot;Liberation Mono&amp;quot;, Menlo, Courier, monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0px;&quot;&gt;context.js&lt;/code&gt;&amp;nbsp;changes in&amp;nbsp;&lt;a class=&quot;issue-link js-issue-link&quot; data-error-text=&quot;Failed to load issue title&quot; data-id=&quot;140106835&quot; data-permission-text=&quot;Issue title is private&quot; href=&quot;https://github.com/karma-runner/karma/pull/1984&quot; style=&quot;background-color: transparent; box-sizing: border-box; color: #4078c0; text-decoration: none;&quot; title=&quot;Transition from contextWindow to postMessage&quot;&gt;#1984&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;release-authorship&quot; style=&quot;background-color: white; box-sizing: border-box; color: #767676; font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe UI&amp;quot;, Roboto, Helvetica, Arial, sans-serif, &amp;quot;Apple Color Emoji&amp;quot;, &amp;quot;Segoe UI Emoji&amp;quot;, &amp;quot;Segoe UI Symbol&amp;quot;; font-size: 14px; line-height: 21px; margin-bottom: 20px; margin-top: 5px;&quot;&gt;
&lt;relative-time datetime=&quot;2016-06-23T18:40:11Z&quot; style=&quot;box-sizing: border-box;&quot; title=&quot;Jun 23, 2016, 7:40 PM GMT+1&quot;&gt;&lt;/relative-time&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #333333; font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe UI&amp;quot;, Roboto, Helvetica, Arial, sans-serif, &amp;quot;Apple Color Emoji&amp;quot;, &amp;quot;Segoe UI Emoji&amp;quot;, &amp;quot;Segoe UI Symbol&amp;quot;; font-size: 16px; line-height: 24px;&quot;&gt;
As a result, all&amp;nbsp;&lt;code style=&quot;background-color: rgba(0, 0, 0, 0.0392157); border-radius: 3px; box-sizing: border-box; font-family: Consolas, &amp;quot;Liberation Mono&amp;quot;, Menlo, Courier, monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0px;&quot;&gt;customContextFile&lt;/code&gt;&amp;nbsp;and&amp;nbsp;&lt;code style=&quot;background-color: rgba(0, 0, 0, 0.0392157); border-radius: 3px; box-sizing: border-box; font-family: Consolas, &amp;quot;Liberation Mono&amp;quot;, Menlo, Courier, monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0px;&quot;&gt;customDebugFile&lt;/code&gt;&amp;nbsp;options much update their format&lt;br /&gt;
to match this new format.&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;hr /&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #333333; font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe UI&amp;quot;, Roboto, Helvetica, Arial, sans-serif, &amp;quot;Apple Color Emoji&amp;quot;, &amp;quot;Segoe UI Emoji&amp;quot;, &amp;quot;Segoe UI Symbol&amp;quot;; font-size: 16px; line-height: 24px;&quot;&gt;
&lt;br /&gt;
Hmm clear as mud huh?&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #333333; font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe UI&amp;quot;, Roboto, Helvetica, Arial, sans-serif, &amp;quot;Apple Color Emoji&amp;quot;, &amp;quot;Segoe UI Emoji&amp;quot;, &amp;quot;Segoe UI Symbol&amp;quot;; font-size: 16px; line-height: 24px;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; box-sizing: border-box; color: #333333; font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe UI&amp;quot;, Roboto, Helvetica, Arial, sans-serif, &amp;quot;Apple Color Emoji&amp;quot;, &amp;quot;Segoe UI Emoji&amp;quot;, &amp;quot;Segoe UI Symbol&amp;quot;; font-size: 16px; line-height: 24px;&quot;&gt;
Certainly I will be keeping a close eye on &lt;a href=&quot;https://github.com/karma-runner/karma-jasmine/issues/127&quot;&gt;this issue&lt;/a&gt; to see when I can upgrade safely.&lt;br /&gt;
&lt;br /&gt;
UPDATE: It looks as though this has been fixed - all the errors related to this were consolidated in issue &lt;a href=&quot;https://github.com/karma-runner/karma/issues/2194&quot;&gt;2194&lt;/a&gt;&amp;nbsp;and released just days after I wrote this post.&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://garethscode.blogspot.com/feeds/406534705038573040/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://garethscode.blogspot.com/2016/07/karma-error-you-need-to-include-some.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3311430580289688408/posts/default/406534705038573040'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3311430580289688408/posts/default/406534705038573040'/><link rel='alternate' type='text/html' href='http://garethscode.blogspot.com/2016/07/karma-error-you-need-to-include-some.html' title='Karma Error: You need to include some adapter that implements __karma__.start method'/><author><name>trujillo42</name><uri>http://www.blogger.com/profile/09625726405492153186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhEf01X-ZSNY0Frfccbx__D4RmjKWFGlz_KJVCMw9lA7Y0NwSe8cZhpQS5jhgoy92eH9tn8VV7GaLw7JqH3qQ7QQZ0OVLVqVg6czHNiWN3AlPqIEaLEmHpbYzzc9L2Y4vMhieVtWcI82Kg/s72-c/Karma+Error.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3311430580289688408.post-4244281742052104431</id><published>2016-06-26T10:08:00.001-07:00</published><updated>2016-06-26T10:08:36.194-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Babel"/><category scheme="http://www.blogger.com/atom/ns#" term="ES6"/><category scheme="http://www.blogger.com/atom/ns#" term="JSPM"/><title type='text'>Hitting a bug where the best fix is to update... everything</title><content type='html'>&lt;u&gt;Background&lt;/u&gt;&lt;br /&gt;
&lt;u&gt;&lt;br /&gt;&lt;/u&gt;
I have been working on a number of&amp;nbsp;&lt;a href=&quot;http://mean.io/&quot;&gt;MEAN stack&lt;/a&gt; projects for the last year and a half. I had been moving rapidly between one project and the next, however, since December last year I have been working consistently on the same ambitious web application.&lt;br /&gt;
&lt;br /&gt;
I have been so focused on delivering new features that I have not been updating my packages at all.&lt;br /&gt;
&lt;br /&gt;
This finally came to a head when trying to improve my production build process.&lt;br /&gt;
&lt;br /&gt;
I was trying to use the &lt;a href=&quot;https://www.npmjs.com/package/gulp-jspm&quot;&gt;gulp-jspm&lt;/a&gt; plugin to allow me more control over my JSPM bundled front end JavaScript. Until now I have been using some hacky powershell to bundle my transpiled JavaScript - not the best for adding in more processes into my production build.&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;Starting Out&lt;/u&gt;&lt;br /&gt;
&lt;u&gt;&lt;br /&gt;&lt;/u&gt;
After hitting a few minor hurdles I was successfully generating a bundled file through gulp. Hwever when I loaded the application in my test of production mode locally I was getting a&amp;nbsp;&lt;b style=&quot;font-style: italic;&quot;&gt;&quot;System is not defined error&quot; &lt;/b&gt;in the console.&lt;br /&gt;
&lt;br /&gt;
After reading up on the &lt;i&gt;&lt;b&gt;&quot;System is not defined error&quot;&lt;/b&gt;&lt;/i&gt;, it seems that this was fixed at the back end of last year, just when I stopped updating everything. So, time to commit what I have and then head full tilt into the world of updating third party packages...&lt;br /&gt;
&lt;u&gt;&lt;br /&gt;&lt;/u&gt;
&lt;u&gt;NPM Tip&lt;/u&gt;&lt;br /&gt;
&lt;u&gt;&lt;br /&gt;&lt;/u&gt;
There is a command in NPM which tells you exactly which packages are out of date:&lt;br /&gt;
&lt;br /&gt;
&lt;pre style=&quot;background-color: #f7f7f7; border-radius: 3px; box-sizing: border-box; color: #333333; font-family: Consolas, &amp;quot;Liberation Mono&amp;quot;, Menlo, Courier, monospace; font-size: 11.9px; font-stretch: normal; line-height: 1.45; overflow: auto; padding: 16px; word-wrap: normal;&quot;&gt;&lt;code style=&quot;background: transparent; border-radius: 3px; border: 0px; box-sizing: border-box; display: inline; font-family: Consolas, &amp;quot;Liberation Mono&amp;quot;, Menlo, Courier, monospace; font-size: 11.9px; line-height: inherit; margin: 0px; overflow: visible; padding: 0px; word-break: normal; word-wrap: normal;&quot;&gt;npm outdated&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
This was a useful starting point to try to evaluate how many of the modules needed to be updated and how badly out of date they were. Luckily most of the most crucial babel packages for node seemed to update fine.&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;Unlinked and operation not permitted ??&lt;/u&gt;&lt;br /&gt;
&lt;br /&gt;
When trying to update the JSPM modules, in particular Angular ones with numerous links to one another. I got a number of confusing &quot;please unlink&quot; messages. It seems that this is JSPM&#39;s way of moaning about version inter dependencies. The way through this seems to be to remove the main files like Angular and reinstall which sucks, but got me through to the next set of errors.&lt;br /&gt;
&lt;br /&gt;
After a while I was getting a serious blocker in the form of:&lt;br /&gt;
&lt;br /&gt;
&lt;pre style=&quot;background-color: #f7f7f7; border-radius: 3px; box-sizing: border-box; color: #333333; font-family: Consolas, &amp;quot;Liberation Mono&amp;quot;, Menlo, Courier, monospace; font-size: 11.9px; font-stretch: normal; line-height: 1.45; overflow: auto; padding: 16px; word-wrap: normal;&quot;&gt;&lt;code style=&quot;background: transparent; border-radius: 3px; border: 0px; box-sizing: border-box; display: inline; font-family: Consolas, &amp;quot;Liberation Mono&amp;quot;, Menlo, Courier, monospace; font-size: 11.9px; line-height: inherit; margin: 0px; overflow: visible; padding: 0px; word-break: normal; word-wrap: normal;&quot;&gt;Error: EPERM, operation not permitted&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
I found a number of more recent posts suggesting to readers that they should use the NodeJS console with administrator permissions. I did try this but sadly the end result was no different to using ConEmu in administrator mode.&lt;br /&gt;
&lt;br /&gt;
I then checked the NodeJS version and noticed that it was somewhat out of date @4.2.2 when the current version of NodeJS stable is @4.4.3. The clue here was again from some historic&amp;nbsp;&lt;a href=&quot;https://github.com/Medium/phantomjs/issues/19&quot;&gt;NodeJS GitHub issues&lt;/a&gt;. After updating NodeJS JSPM and NPM package managers started working without me having to manually uninstall and reinstall packages.&lt;br /&gt;
&lt;br /&gt;
I finally got to the end of this mammoth updating spree. I run Gulp to build my JSPM build file which was where I was getting the&amp;nbsp;&lt;i style=&quot;font-weight: bold;&quot;&gt;&quot;System is not defined error&quot;. &lt;/i&gt;The same problem remains. It turns out that the only issue was me misunderstanding the &quot;self executing file&quot; concept in JSPM.&lt;br /&gt;
&lt;br /&gt;
There are &lt;a href=&quot;http://jspm.io/docs/production-workflows.html&quot;&gt;three options with JSPM&lt;/a&gt;. Either you can generate a self executing file which includes everything that your program needs, including System.js and a &quot;micro-loader&quot;. You can create a bundle which must be called by your html - and therefore you must make the node_modules location available. The third option is a full HTTP2 SPDY implementation which seems overkill for me at this moment in time.&lt;br /&gt;
&lt;br /&gt;
The solution was to change the following in my Gulpfile to generate the self executing version:&lt;br /&gt;
&lt;br /&gt;
&lt;pre style=&quot;border-radius: 3px; box-sizing: border-box; font-stretch: normal; overflow: auto; padding: 16px; word-wrap: normal;&quot;&gt;&lt;span style=&quot;color: #333333; font-family: Consolas, Liberation Mono, Menlo, Courier, monospace;&quot;&gt;&lt;span style=&quot;font-size: 11.9px; line-height: 17.255px;&quot;&gt;&lt;span style=&quot;background-color: #f7f7f7;&quot;&gt;gulp.task(&quot;default&quot;, function() {
    gulp.src(&quot;sysadmin/main.js&quot;)
        .pipe(gulp_jspm({verbose: false, &lt;/span&gt;&lt;span style=&quot;background-color: lime;&quot;&gt;&lt;b&gt;selfExecutingBundle: true&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #f7f7f7;&quot;&gt;}))
        .pipe(rename(&quot;build.js&quot;))
        .pipe(gulp.dest(&quot;sysadmin/dist&quot;));
});&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style=&quot;border-radius: 3px; box-sizing: border-box; font-stretch: normal; overflow: auto; padding: 16px; word-wrap: normal;&quot;&gt;&lt;span style=&quot;font-family: Times New Roman;&quot;&gt;&lt;span style=&quot;white-space: normal;&quot;&gt;I have to be philosophical I guess, this blog post might well have the same outcome in my mind as the EU referendum but its a good lesson in why it is important to keep software dependencies up&amp;nbsp;to date, it can lead to a lack of confidence which ends up wasting time.&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
</content><link rel='replies' type='application/atom+xml' href='http://garethscode.blogspot.com/feeds/4244281742052104431/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://garethscode.blogspot.com/2016/06/hitting-bug-where-best-fix-is-to-update.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3311430580289688408/posts/default/4244281742052104431'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3311430580289688408/posts/default/4244281742052104431'/><link rel='alternate' type='text/html' href='http://garethscode.blogspot.com/2016/06/hitting-bug-where-best-fix-is-to-update.html' title='Hitting a bug where the best fix is to update... everything'/><author><name>trujillo42</name><uri>http://www.blogger.com/profile/09625726405492153186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3311430580289688408.post-6315757994850373398</id><published>2016-04-01T11:45:00.002-07:00</published><updated>2016-04-16T07:22:42.626-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ES6"/><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript"/><category scheme="http://www.blogger.com/atom/ns#" term="JSPM"/><category scheme="http://www.blogger.com/atom/ns#" term="Karma"/><category scheme="http://www.blogger.com/atom/ns#" term="Unit Testing"/><title type='text'>Setting up Karma to play nice with JSPM</title><content type='html'>&lt;a href=&quot;https://github.com/thejameskyle/babel-handbook/blob/master/translations/en/user-handbook.md#toc-executing-babel-generated-code&quot; target=&quot;_blank&quot;&gt;The TL;DR version&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
I was getting quite frustrated with unit testing today because when I was attempting to use ES6 features like Array.find I was greeted with errors like this one.&lt;br /&gt;
&lt;br /&gt;
&lt;pre style=&quot;background-color: #f7f7f7; border-radius: 3px; box-sizing: border-box; color: #333333; font-family: Consolas, &#39;Liberation Mono&#39;, Menlo, Courier, monospace; font-size: 11.9px; font-stretch: normal; line-height: 1.45; overflow: auto; padding: 16px; word-wrap: normal;&quot;&gt;&lt;code style=&quot;background: transparent; border-radius: 3px; border: 0px; box-sizing: border-box; display: inline; font-family: Consolas, &#39;Liberation Mono&#39;, Menlo, Courier, monospace; font-size: 11.9px; line-height: inherit; margin: 0px; max-width: initial; overflow: initial; padding: 0px; word-break: normal; word-wrap: normal;&quot;&gt;TypeError: undefined is not a constructor (evaluating &#39;categories.find(function (cat) {
                                return cat._id === id;
                            })&#39;) (line 19)
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
I noticed I was also getting a message like this in my stack trace:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;pre style=&quot;background-color: #f7f7f7; border-radius: 3px; box-sizing: border-box; color: #333333; font-family: Consolas, &#39;Liberation Mono&#39;, Menlo, Courier, monospace; font-size: 11.9px; font-stretch: normal; line-height: 1.45; overflow: auto; padding: 16px; word-wrap: normal;&quot;&gt;&lt;code style=&quot;background: transparent; border-radius: 3px; border: 0px; box-sizing: border-box; display: inline; font-family: Consolas, &#39;Liberation Mono&#39;, Menlo, Courier, monospace; font-size: 11.9px; line-height: inherit; margin: 0px; max-width: initial; overflow: initial; padding: 0px; word-break: normal; word-wrap: normal;&quot;&gt;tryCatchReject (http://localhost:9876/base/jspm_packages/system-polyfills.src.js&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
Why couldn&#39;t SystemJS load polyfills? It was managing it fine in my browser, at least that is what I assumed.&lt;br /&gt;
&lt;br /&gt;
I made a mistake and thought that I must need to pre-process my unit tests so that they become babelified or ES6 ified or JS2015 ified etc...&lt;br /&gt;
&lt;br /&gt;
I started looking at this...&lt;br /&gt;
https://github.com/babel/karma-babel-preprocessor&lt;br /&gt;
This made it worse because I was trying to re-implement using a different tool the same task which is being undertaken by JSPM and SystemJS.&lt;br /&gt;
&lt;br /&gt;
In the end the answer was rather than keep adding configuration, strip out configuration and then add just one extra line.&lt;br /&gt;
&lt;br /&gt;
I actually found this tip/clue from the karma-babel-preprocessor configuration page.&lt;br /&gt;
&lt;h3 style=&quot;box-sizing: border-box; color: #333333; font-family: &#39;Helvetica Neue&#39;, Helvetica, &#39;Segoe UI&#39;, Arial, freesans, sans-serif, &#39;Apple Color Emoji&#39;, &#39;Segoe UI Emoji&#39;, &#39;Segoe UI Symbol&#39;; font-size: 1.5em; line-height: 1.43; margin-bottom: 16px; margin-top: 1em;&quot;&gt;
Polyfill&lt;/h3&gt;
&lt;div style=&quot;box-sizing: border-box; color: #333333; font-family: &#39;Helvetica Neue&#39;, Helvetica, &#39;Segoe UI&#39;, Arial, freesans, sans-serif, &#39;Apple Color Emoji&#39;, &#39;Segoe UI Emoji&#39;, &#39;Segoe UI Symbol&#39;; font-size: 16px; line-height: 25.6px; margin-bottom: 16px;&quot;&gt;
If you need&amp;nbsp;&lt;a href=&quot;https://babeljs.io/docs/usage/polyfill/&quot; style=&quot;box-sizing: border-box; color: #4078c0; text-decoration: none;&quot;&gt;polyfill&lt;/a&gt;, make sure to include it in&amp;nbsp;&lt;code style=&quot;background-color: rgba(0, 0, 0, 0.0392157); border-radius: 3px; box-sizing: border-box; font-family: Consolas, &#39;Liberation Mono&#39;, Menlo, Courier, monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0px;&quot;&gt;files&lt;/code&gt;.&lt;/div&gt;
&lt;div class=&quot;highlight highlight-source-shell&quot; style=&quot;box-sizing: border-box; color: #333333; font-family: &#39;Helvetica Neue&#39;, Helvetica, &#39;Segoe UI&#39;, Arial, freesans, sans-serif, &#39;Apple Color Emoji&#39;, &#39;Segoe UI Emoji&#39;, &#39;Segoe UI Symbol&#39;; font-size: 16px; line-height: 25.6px; margin-bottom: 16px;&quot;&gt;
&lt;pre style=&quot;background-color: #f7f7f7; border-radius: 3px; box-sizing: border-box; font-family: Consolas, &#39;Liberation Mono&#39;, Menlo, Courier, monospace; font-size: 13.6px; font-stretch: normal; line-height: 1.45; overflow: auto; padding: 16px; word-break: normal; word-wrap: normal;&quot;&gt;npm install babel-polyfill --save-dev&lt;/pre&gt;
&lt;/div&gt;
&lt;div class=&quot;highlight highlight-source-js&quot; style=&quot;box-sizing: border-box; color: #333333; font-family: &#39;Helvetica Neue&#39;, Helvetica, &#39;Segoe UI&#39;, Arial, freesans, sans-serif, &#39;Apple Color Emoji&#39;, &#39;Segoe UI Emoji&#39;, &#39;Segoe UI Symbol&#39;; font-size: 16px; line-height: 25.6px; margin-bottom: 16px;&quot;&gt;
&lt;pre style=&quot;background-color: #f7f7f7; border-radius: 3px; box-sizing: border-box; font-family: Consolas, &#39;Liberation Mono&#39;, Menlo, Courier, monospace; font-size: 13.6px; font-stretch: normal; line-height: 1.45; overflow: auto; padding: 16px; word-break: normal; word-wrap: normal;&quot;&gt;&lt;span class=&quot;pl-c1&quot; style=&quot;box-sizing: border-box; color: #0086b3;&quot;&gt;module&lt;/span&gt;.&lt;span class=&quot;pl-en&quot; style=&quot;box-sizing: border-box; color: #795da3;&quot;&gt;exports&lt;/span&gt; &lt;span class=&quot;pl-k&quot; style=&quot;box-sizing: border-box; color: #a71d5d;&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;pl-k&quot; style=&quot;box-sizing: border-box; color: #a71d5d;&quot;&gt;function&lt;/span&gt; (&lt;span class=&quot;pl-smi&quot; style=&quot;box-sizing: border-box;&quot;&gt;config&lt;/span&gt;) {
  &lt;span class=&quot;pl-smi&quot; style=&quot;box-sizing: border-box;&quot;&gt;config&lt;/span&gt;.&lt;span class=&quot;pl-en&quot; style=&quot;box-sizing: border-box; color: #795da3;&quot;&gt;set&lt;/span&gt;({
    files&lt;span class=&quot;pl-k&quot; style=&quot;box-sizing: border-box; color: #a71d5d;&quot;&gt;:&lt;/span&gt; [
      &lt;span class=&quot;pl-s&quot; style=&quot;box-sizing: border-box; color: #183691;&quot;&gt;&lt;span class=&quot;pl-pds&quot; style=&quot;box-sizing: border-box;&quot;&gt;&#39;&lt;/span&gt;node_modules/babel-polyfill/dist/polyfill.js&lt;span class=&quot;pl-pds&quot; style=&quot;box-sizing: border-box;&quot;&gt;&#39;&lt;/span&gt;&lt;/span&gt;,
      &lt;span class=&quot;pl-c&quot; style=&quot;box-sizing: border-box; color: #969896;&quot;&gt;// ...&lt;/span&gt;
    ],
    &lt;span class=&quot;pl-c&quot; style=&quot;box-sizing: border-box; color: #969896;&quot;&gt;// ...&lt;/span&gt;
  });
});&lt;/pre&gt;
&lt;/div&gt;
I added the line above to the files array and &quot;hey presto&quot; all my unit tests were working fine with array.find. To prove that &quot;karma-babel-preprocessor&quot; was not needed I uninstalled it and re-ran my tests.&lt;br /&gt;
&lt;u&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/u&gt;I later found that I also needed to reference babels polyfill.js in the client-side code that was using the find method.&lt;br /&gt;
&lt;br /&gt;
The only reason I had not noticed was because Chrome has a native implementation. However MS Edge and all other IE browsers do not, so nothing worked on those browsers - a dead giveaway. I added this line to the files in question:&lt;br /&gt;
&lt;pre style=&quot;-webkit-font-smoothing: antialiased; background: rgb(249, 249, 249); border-radius: 4px; border: none; box-shadow: none; box-sizing: border-box; color: #323330; font-family: Menlo, Monaco, Consolas, &#39;Courier New&#39;, monospace; font-size: 13px; line-height: 1.42857; margin-bottom: 10px; overflow: auto; padding: 1em; word-break: break-all; word-wrap: break-word;&quot;&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot; style=&quot;-webkit-font-smoothing: antialiased; background-color: transparent; border-radius: 0px; box-sizing: border-box; color: inherit; font-family: Menlo, Monaco, Consolas, &#39;Courier New&#39;, monospace; font-size: inherit; padding: 0px; white-space: pre-wrap;&quot;&gt;&lt;span class=&quot;kr&quot; style=&quot;box-sizing: border-box; color: #8959a8;&quot;&gt;import &lt;span class=&quot;s2&quot; style=&quot;box-sizing: border-box; color: #718c00;&quot;&gt;&quot;babel-polyfill&quot;&lt;/span&gt;&lt;span class=&quot;p&quot; style=&quot;box-sizing: border-box; color: #4d4d4c;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
See:&amp;nbsp;https://babeljs.io/docs/usage/polyfill/&lt;br /&gt;
&lt;br /&gt;
I found later that sometimes the unit tests would still crash PhantomJS. The final solution to this was to split the specification files from the implementation files using the following &lt;a href=&quot;https://www.npmjs.com/package/karma-jspm&quot;&gt;from karm-jspm&lt;/a&gt;:&lt;br /&gt;
&lt;br /&gt;
&lt;pre style=&quot;background: rgb(249, 249, 249); border-radius: 4px; border: none; box-shadow: none; box-sizing: border-box; margin-bottom: 10px; overflow: auto; padding: 1em; word-break: break-all; word-wrap: break-word;&quot;&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot; style=&quot;background-color: transparent; border-radius: 0px; box-sizing: border-box; padding: 0px;&quot;&gt;&lt;span class=&quot;kr&quot; style=&quot;box-sizing: border-box; color: #8959a8;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;menlo&amp;quot; , &amp;quot;monaco&amp;quot; , &amp;quot;consolas&amp;quot; , &amp;quot;courier new&amp;quot; , monospace;&quot;&gt;&lt;span style=&quot;line-height: 18.5714px; white-space: pre-wrap;&quot;&gt;jspm: {
    loadFiles: [&#39;test/**/*.js&#39;],
    serveFiles: [&#39;src/**/*.js&#39;]
}&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: rgba(0 , 0 , 0 , 0); font-family: &amp;quot;menlo&amp;quot; , &amp;quot;monaco&amp;quot; , &amp;quot;consolas&amp;quot; , &amp;quot;courier new&amp;quot; , monospace;&quot;&gt;&lt;span style=&quot;line-height: 1.42857; white-space: pre-wrap;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
The theory being that you don&#39;t need to load the actual files to be tested until you have initially loaded the tests themselves.&lt;br /&gt;
&lt;br /&gt;
I think it is fair to say that sometimes Karma does not like to play nicely with JSPM, although this does seem to depend on your project structure as well. I hope these little tips either help to resolve an issue or go someway to alleviate some confusion.&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://garethscode.blogspot.com/feeds/6315757994850373398/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://garethscode.blogspot.com/2016/04/setting-up-karma-to-play-nice-with-jspm.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3311430580289688408/posts/default/6315757994850373398'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3311430580289688408/posts/default/6315757994850373398'/><link rel='alternate' type='text/html' href='http://garethscode.blogspot.com/2016/04/setting-up-karma-to-play-nice-with-jspm.html' title='Setting up Karma to play nice with JSPM'/><author><name>trujillo42</name><uri>http://www.blogger.com/profile/09625726405492153186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3311430580289688408.post-5585240608972903329</id><published>2016-03-11T04:17:00.002-08:00</published><updated>2017-03-17T07:50:03.499-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Azure"/><category scheme="http://www.blogger.com/atom/ns#" term="Microsoft Windows Workflow Foundation"/><category scheme="http://www.blogger.com/atom/ns#" term="Opinion"/><title type='text'>The dev-ops cycle (a tale from the trenches)</title><content type='html'>Hi, I would like to describe to you a problem which caused real pain for me and the company I work for. And then I would like to explain to you why these problems were occurring and how we kept failing to address them. And finally what was improved as a result.&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;Some Background (Windows Workflow)&lt;/u&gt;&lt;br /&gt;
&lt;br /&gt;
At company x we have been using Microsoft&#39;s Windows Workflow Foundation hosted and scaled using a number of Azure Web Instances. In other words, when there is a problem with the workflows it adversely effects the end users. Pretty flawed design, but this is what we had been working with for sometime.&lt;br /&gt;
&lt;br /&gt;
In general Windows Workflow is a highly effective way to manage software development. It offers a clear overview of a highly complex systems and a highly scalable run-time engine out of the box. This &lt;a href=&quot;https://www.dotnetrocks.com/?show=1236&quot;&gt;guy (Blake Helms) is a major fan&lt;/a&gt;&amp;nbsp;and so is the CTO at my company.&lt;br /&gt;
&lt;br /&gt;
Of course, Windows Workflow does have some peculiarities. See these excellent posts on the dreaded &lt;a href=&quot;http://blog.lytzen.name/2012/04/windows-workflow-foundation-4-state.html&quot;&gt;tight loop&lt;/a&gt;&amp;nbsp;and managing the &lt;a href=&quot;http://blog.lytzen.name/2013/05/hard-windows-workflow-lessons-from-azure.html&quot;&gt;workflow persistence store&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;A Case Study&lt;/u&gt;&lt;br /&gt;
&lt;u&gt;&lt;br /&gt;&lt;/u&gt;
On Thursday afternoon our web instances started bouncing wildly between 50% -100% CPU usage, our users were complaining that the site was &quot;slow&quot;, and restarting one web instance at a time was only solving the problem temporarily. Looking through the logs it seemed that this had been going for a few days to a lesser or greater extent depending on load. The same pattern was occurring again and again each day getting worse and more noticeable - the overall CPU usage would ramp up and then ramp back down again temporarily disabling Web Instances.&lt;br /&gt;
&lt;br /&gt;
Having spent some time looking at this with our normal analysis techniques it seemed that there was no problem with the workflows. Looking at the workflows coming in every couple of minutes showed that they were being processed as expected. I suggested that we see what happens when the users log off at the end of the day - hoping that we would see a clearer picture out of hours.&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;Accept The Problem&lt;/u&gt;&lt;br /&gt;
&lt;br /&gt;
Dev-ops problems tend to be unpopular in organisations. Most people dislike being disturbed of course, but it is also the stress and fraught nature of such incidents which cause Developers to shy away.&lt;br /&gt;
&lt;br /&gt;
I personally believe that there are huge incentives to take on real live problems, but to reap the benefits they must be seen through from start to finish. Like many things in computer science, when a problem is hard do more of it! This, I guess, is why we are seeing more developers become dev-op specialists.&lt;br /&gt;
&lt;u&gt;&lt;br /&gt;&lt;/u&gt;
&lt;u&gt;The Danger&lt;/u&gt;&lt;br /&gt;
&lt;br /&gt;
The danger with all dev-ops is that we spot the problems and find a work-around, because this gets the situation off our backs.&lt;br /&gt;
&lt;br /&gt;
This behaviour can create the &quot;dev-ops infinite loop&quot; because the real source of the problem isn&#39;t fed back into the development process.&lt;br /&gt;
&lt;br /&gt;
As I am writing this now, it sounds obvious: find the issue and make sure there is a pull request into the next release which fixes it, what&#39;s the problem?&lt;br /&gt;
&lt;br /&gt;
Well, it is quite possible that you may not have considered where or how the situation came about from the very beginning. In larger organisations a particular release may have involved many people, which could mean that vital information is lost or unavailable to you. It could also be that information may have been forgotten completely due to a release cycle that is too long or too complex.&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;Understanding Why - Continuing The Case Study&lt;/u&gt;&lt;br /&gt;
&lt;br /&gt;
By Friday team was starting to get desperate because the problem was not going away and we still could not understand why the problem was happening. There seemed to be no difference between out of ours and in hours. A few theories were put forward with minor bug fixes in the code, one of which was a bug which had been present in the system since nearly the first release, lets call this &quot;Theory 1&quot;:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;i&gt;Email templates are being compiled through the Razor engine every time an email is sent. This causes the CPU usage on the Web Instance to ramp up because it is such a resource heavy operation.&lt;/i&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
If you have worked with Razor in a highly scaled system, you may have also come across this problem. A fix was developed and released over the weekend. The email Razor templates would now be pre-compiled on app startup thus reducing the load and solving the problem.&lt;br /&gt;
&lt;br /&gt;
However, come Monday morning this did not calm the server instances down. Every time we ran up a new server instance the load would be OK for a time but then would start bouncing up and down giving our users a poor experience when using the site.&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;A Moment Of Monday Clarity&lt;/u&gt;&lt;br /&gt;
&lt;br /&gt;
&quot;Theory 2&quot;:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;i&gt;There is a workflow which is running which is blocking the web instance and causing the increase in CPU usage.&lt;/i&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
We had to accept on Monday that it was back to the drawing board. The workflows had been disregarded as a potential cause because the monitoring tools we had written to check the database showed that the workflows were being processed very efficiently. However, there seemed to be no other plausible explanation.&lt;br /&gt;
&lt;br /&gt;
Further analysis on the &quot;workflow instance table&quot; in the database showed us that there were a growing number of workflows being fired of a particular type at very particular intervals. We were able to identify this by changing our workflow monitoring tools to look at the number of workflows queued of a particular type, rather than how many workflows were suspended or overdue.&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;The Temporary Fix&lt;/u&gt;&lt;br /&gt;
&lt;u&gt;&lt;br /&gt;&lt;/u&gt;On Monday evening we were able to push a small fix which restricted the workflow in question so that it ran only in out of office hours. We hoped this would get the users and the CEO off our backs - yes it got pretty serious! But we were still not entirely clear on what the route cause of the problem was.&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;Finding A Lasting Solution&lt;/u&gt;&lt;br /&gt;
&lt;u&gt;&lt;br /&gt;&lt;/u&gt;
The final solution to the problem was eventually deduced through some more thorough detective work. The kind of detective work that is hard to do properly when under pressure.&lt;br /&gt;
&lt;br /&gt;
What went into the last release that could be very resource hungry? And what could cause this hunger to increase gradually over the days that proceeded afterwards?&lt;br /&gt;
&lt;br /&gt;
The answer turned out to be from a new more generic workflow which had been written to replace a number of other workflow processes. There was actually nothing wrong with what the workflow was doing. The only error that the developer had made was to fail to consider its impact when deployed &quot;en masse&quot; if you will. This workflow had been written by a developer who had left the company some months before. Something like this would have been tricky to predict.&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;Areas For Improvement&lt;/u&gt;&lt;br /&gt;
&lt;br /&gt;
I would say that this tale lays bare some quite common problems within software organisations.&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Before the software was released, there was no effort made to load test the solution.&lt;/li&gt;
&lt;li&gt;When the release was promoted to production, there were so many changes made by so many developers over so much time that there was no &quot;scrum master&quot; or technical leader who knew enough about what was in the release.&lt;/li&gt;
&lt;li&gt;After the release was running, the tools for monitoring the solution where not sensitive or sophisticated enough to show a larger than expected increase in server resource usage.&lt;/li&gt;
&lt;li&gt;The problem went unnoticed for too long.&lt;/li&gt;
&lt;li&gt;When the problem was identified, developers hoped that it would just &quot;go away&quot; without pursuing the problem vigorously enough.&lt;/li&gt;
&lt;li&gt;Developers put too much faith in one solution working without thinking enough about developing some ideas on other solutions.&lt;/li&gt;
&lt;li&gt;Nobody in the team was calm enough to look through the new feature list and suggest a feature with risks.&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
&lt;br /&gt;
What has happened since this incident:&lt;/div&gt;
&lt;div&gt;
&lt;ul&gt;
&lt;li&gt;UAT goes through a load test before being promoted to Production.&lt;/li&gt;
&lt;li&gt;Releases are kept much smaller and more frequent&lt;/li&gt;
&lt;li&gt;The workflow database monitoring tools have been improved&lt;/li&gt;
&lt;li&gt;We gave ourselves a kick and tried to learn as much as we can from the case.&lt;/li&gt;
&lt;li&gt;The incident resolution process has been looked at.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://garethscode.blogspot.com/feeds/5585240608972903329/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://garethscode.blogspot.com/2016/03/the-dev-ops-cycle-tale-from-trenches.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3311430580289688408/posts/default/5585240608972903329'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3311430580289688408/posts/default/5585240608972903329'/><link rel='alternate' type='text/html' href='http://garethscode.blogspot.com/2016/03/the-dev-ops-cycle-tale-from-trenches.html' title='The dev-ops cycle (a tale from the trenches)'/><author><name>trujillo42</name><uri>http://www.blogger.com/profile/09625726405492153186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3311430580289688408.post-8516199527580348535</id><published>2016-03-11T03:34:00.000-08:00</published><updated>2018-01-14T12:06:44.972-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Python"/><title type='text'>Getting started with Python...in Windows 10</title><content type='html'>&lt;u&gt;Python is increasingly popular&lt;/u&gt;&lt;br /&gt;
The testing team where I work are using it in a big way to run automation scripts. It seems to be the language of choice to teach to 17 and 18 year old&#39;s at A-Level. I was recently forced to admit that I had never written a single line of code in Python... time to change that!&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;Getting started&lt;/u&gt;&lt;br /&gt;
Full of enthusiasm I went to the &lt;a href=&quot;https://wiki.python.org/moin/BeginnersGuide&quot;&gt;beginners guide on the Python Wiki&lt;/a&gt;&amp;nbsp;. Immediately there seems to have be a break in the development of the language. In 2010 Python 3 was released and it looks like some want to hang on to Python 2. Did it really break that badly? Honestly I don&#39;t know the history but it makes for a baffling first impression. Looking around it seems that somebody is recommending Python 3 for learning and then you can go back to v2... erm no thanks! Sounds terrible, I&#39;ll stick to 3. I later found the &lt;a href=&quot;http://pythonclock.org/&quot;&gt;Python 2 clock&lt;/a&gt;, there is&amp;nbsp;a &amp;nbsp;rough deprecation deadline for Python 2.7 in 2020.&lt;br /&gt;
&lt;br /&gt;
Ok, so it looks like JetBrains have made a super cool IDE with a free download... oh I have to pay for this after the 30 day trial. Hmph! Not very friendly for a beginner. I thought this was a script kiddies language?&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;https://www.python.org/downloads/release/python-351/&quot;&gt;This is more like it&lt;/a&gt;. Now all I have to do is download the &lt;a href=&quot;https://www.python.org/ftp/python/3.5.1/python-3.5.1-amd64-webinstall.exe&quot;&gt;web based installer&lt;/a&gt;&amp;nbsp;- it asks me whether &lt;i&gt;&lt;b&gt;I want to install Python to the Windows Path&lt;/b&gt;&lt;/i&gt;, I think yes. In the latest installer, it is not set by default so watch out for this option.&lt;br /&gt;
&lt;br /&gt;
Setup successful and a nice &lt;a href=&quot;https://docs.python.org/3.5/&quot;&gt;link to the docs&lt;/a&gt;. Now we are getting somewhere. I then fire up my Powershell console of choice and type &quot;python&quot;. Thanks to ticking the install to&amp;nbsp;Windows Path&amp;nbsp;option this works.&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/AVvXsEjicIinH0F9uV1wzrrF5MJtDYr6-sSetqY-ZEbt2ZvjvG3exikw22LUdG7rUHKcF2KLC3Y65eDu0XJLV3pPTqdWUCUBqbSNKfzC9tzDqH_TBYN6Ij2eq1qejUR-NuCyRxv0x5DnAAlcgok/s1600/Python1.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;163&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjicIinH0F9uV1wzrrF5MJtDYr6-sSetqY-ZEbt2ZvjvG3exikw22LUdG7rUHKcF2KLC3Y65eDu0XJLV3pPTqdWUCUBqbSNKfzC9tzDqH_TBYN6Ij2eq1qejUR-NuCyRxv0x5DnAAlcgok/s640/Python1.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Now lets do the standard Hello World app. In Python 2 you would write:&lt;br /&gt;
&lt;pre style=&quot;background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdQyqQyWr9eHET9gluk3ft4C47yN6RgAs7etO24lN4DXQ1rrFk048AU2BIdGjzogjVL7wT-sI7VULmiDt32CyeGZprJV_9e98eqKX0TIzNFNSfP_JTukxeqkZuAP-SfsR-gLdqUn9f5-t0/s320/codebg.gif); background: #ccc; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;&quot;&gt;&lt;code style=&quot;color: black; word-wrap: normal;&quot;&gt;&lt;code&gt;print &quot;hello world!&quot;
&lt;/code&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
In Python 3 its:&lt;br /&gt;
&lt;br /&gt;
&lt;pre style=&quot;background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdQyqQyWr9eHET9gluk3ft4C47yN6RgAs7etO24lN4DXQ1rrFk048AU2BIdGjzogjVL7wT-sI7VULmiDt32CyeGZprJV_9e98eqKX0TIzNFNSfP_JTukxeqkZuAP-SfsR-gLdqUn9f5-t0/s320/codebg.gif); background: #ccc; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;&quot;&gt;&lt;code style=&quot;color: black; word-wrap: normal;&quot;&gt;&lt;code&gt;print(&quot;hello world!&quot;)
&lt;/code&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
Confusing huh!&lt;br /&gt;
&lt;br /&gt;
I will continue this tutorial with next time I write. I will demonstrate how to define the structures that underpin the language.</content><link rel='replies' type='application/atom+xml' href='http://garethscode.blogspot.com/feeds/8516199527580348535/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://garethscode.blogspot.com/2016/03/getting-started-with-pythonin-windows-10.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3311430580289688408/posts/default/8516199527580348535'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3311430580289688408/posts/default/8516199527580348535'/><link rel='alternate' type='text/html' href='http://garethscode.blogspot.com/2016/03/getting-started-with-pythonin-windows-10.html' title='Getting started with Python...in Windows 10'/><author><name>trujillo42</name><uri>http://www.blogger.com/profile/09625726405492153186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjicIinH0F9uV1wzrrF5MJtDYr6-sSetqY-ZEbt2ZvjvG3exikw22LUdG7rUHKcF2KLC3Y65eDu0XJLV3pPTqdWUCUBqbSNKfzC9tzDqH_TBYN6Ij2eq1qejUR-NuCyRxv0x5DnAAlcgok/s72-c/Python1.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3311430580289688408.post-8591776275839609725</id><published>2015-10-30T03:04:00.002-07:00</published><updated>2016-01-21T03:55:02.805-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Pester"/><category scheme="http://www.blogger.com/atom/ns#" term="PowerShell"/><title type='text'>PowerShell Unit Testing with Pester 3.3</title><content type='html'>I have been working with the Pester unit testing framework at the moment, so I thought I would share some of the more interesting bits...&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;PowerShell returns everything from a function!&lt;/u&gt;&lt;br /&gt;
&lt;u&gt;&lt;br /&gt;&lt;/u&gt;I think this is a trap every PowerShell programmer has fallen into at some point - probably at the beginning. The return statement will return everything which is not &quot;captured&quot; in a function. In my case the answer was to wrap some xml manipulation code in a function which casts to void so that the return statement would actually return the custom PSObject I was expecting instead of an XmlElement which was being created at some point in my code.&lt;br /&gt;
&lt;br /&gt;
&lt;pre style=&quot;background: rgb(204, 204, 204); border: 1px dashed rgb(204, 204, 204); font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; width: 646.469px;&quot;&gt;&lt;code style=&quot;word-wrap: normal;&quot;&gt;
   [void](do-XmlManipulation $myParamater)
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;a href=&quot;http://manski.net/2013/03/powershell-functions-for-the-uninitiated-c-programmer/&quot;&gt;This was the explanation which really hit home&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
It helped me realise the awful truth!&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;Mocking&lt;/u&gt;&lt;br /&gt;
&lt;u&gt;&lt;br /&gt;&lt;/u&gt;
Mocking in Pester is fantastically simple, there is an object called Mock!&lt;br /&gt;
&lt;br /&gt;
You simply type Mock followed by the function that you wish to mock and then return.&lt;br /&gt;
&lt;pre style=&quot;background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdQyqQyWr9eHET9gluk3ft4C47yN6RgAs7etO24lN4DXQ1rrFk048AU2BIdGjzogjVL7wT-sI7VULmiDt32CyeGZprJV_9e98eqKX0TIzNFNSfP_JTukxeqkZuAP-SfsR-gLdqUn9f5-t0/s320/codebg.gif); background: #ccc; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;&quot;&gt;&lt;code style=&quot;color: black; word-wrap: normal;&quot;&gt;
Mock get-MyObject {
   return { [PSCustomObject]@{ Project = &quot;New and Exciting Project&quot; } }
}

&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
In this case I have returned a Powershell object with the property &quot;Project&quot; which is a string. For example, the code in the module may look like this:
&lt;br /&gt;
&lt;pre style=&quot;background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdQyqQyWr9eHET9gluk3ft4C47yN6RgAs7etO24lN4DXQ1rrFk048AU2BIdGjzogjVL7wT-sI7VULmiDt32CyeGZprJV_9e98eqKX0TIzNFNSfP_JTukxeqkZuAP-SfsR-gLdqUn9f5-t0/s320/codebg.gif); background: #ccc; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;&quot;&gt;&lt;code style=&quot;color: black; word-wrap: normal;&quot;&gt;&lt;code&gt;## myRealCodeModule.psm1

$document = get-MyObject

function get-MyObject {  
   $xmlDocument = Get-Content -Path &quot;C:\temp.xml&quot;
      return $xmlDocument
   }
}
&lt;/code&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
But the unit test will simply bypass the attempt to get the xml file and will return our object, as defined in our unit test, instead.&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;Unit testing powershell modules&lt;/u&gt;&lt;br /&gt;
&lt;u&gt;&lt;br /&gt;&lt;/u&gt;
I keep all my most important logic in PowerShell modules. Sure, I will unit test the main PowerShell script but probably this will be mostly mocking, the real meat should be found in nicely named and separated modules.&lt;br /&gt;
&lt;br /&gt;
Example of testing mocked functions in the main PowerShell script:&lt;br /&gt;
&lt;br /&gt;
&lt;pre style=&quot;background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdQyqQyWr9eHET9gluk3ft4C47yN6RgAs7etO24lN4DXQ1rrFk048AU2BIdGjzogjVL7wT-sI7VULmiDt32CyeGZprJV_9e98eqKX0TIzNFNSfP_JTukxeqkZuAP-SfsR-gLdqUn9f5-t0/s320/codebg.gif); background: #ccc; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;&quot;&gt;&lt;code style=&quot;color: black; word-wrap: normal;&quot;&gt;&lt;code&gt;$scriptPath = Split-Path $script:MyInvocation.MyCommand.Path
Import-Module (&quot;{0}\migrate.ps1&quot; -f $scriptPath) -Verbose

Describe &#39;Migrate&#39; {
    Context &quot;When calling&quot; {
        Mock Restore-Database {
            return &quot;OK&quot;
        }
    }
 
 It &#39;Should call all mocks&#39; {
  Assert-VerifiableMocks
 }
}
&lt;/code&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
One of the strengths of modules is that they must be imported. When they are imported a snapshot is kept in the scope of the importing script. Unfortunately, that means when changing the module, the changes are not immediately reflected because a snapshot still exists against the unit test script. My particular solution is to use &quot;remove-module&quot;. There is the recommended solution from Pester &lt;a href=&quot;https://github.com/pester/Pester/wiki/Unit-Testing-within-Modules&quot;&gt;here&lt;/a&gt;. However, for my purposes this is overkill.&lt;br /&gt;
&lt;br /&gt;
&lt;pre style=&quot;background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdQyqQyWr9eHET9gluk3ft4C47yN6RgAs7etO24lN4DXQ1rrFk048AU2BIdGjzogjVL7wT-sI7VULmiDt32CyeGZprJV_9e98eqKX0TIzNFNSfP_JTukxeqkZuAP-SfsR-gLdqUn9f5-t0/s320/codebg.gif); background: #ccc; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;&quot;&gt;&lt;code style=&quot;color: black; word-wrap: normal;&quot;&gt;
Get-Module | Remove-Module
$scriptPath = (Get-Location).Path
Import-Module (&quot;{0}\myRealCodeModule.psm1&quot; -f $scriptPath)

&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
The other strength of modules is that only exported functions are exposed, which means that functions can be internalised or made &quot;private&quot;. This is a good thing because I have more scope for writing neat, well named functions which will make my code more readable to future maintainers.&lt;br /&gt;
&lt;br /&gt;
Unfortunately this is a potential barrier to unit testing effectively. Luckily Pester has the answer here as well with &quot;InModuleScope&quot;:&lt;br /&gt;
&lt;br /&gt;
&lt;pre style=&quot;background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdQyqQyWr9eHET9gluk3ft4C47yN6RgAs7etO24lN4DXQ1rrFk048AU2BIdGjzogjVL7wT-sI7VULmiDt32CyeGZprJV_9e98eqKX0TIzNFNSfP_JTukxeqkZuAP-SfsR-gLdqUn9f5-t0/s320/codebg.gif); background: #ccc; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;&quot;&gt;&lt;code style=&quot;color: black; word-wrap: normal;&quot;&gt;&lt;code&gt;
   Describe &#39;When unit testing get-MyObject which is not exported by the module&#39; {
      InModuleScope myRealCodeModule {
         It &#39;Should have called the mock&#39; {
            
            Mock get-MyObject {
               return { [PSCustomObject]@{ Project = &quot;New and Exciting Project&quot; } }
            }
            
            my-MainExportedAndThereforePublicFunction

            Assert-MockCalled get-MyObject -Times 1
         }
      }
   }
&lt;/code&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For a getting started guide:&amp;nbsp;&lt;span style=&quot;color: #0000ee; text-decoration: underline;&quot;&gt;see this excellent blog&lt;/span&gt;</content><link rel='replies' type='application/atom+xml' href='http://garethscode.blogspot.com/feeds/8591776275839609725/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://garethscode.blogspot.com/2015/10/powershell-unit-testing-with-pester-33.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3311430580289688408/posts/default/8591776275839609725'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3311430580289688408/posts/default/8591776275839609725'/><link rel='alternate' type='text/html' href='http://garethscode.blogspot.com/2015/10/powershell-unit-testing-with-pester-33.html' title='PowerShell Unit Testing with Pester 3.3'/><author><name>trujillo42</name><uri>http://www.blogger.com/profile/09625726405492153186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3311430580289688408.post-7109261512108875764</id><published>2015-10-12T13:49:00.002-07:00</published><updated>2016-03-11T03:40:17.277-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ES6"/><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript"/><category scheme="http://www.blogger.com/atom/ns#" term="Visual Studio Code"/><title type='text'>ES6 or JS2015 is finally here!</title><content type='html'>Short post this time. I have been away from the Javascripot space for a little while, but now I have started a new NodeJS project.&lt;br /&gt;
&lt;br /&gt;
I am incredibly excited about the wide spread adoption of ES6 this year and I have to say that VS Code has just made me incredibly happy. Not only does VS Code give ES6 intellisense but by telling the IDE that you wish to compile in ES6 you can stop it giving red squiggly lines as well. Fantastic stuff. &lt;a href=&quot;http://stackoverflow.com/questions/29953293/is-there-a-way-to-turn-on-es6-es7-syntax-support-in-vscode&quot;&gt;Just add a jsconfig.json file with the following&lt;/a&gt;:&lt;br /&gt;
&lt;br /&gt;
&lt;pre style=&quot;background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdQyqQyWr9eHET9gluk3ft4C47yN6RgAs7etO24lN4DXQ1rrFk048AU2BIdGjzogjVL7wT-sI7VULmiDt32CyeGZprJV_9e98eqKX0TIzNFNSfP_JTukxeqkZuAP-SfsR-gLdqUn9f5-t0/s320/codebg.gif); background: #ccc; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;&quot;&gt;&lt;code style=&quot;color: black; word-wrap: normal;&quot;&gt;{
    &quot;compilerOptions&quot;: {
        &quot;target&quot;: &quot;ES6&quot;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
The only bad news is that surely I have to remember which features have actually been implemented by the V8 engine.&lt;br /&gt;
&lt;br /&gt;
Well again I was very happy to discover that there is not a &lt;a href=&quot;https://nodejs.org/en/docs/es6/&quot;&gt;great deal left&lt;/a&gt;. The only proviso is that you have to run node --harmony which something you can alias in you command line runner of choice.&lt;br /&gt;
&lt;br /&gt;
The other option is to &lt;a href=&quot;http://www.2ality.com/2015/03/babel-on-node.html&quot;&gt;run babel&lt;/a&gt;. In the end I have settled on doing the following :&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;npm install babel &amp;nbsp;&lt;/li&gt;
&lt;li&gt;Add require((&quot;babel/register&quot;) to the server.js file&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
The advantage of this approach is that I do not have to remember to write a custom build script with the correct parameters.&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://garethscode.blogspot.com/feeds/7109261512108875764/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://garethscode.blogspot.com/2015/10/es6-or-js2015-is-officially-here.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3311430580289688408/posts/default/7109261512108875764'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3311430580289688408/posts/default/7109261512108875764'/><link rel='alternate' type='text/html' href='http://garethscode.blogspot.com/2015/10/es6-or-js2015-is-officially-here.html' title='ES6 or JS2015 is finally here!'/><author><name>trujillo42</name><uri>http://www.blogger.com/profile/09625726405492153186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3311430580289688408.post-1451099095717208977</id><published>2015-08-03T14:51:00.002-07:00</published><updated>2015-08-11T16:40:43.116-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Gulp"/><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript"/><title type='text'>A Basic Gulp Gotcha</title><content type='html'>Recently I have been incorporating gulp into my personal website project. For those completely unfamiliar with Gulp, it is a tool which can be used to primarily to amalgamate your css or javascript into a single file to reduce the number of web requests required to satisfy your various dependencies. Checkout &lt;a href=&quot;http://markdalgleish.github.io/presentation-build-wars-gulp-vs-grunt/&quot;&gt;this highly amusing slideshow comparing Gulp with Grunt&lt;/a&gt;, it also gives further detail as to why these sort of build tools are such a good idea. It is worth noting that minifying may not be necessary if utilising &amp;nbsp;&lt;a href=&quot;https://en.wikipedia.org/wiki/HTTP/2#HTTP.2FHTTPS_servers&quot;&gt;HTTP/2&lt;/a&gt;&amp;nbsp;&quot;server push&quot; technology. However there are many plugins and use cases for Grunt which you may still find useful.&lt;br /&gt;
&lt;br /&gt;
I configured my gulpfile.js to do just three things:&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;Concatenate all files from a set directory into one file and put it in the build folder&lt;/li&gt;
&lt;li&gt;Minify the resulting JavasScript&lt;/li&gt;
&lt;li&gt;Rename the file, changing the extension to .min.js&lt;/li&gt;
&lt;/ol&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/AVvXsEhXNzWKAruUL1bHbFDu4NFTsIkiBrU8f5ofxuvQgCHaB_vefaaOpkXoJjpeqbnGVMEmDcojxlZNO2mSA9Mr33ADorJeD9imBbtC7PM0W_CZ1vD65cRt6d6dhn4aTUTe0VOISelLUNM7lsA/s1600/Gulp+build+script.png&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;136&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXNzWKAruUL1bHbFDu4NFTsIkiBrU8f5ofxuvQgCHaB_vefaaOpkXoJjpeqbnGVMEmDcojxlZNO2mSA9Mr33ADorJeD9imBbtC7PM0W_CZ1vD65cRt6d6dhn4aTUTe0VOISelLUNM7lsA/s320/Gulp+build+script.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Everything was working great. By simply running &#39;gulp app-build&#39; from the command line I could produce a nice small file, perfect for a snappy web experience.&lt;br /&gt;
&lt;br /&gt;
However, I came across some serious issues when trying to deploy the project to production. I tried adding Gulp to my &lt;a href=&quot;https://github.com/projectkudu/kudu&quot;&gt;Kudu&lt;/a&gt; deployment script like I had done to load my npm modules. I was frustrated when despite my insistent hacking (which went further into the early hours of the night than I would like to admit!) I kept getting the following error or similar:&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&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/AVvXsEgEo7SKRPq3LqiFsBWUydaM1vOMPHKk_6cTX2Lnd7okjKmz1-bVZvH4L8xjBw0es2xMTK5gEvi0sXK0peIkyqxDY175dd3Gmj3Ib6BTGQNdgIkQ5QauhcMRze_fX0Mj3GIXuPMbt8YXNkI/s1600/windowAzureDeployLogGulpFail.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/AVvXsEgEo7SKRPq3LqiFsBWUydaM1vOMPHKk_6cTX2Lnd7okjKmz1-bVZvH4L8xjBw0es2xMTK5gEvi0sXK0peIkyqxDY175dd3Gmj3Ib6BTGQNdgIkQ5QauhcMRze_fX0Mj3GIXuPMbt8YXNkI/s1600/windowAzureDeployLogGulpFail.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
When I came back to revisit this problem during a sensible time of day, I discovered my mistake.&lt;br /&gt;
This issue on &lt;a href=&quot;https://github.com/Swiip/generator-gulp-angular/issues/665&quot;&gt;Github was a particular givaway&lt;/a&gt;. My thanks to Matheiu Swiip. I had incorrectly assumed that gulp was a tool that I could make a part of my build.&lt;br /&gt;
&lt;br /&gt;
UPDATE:&lt;br /&gt;
Having spoken to a colleague about this, it turns out that you can in fact use gulp as part of the build. But any dependencies marked as &quot;dev-dependencies&quot; in the npm package file. So all I need to do is move the ones I need for my build into the main &quot;dependencies&quot; area.&lt;br /&gt;
&lt;br /&gt;
I don&#39;t think that anybody doubts the reasons for minfying JS files. But in case anybody is interested, this is the difference it made to my AngularJS app:&lt;br /&gt;
&lt;br /&gt;
We start with:&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&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/AVvXsEhloS7dEN-sDCoCC2RJdYZbVyw9_Tgy2k8clF2Dcb4bTv7uB0ZW09oq_orHWYHzXcGwjR6n2_6hmyfO2HEaT5vrWleobOSj-N62oZHoYFpP84WnG90iDZ2_79HhDmMw0OW_Mi-6SAwW0Jk/s1600/before+minification.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;230&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhloS7dEN-sDCoCC2RJdYZbVyw9_Tgy2k8clF2Dcb4bTv7uB0ZW09oq_orHWYHzXcGwjR6n2_6hmyfO2HEaT5vrWleobOSj-N62oZHoYFpP84WnG90iDZ2_79HhDmMw0OW_Mi-6SAwW0Jk/s640/before+minification.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
And after minfication:&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/AVvXsEjSlroGjJX6NoNlwXEm4aqhY-avaBuw-ZLTfsoc7npAGAnZPwv3Zb4ANatoID0l0m78mVTqvbH9j5i0lMRvCOv-dTI92r7bW_YurCAB62hKrPmHs2qFttQIKeHc97VUxCNTwif_KAFNCrY/s1600/after+minification.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;249&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjSlroGjJX6NoNlwXEm4aqhY-avaBuw-ZLTfsoc7npAGAnZPwv3Zb4ANatoID0l0m78mVTqvbH9j5i0lMRvCOv-dTI92r7bW_YurCAB62hKrPmHs2qFttQIKeHc97VUxCNTwif_KAFNCrY/s640/after+minification.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
At 938KB and 123KB we can see that AngularJS itself is the biggest file.&lt;br /&gt;
&lt;br /&gt;
When finally I got gulp working properly in my production environment and I had concatenated and minified my dependencies things started looking really peachy:&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/AVvXsEjTDQu5Go-fgVLMhiBQ2qYYBKRZYb-0ae7IwkmeK5Wgu0IgIaii1Pepusl12N2k2nD1SRMjUgC01cKJlmvK6Q_49_Ms6IOSF0zB-OVpbv04MWHYZ45akTkMf6s20fWvdoyCYyeUTALLAX4/s1600/brutallyminifieddependencies.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;164&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjTDQu5Go-fgVLMhiBQ2qYYBKRZYb-0ae7IwkmeK5Wgu0IgIaii1Pepusl12N2k2nD1SRMjUgC01cKJlmvK6Q_49_Ms6IOSF0zB-OVpbv04MWHYZ45akTkMf6s20fWvdoyCYyeUTALLAX4/s640/brutallyminifieddependencies.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://garethscode.blogspot.com/feeds/1451099095717208977/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://garethscode.blogspot.com/2015/08/a-basic-gulp-gotcha.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3311430580289688408/posts/default/1451099095717208977'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3311430580289688408/posts/default/1451099095717208977'/><link rel='alternate' type='text/html' href='http://garethscode.blogspot.com/2015/08/a-basic-gulp-gotcha.html' title='A Basic Gulp Gotcha'/><author><name>trujillo42</name><uri>http://www.blogger.com/profile/09625726405492153186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXNzWKAruUL1bHbFDu4NFTsIkiBrU8f5ofxuvQgCHaB_vefaaOpkXoJjpeqbnGVMEmDcojxlZNO2mSA9Mr33ADorJeD9imBbtC7PM0W_CZ1vD65cRt6d6dhn4aTUTe0VOISelLUNM7lsA/s72-c/Gulp+build+script.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3311430580289688408.post-6617538627894320000</id><published>2015-04-04T16:17:00.002-07:00</published><updated>2016-02-25T02:30:13.921-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Azure"/><category scheme="http://www.blogger.com/atom/ns#" term="DNS"/><title type='text'>The full DNS lowdown for your website - A practical guide focusing on Windows Azure</title><content type='html'>&lt;style&gt;
   .dnsrecord { border: #000; }
&lt;/style&gt;
Ok, so what is DNS or the Domain Name System? I have always thought of it as a human friendly way of naming computers which are serving content. However, while a snappy explanation to serve up to a non technical person, it does not really get to the knob of the issue.&lt;br /&gt;
&lt;br /&gt;
DNS assigns names to IP addresses,&amp;nbsp;DNS is Hierarchical and DNS is a protocol.&lt;br /&gt;
&lt;br /&gt;
The DNS protocol specification simply describes how the DNS records should be formatted. This means that there is no need to have a single centralised database, indeed this would be very unwise!&lt;br /&gt;
&lt;br /&gt;
Each DNS record has a type. There are a number of types, but the most commonly used are A, CNAME, MX and NS.&lt;br /&gt;
&lt;br /&gt;
For those who really want to dig into the full specification Microsoft have compiled the current documents for the DNS specification&amp;nbsp;&lt;a href=&quot;https://msdn.microsoft.com/en-us/library/windows/desktop/ms682099%28v=vs.85%29.aspx&quot;&gt;here&lt;/a&gt;. For instance if you want to know what the types really are see&amp;nbsp;&lt;span style=&quot;white-space: pre-wrap;&quot;&gt;RFC 1034 (November 1987).&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;color: #bf9000; font-size: large;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;color: #bf9000; font-size: large;&quot;&gt;Setting up DNS for your website&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
So moving away from theory to real life ...I want to set up my website so that when you type the URL mysite.com into chrome it goes straight to my website.&lt;br /&gt;
&lt;br /&gt;
First of all I need to buy a domain name. There are a number of providers, Ghandi and DNSSimple are considered particularly good ones.&lt;br /&gt;
&lt;br /&gt;
Once I have bought a domain name I can get going and set-up some CNAME (&lt;span style=&quot;white-space: pre-wrap;&quot;&gt;canonical name of an Alias - see RFC 1034 :-) &lt;/span&gt;) records. This is because in this first instance I am telling my domain name to simply look for the azure domain name server which will be something like myproject.azuresites.com.&lt;br /&gt;
&lt;br /&gt;
Therefore my CNAME record looks like:&lt;br /&gt;
&lt;table class=&quot;dnsrecord&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;th&gt;host&lt;/th&gt;&lt;th&gt;&amp;nbsp;type&lt;/th&gt;&lt;th&gt;target&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;www&lt;/td&gt; &lt;td&gt;&amp;nbsp; &amp;nbsp; CNAME&lt;/td&gt; &lt;td&gt;&amp;nbsp; &amp;nbsp; myproject.azuresites.net&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
So when I go to www.mydomain.com I get the resource hosted at myproject.azuresites.net.&lt;br /&gt;
&lt;br /&gt;
What is actually happening here is that Azure has already setup an A record pointing from myproject.azuresites.net to the virtual IP address. The virtual IP address will then resolve to any number of different boxes in their &quot;Cloud&quot; server farm. I imagine it is probably powered by nerd sweat =P.&lt;br /&gt;
&lt;br /&gt;
DNS changes &lt;i&gt;can&lt;/i&gt; take up to 48 hours to propagate, although personally I have never had to wait longer than half an hour. There are a few little tricks which can help to minimise any confusion: &lt;br /&gt;
&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;Try checking a DNS tracking site e.g.&amp;nbsp;&lt;a href=&quot;https://www.whatsmydns.net/&quot;&gt;whatsmydns.net&lt;/a&gt;&amp;nbsp;&lt;/li&gt;
&lt;li&gt;If it has propagated and you are still not seeing the correct result try flushing your local DNS cache by going to the cmd prompt and typing: ipconfig/flushdns.&lt;/li&gt;
&lt;/ol&gt;
&lt;span style=&quot;color: #bf9000; font-size: large;&quot;&gt;&lt;br /&gt;&lt;/span&gt;

&lt;span style=&quot;color: #bf9000; font-size: large;&quot;&gt;Incoming email&lt;/span&gt;&lt;br /&gt;
&lt;u&gt;&lt;br /&gt;&lt;/u&gt;
What I want to do is push all the emails sent into my domains email address into my gmail account. To do this I need to understand a little about the DNS Mail Exchanger (MX) record.&lt;br /&gt;
&lt;br /&gt;
So, the MX record.&lt;br /&gt;
&lt;table class=&quot;dnsrecord&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;th&gt;host&lt;/th&gt;&lt;th&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; type&lt;/th&gt;&lt;th&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; target&lt;/th&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&amp;nbsp;&amp;nbsp;@ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;MX &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ? depends ?&lt;br /&gt;
&lt;br /&gt;
The target depends on what you are trying to achieve. You need a &quot;mailbox&quot; which is going to track emails going to your domain. E.g. &lt;i&gt;&lt;b&gt;to&lt;/b&gt;&lt;/i&gt; email@mydomain.com.&lt;br /&gt;
&lt;br /&gt;
The easiest way is to buy a mailbox from your domain supplier and then configure your preferred email client app (e.g. gmail, yahoo etc...) to look at their&amp;nbsp;SMTP server. You can then send/receive the mail from the mailbox via SSL encrypted connection. Take a look at &lt;a href=&quot;https://www.digitalocean.com/community/tutorials/how-to-use-google-s-smtp-server&quot;&gt;this page&lt;/a&gt;&amp;nbsp;for help on setting this up. I am working on providing you an alternative solution so watch this space...!&lt;br /&gt;
&lt;span style=&quot;color: #bf9000; font-size: large;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;color: #bf9000; font-size: large;&quot;&gt;Outgoing Email&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #bf9000; font-size: large;&quot;&gt;&lt;span style=&quot;color: black; font-size: small;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span style=&quot;color: #bf9000; font-size: large;&quot;&gt;&lt;span style=&quot;color: black; font-size: small;&quot;&gt;This is actually a big subject, many organisations and individuals have got into a lot of trouble over outgoing emails form an app. Span has always been the issue. The steps put in place to reduce spam have unfortunately produced a world where people often say &quot;Your system/ you didn&#39;t send the email :( &quot;.... &quot; yes I have :/&quot;...&quot;Have you checked your span filter? :)&quot;.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #bf9000; font-size: large;&quot;&gt;&lt;span style=&quot;color: black; font-size: small;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;
&lt;br /&gt;
&lt;span style=&quot;color: #bf9000; font-size: medium;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;color: #bf9000; font-size: large;&quot;&gt;Non-www&lt;/span&gt;&lt;br /&gt;
&lt;u&gt;&lt;br /&gt;&lt;/u&gt;Generally people no longer bother with typing the full address www.mydomain.com. In fact, the average Joe, will be completely baffled as to why their browser throws back an error.&lt;br /&gt;
&lt;br /&gt;
Again DNS comes to the rescue, try:&lt;br /&gt;
&lt;table class=&quot;dnsrecord&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;th&gt;host&lt;/th&gt;&lt;th&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; type&lt;/th&gt;&lt;th&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; target&lt;/th&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&amp;nbsp; @ &amp;nbsp; &amp;nbsp; &amp;nbsp;CNAME &amp;nbsp; &amp;nbsp;myproject.azuresites.net&lt;br /&gt;
&lt;br /&gt;
If you use this in conjunction with the &#39;www&#39; record mentioned above then your users should be able to go to www.mydomain.com or mydomain.com with the same result.... some juicy content. hmmm!&lt;br /&gt;
&lt;br /&gt;
Generally you may think that one or the other domain names (non-www or with www) is the preferable URL which should be visible to &quot;the average Joe&quot;. What you probably want is the server to immediately redirect to say mydomain.com as soon as somebody goes to www.mydomain.com in their browser.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;There are a number of techniques for doing this. With an IIS or Apache web server you can use a command line file which by convention is of the file type .htaccess. Placing this file in the route directory of your code will cause the hosting OS to immediately run the file when serving a resource. You can write something like:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;background-color: #eeeeee; color: #444444; font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace; font-size: 14.08px; line-height: 21.12px;&quot;&gt;# Redirect www urls to non-www&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: #eeeeee; color: #444444; font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace; font-size: 14.08px; line-height: 21.12px;&quot;&gt;RewriteEngine on&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: #eeeeee; color: #444444; font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace; font-size: 14.08px; line-height: 21.12px;&quot;&gt;RewriteCond %{HTTP_HOST} !^mydomain\.com&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: #eeeeee; color: #444444; font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace; font-size: 14.08px; line-height: 21.12px;&quot;&gt;RewriteRule (.*) http://mydomain.com/$1 [R=301,L]&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: white; font-size: 14.08px; line-height: 21.12px;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;background-color: white; font-size: 14.08px; line-height: 21.12px;&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;I am using NodeJS and this has its own technique to achieve this:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
// redirect for non-www&lt;br /&gt;
app.all(&#39;/*&#39;, function(req, res, next) {&lt;br /&gt;
&amp;nbsp; if (req.headers.host.match(/^www\./) !== null) {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; res.redirect(301, req.protocol + &#39;://&#39; + req.headers.host.replace(/^www\./, &#39;&#39;) + req.url);&lt;br /&gt;
&amp;nbsp; } else {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; next(); &lt;br /&gt;
&amp;nbsp; }&lt;br /&gt;
})&lt;br /&gt;
&lt;br /&gt;
app.set(&#39;trust proxy&#39;, true);&lt;br /&gt;
&lt;u&gt;&lt;br /&gt;&lt;/u&gt;&lt;span style=&quot;color: #bf9000; font-size: large;&quot;&gt;Sub-domains&lt;/span&gt;&lt;br /&gt;
&lt;u&gt;&lt;br /&gt;&lt;/u&gt;Again these are easy to setup as well. Simply use the * symbol in your CNAME record:&lt;br /&gt;
* CNAME myproject.azuresites.net&lt;br /&gt;
&lt;br /&gt;
Then the request to a certain subdomain e.g. elephants.mydomain.com can be sniffed for and intercepted by your code.</content><link rel='replies' type='application/atom+xml' href='http://garethscode.blogspot.com/feeds/6617538627894320000/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://garethscode.blogspot.com/2015/04/setting-up-dns-for-your-website.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3311430580289688408/posts/default/6617538627894320000'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3311430580289688408/posts/default/6617538627894320000'/><link rel='alternate' type='text/html' href='http://garethscode.blogspot.com/2015/04/setting-up-dns-for-your-website.html' title='The full DNS lowdown for your website - A practical guide focusing on Windows Azure'/><author><name>trujillo42</name><uri>http://www.blogger.com/profile/09625726405492153186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total><georss:featurename>Oxford, Oxford, UK</georss:featurename><georss:point>51.7520209 -1.2577263000000585</georss:point><georss:box>51.594735899999996 -1.5804498000000584 51.9093059 -0.93500280000005853</georss:box></entry><entry><id>tag:blogger.com,1999:blog-3311430580289688408.post-6724733410960635502</id><published>2014-11-05T15:09:00.003-08:00</published><updated>2015-05-31T09:38:56.409-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Asynchronous"/><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript"/><category scheme="http://www.blogger.com/atom/ns#" term="NodeJS"/><title type='text'>Asynchronous JavaScript programming in Node</title><content type='html'>I want to be able to read an atom feed!! This is NodeJS, so of course there is this great library for doing just that (&lt;a href=&quot;https://github.com/sentientwaffle/feed-read/blob/master/index.js&quot;&gt;feed-read&lt;/a&gt;), the feed function is asynchronous. I also want to use a Node abstraction in the form using Express modules.&lt;br /&gt;
Ok, no problem, I thought. I tried putting the feed directly in my server.js file. There was a simple problem - I don&#39;t have the blog data because feed-read has made an asynchronous call to gather the feed information leaving me with nothing.&lt;br /&gt;
Once I understood the problem I started searching for solutions. What generally comes up are yet more helpful libraries to help you &#39;deal with&#39; the async &#39;problem&#39;.&lt;br /&gt;
I am sure there are more complicated problems which may merit a complex library but I happen to know that this is something that JavaScript is great at. JQuery introduced the idea of a promise in version 1.5 and this is basically the same problem, with a similar solution. So the answer?&lt;br /&gt;
&lt;br /&gt;
In my case chain callbacks. Yes, if you are using a function from an abstracted module, pass in a function which will then pass a function etc... When the function at the bottom of the chain passes us some data back we will be ready!! Use an API call to do this perhaps so we can give our users a spinner while they are waiting.&lt;br /&gt;
&lt;ul&gt;
&lt;pre style=&quot;background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdQyqQyWr9eHET9gluk3ft4C47yN6RgAs7etO24lN4DXQ1rrFk048AU2BIdGjzogjVL7wT-sI7VULmiDt32CyeGZprJV_9e98eqKX0TIzNFNSfP_JTukxeqkZuAP-SfsR-gLdqUn9f5-t0/s320/codebg.gif); background: #ccc; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;&quot;&gt;&lt;code style=&quot;color: black; word-wrap: normal;&quot;&gt; var blogReader = { 
  GetMostRecentBlog : function(callback) {  
    feed(&#39;http://bloglocation.com/feeds&#39;, function(articles) {  
     var mostRecentBlogPost = articles[0];  
     var blog = {  
        Title: mostRecentBlogPost.title,  
        Content: mostRecentBlogPost.content  
     };  
     callback(blog);  
   }); 
};  
module.exports = blogReader;
&lt;/code&gt;&lt;/pre&gt;
You then can use it like :

&lt;pre style=&quot;background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdQyqQyWr9eHET9gluk3ft4C47yN6RgAs7etO24lN4DXQ1rrFk048AU2BIdGjzogjVL7wT-sI7VULmiDt32CyeGZprJV_9e98eqKX0TIzNFNSfP_JTukxeqkZuAP-SfsR-gLdqUn9f5-t0/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;&quot;&gt;&lt;code style=&quot;color: black; word-wrap: normal;&quot;&gt; blogReader.GetMostRecentBlog(function(blog) {  
   //use Blog object here for display  
 });  
&lt;/code&gt;&lt;/pre&gt;
&lt;/ul&gt;
I found this exact pattern in Mixu&#39;s Node book chapter 7 - http://book.mixu.net/node/ch7.html.
He also talks about two other useful patterns to deal with asynchronous calls which may be useful on larger scale projects - Parallel and Limited Parallel patterns.&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;As always, the code for my solution can be found on &lt;a href=&quot;https://github.com/garethfentimen/gfentimencom&quot;&gt;github&lt;/a&gt;.</content><link rel='replies' type='application/atom+xml' href='http://garethscode.blogspot.com/feeds/6724733410960635502/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://garethscode.blogspot.com/2014/11/nodejs-and-asynchronous-code.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3311430580289688408/posts/default/6724733410960635502'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3311430580289688408/posts/default/6724733410960635502'/><link rel='alternate' type='text/html' href='http://garethscode.blogspot.com/2014/11/nodejs-and-asynchronous-code.html' title='Asynchronous JavaScript programming in Node'/><author><name>trujillo42</name><uri>http://www.blogger.com/profile/09625726405492153186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3311430580289688408.post-3166829748509811538</id><published>2014-09-14T14:37:00.001-07:00</published><updated>2015-05-31T09:39:18.851-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Express"/><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript"/><category scheme="http://www.blogger.com/atom/ns#" term="NodeJS"/><title type='text'>NodeJS progress and the mighty Bootstrap</title><content type='html'>&lt;style&gt;
.code {
    background: #292929;
    border: 1px solid rgb(221, 221, 221); 
    color: #ccc;
    font-family: Helvetica, Arial, sans-serif; 
    line-height: 24px; 
    overflow: auto; 
    padding: 2px 10px !important;
}
&lt;/style&gt;
Since writing my last post I have spent some more time with NodeJS.&lt;br /&gt;
Things I have done:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;I created an API using Express using this article to create some bears - http://scotch.io/tutorials/javascript/build-a-restful-api-using-node-and-express-4)&amp;nbsp;&lt;/li&gt;
&lt;li&gt;I added a favicon using this -&amp;nbsp;https://github.com/expressjs/serve-favicon&lt;/li&gt;
&lt;li&gt;I pondered Jade as my view engine and then quickly decided that Handlebars would be much easier as I was already very familiar -&amp;nbsp;https://github.com/ericf/express-handlebars&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
As you can see progress is good.&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Unfortunately, next came the bit I always dread, trying to set out an effective design for the website. I struggle as a designer. At university I got familiar Photoshop and Illustrator, and while I really liked doing it at the time, sadly I have not kept up with the evolution of the software since. Luckily I can just prototype and see where it...&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
...Mild panic began to build.... oh god what about phones and tablets! As if deciding on a design isn&#39;t hard enough, I have to think responsive! Anyway - thank god for the kind people/companies of open source. Luckily we have &lt;a href=&quot;http://foundation.zurb.com/&quot;&gt;Zurb Foundation&lt;/a&gt; and &lt;a href=&quot;http://getbootstrap.com/&quot;&gt;Bootstrap&lt;/a&gt;. Zurb Foundation is fantastic, but as I am already familiar with Zurb I thought I would use Bootstrap.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
I am not going to bore you with all the details but provide you with my gotcha&#39;s list:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;ul&gt;
&lt;li&gt;By default Node does not permit the public directory to be accessed. I wanted to do this so I could access the bootstrap files which were stored in public/libs. If you would like to store your bower packages in a custom directory rather than the default like me, create a .bowerrc file in your route directory with no file name, if unsure check &lt;a href=&quot;http://stackoverflow.com/questions/5004633/how-to-manually-create-a-file-with-a-dot-prefix-in-windows-for-example-htacce&quot;&gt;this&lt;/a&gt;. Then add the following:&amp;nbsp;
&lt;div class=&quot;code&quot;&gt;
{
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &quot;directory&quot;: &quot;public/libs&quot;
&lt;br /&gt;
}
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;To access the public directory for styles and scripts:&lt;div class=&quot;code&quot;&gt;
app.use(express.static(__dirname + &#39;/public&#39;));
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;To use in your views:&lt;div class=&quot;code&quot;&gt;
&amp;lt;script src=&quot;libs/bootstrap/dist/js/bootstrap.min.js&quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;Use navbar-static-top rather than navbar-fixed-top. This is a new class as of Bootstrap 3.0, it addresses the problem wherein the navbar sits over the content of the page.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://garethscode.blogspot.com/feeds/3166829748509811538/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://garethscode.blogspot.com/2014/09/nodejs-progress-and-mighty-bootstrap.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3311430580289688408/posts/default/3166829748509811538'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3311430580289688408/posts/default/3166829748509811538'/><link rel='alternate' type='text/html' href='http://garethscode.blogspot.com/2014/09/nodejs-progress-and-mighty-bootstrap.html' title='NodeJS progress and the mighty Bootstrap'/><author><name>trujillo42</name><uri>http://www.blogger.com/profile/09625726405492153186</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>