<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Nick W</title>
    <description>The latest articles on Forem by Nick W (@nickp60).</description>
    <link>https://forem.com/nickp60</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4863%2F34c06ea0-df7c-4358-8c01-de354b260abe.jpg</url>
      <title>Forem: Nick W</title>
      <link>https://forem.com/nickp60</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/nickp60"/>
    <language>en</language>
    <item>
      <title>My three steps to more manageable bash profiles</title>
      <dc:creator>Nick W</dc:creator>
      <pubDate>Wed, 25 Oct 2017 13:17:52 +0000</pubDate>
      <link>https://forem.com/nickp60/my-three-steps-to-more-manageable-bash-profiles-dh5</link>
      <guid>https://forem.com/nickp60/my-three-steps-to-more-manageable-bash-profiles-dh5</guid>
      <description>&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://shreevatsa.wordpress.com/2008/03/30/zshbash-startup-files-loading-order-bashrc-zshrc-etc/"&gt;great blog post on load order&lt;/a&gt;&lt;br&gt;
&lt;a href="https://stackoverflow.com/questions/415403/whats-the-difference-between-bashrc-bash-profile-and-environment"&gt;an insightful SO question&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;I work on a Linux distro called BioLinux, which is built on top of Ubuntu 14.  This came with zsh as the default shell. As I have been transitioning into the computer world from being a lab biologist, I had a lot of questions starting out.  One recurring question was how to set the $PATH variable.  Every time I tried to install a new program, I was faced with a decision:  do I change the path in .bashrc, .bash_profile, .zshrc, or .profile?  I ended having spaghetti code calling all of those in some order.  Each was a mix of variables, aliases, custom function, and so on.&lt;/p&gt;

&lt;p&gt;Things got even more complicated when I would ssh into this computer and discover that the $PATH variable was different or missing.&lt;/p&gt;

&lt;p&gt;Later, I started to work more and more on remote machines, and wanted to have my settings the same across the different shells.  Some of these machines have both zsh and bash, others just have bash.&lt;/p&gt;

&lt;p&gt;This past weekend, I sorted out my mess, and wanted to share what I see as a managble solution (for now!).&lt;/p&gt;
&lt;h2&gt;
  
  
  Fix #1: Stick to one shell
&lt;/h2&gt;

&lt;p&gt;Half of my confusion was due to working in zsh on my main machine, and in bash on the three remote machines I regularly use. I never had any issues with zsh, but after some googling, I discovered that I was not making use of all of zsh's features.  So I decided to switch back to good 'ol bash for two reasons:&lt;br&gt;
1) to keep things the same across all the machines I use.&lt;br&gt;
2) to simplify. I clearly was not using zsh as it could be used, and so I made the decision to move to bash until I felt I needed the extras that zsh offers.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;chsh &lt;span class="nt"&gt;-s&lt;/span&gt; /bin/bash myuser
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Fix #2: Keep things the same between interactive, and non-interactive shells
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://superuser.com/questions/183870/difference-between-bashrc-and-bash-profile"&gt;https://superuser.com/questions/183870/difference-between-bashrc-and-bash-profile&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I still don't understand the in's and out's of this, but .bashrc isn't checked whenever you open a new shell -- .bash_profile is.  But as I wanted my settings to be called both in login shells and over ssh sessions, etc, I simplified the structure by changing my .bash_profile to the following 3 lines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; ~/.bashrc &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
   &lt;/span&gt;&lt;span class="nb"&gt;source&lt;/span&gt; ~/.bashrc
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, when I open a new shell, .bash_profile is called, which then loads everything I have in my .bashrc;  this way, I get the same behaviour no matter when I login from or what I am doing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fix #3: Separate machine-specific things from convenience things
&lt;/h2&gt;

&lt;p&gt;I like having nice colors in my shell, custom aliases, git status in my prompt, and other fun stuff.  I wanted to have the same aliases, functions, and color setting on each of my machines. But I couldn't just copy my .bashrc to different machines, as the $PATHs would be different.&lt;/p&gt;

&lt;p&gt;My solution was to go through my .bashrc and move all the me-specific things to a new file, which I called .nickstuff.  Then, I added  the following line to the end of my .bashrc&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;source&lt;/span&gt; ~/.nickstuff
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, when I get access to a new machine, I can move that .nickstuff file to my new machine's home directory, add that same line to the new machines .bashrc, and I have access to all the features the make my life easier.&lt;/p&gt;

&lt;p&gt;For those curious, here is what I have in my .nickstuff file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;##### stuff fo aesthetics, etc&lt;/span&gt;
&lt;span class="nb"&gt;alias &lt;/span&gt;&lt;span class="nv"&gt;pyclean&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'find . | grep -E "(__pycache__|\.pyc|\.pyo$)" | xargs rm -rf'&lt;/span&gt;
&lt;span class="nb"&gt;alias &lt;/span&gt;&lt;span class="nv"&gt;duh&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"du ./ --max-depth 1 -h"&lt;/span&gt;
&lt;span class="nb"&gt;alias &lt;/span&gt;&lt;span class="nv"&gt;diffy&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'diff -y --suppress-common-lines'&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HOST&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'gruffalo'&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;HOST_COLOR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\[&lt;/span&gt;&lt;span class="s2"&gt;033[1;36m&lt;/span&gt;&lt;span class="se"&gt;\]&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;


&lt;span class="c"&gt;# custom&lt;/span&gt;
kptrk&lt;span class="o"&gt;(){&lt;/span&gt;
    &lt;span class="nb"&gt;source&lt;/span&gt; ~/.bash-preexec.sh
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$KPTRK_ON&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;true&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"KeePTRacK is disabled"&lt;/span&gt;
    preexec&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
    precmd&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;KPTRK_ON&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;false
    export &lt;/span&gt;&lt;span class="nv"&gt;KPTRK_DIR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0
    &lt;span class="k"&gt;else
    &lt;/span&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;KPTRK_DIR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;pwd&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"KeePTRacK is enabled!"&lt;/span&gt;
    preexec&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="se"&gt;\t&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$KPTRK_DIR&lt;/span&gt;/kptrk_README&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
    precmd&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"kptrk is on"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;KPTRK_ON&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true
    &lt;/span&gt;&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;# get rid of files added when running setup.py&lt;/span&gt;
rmsetup&lt;span class="o"&gt;(){&lt;/span&gt;
    python setup.py &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--record&lt;/span&gt; files.txt
    &lt;span class="nb"&gt;cat &lt;/span&gt;files.txt | xargs &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;# prompt stuff&lt;/span&gt;
&lt;span class="c"&gt;# my default PS1&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;PS1_def&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\[\0&lt;/span&gt;&lt;span class="s2"&gt;33[38;5;49m&lt;/span&gt;&lt;span class="se"&gt;\]\u\[&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;tput sgr0&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="se"&gt;\]\[\0&lt;/span&gt;&lt;span class="s2"&gt;33[38;5;15m&lt;/span&gt;&lt;span class="se"&gt;\]&lt;/span&gt;&lt;span class="s2"&gt;@&lt;/span&gt;&lt;span class="se"&gt;\[&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;tput sgr0&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="se"&gt;\]\[\0&lt;/span&gt;&lt;span class="s2"&gt;33[38;5;34m&lt;/span&gt;&lt;span class="se"&gt;\]\h\[&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;tput sgr0&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="se"&gt;\]\[\0&lt;/span&gt;&lt;span class="s2"&gt;33[38;5;15m&lt;/span&gt;&lt;span class="se"&gt;\]&lt;/span&gt;&lt;span class="s2"&gt;[&lt;/span&gt;&lt;span class="se"&gt;\[&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;tput sgr0&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="se"&gt;\]\[\0&lt;/span&gt;&lt;span class="s2"&gt;33[38;5;139m&lt;/span&gt;&lt;span class="se"&gt;\]\W\[&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;tput sgr0&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="se"&gt;\]\[\0&lt;/span&gt;&lt;span class="s2"&gt;33[38;5;15m&lt;/span&gt;&lt;span class="se"&gt;\]&lt;/span&gt;&lt;span class="s2"&gt;]&lt;/span&gt;&lt;span class="se"&gt;\$&lt;/span&gt;&lt;span class="s2"&gt;(__git_ps1) &lt;/span&gt;&lt;span class="se"&gt;\[&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;tput sgr0&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="se"&gt;\]&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="c"&gt;# teaching PS1&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;PS1_teach&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\[\0&lt;/span&gt;&lt;span class="s2"&gt;33[38;5;202m&lt;/span&gt;&lt;span class="se"&gt;\]\u\[&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;tput sgr0&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="se"&gt;\]\[\0&lt;/span&gt;&lt;span class="s2"&gt;33[38;5;15m&lt;/span&gt;&lt;span class="se"&gt;\]&lt;/span&gt;&lt;span class="s2"&gt;[&lt;/span&gt;&lt;span class="se"&gt;\[&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;tput sgr0&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="se"&gt;\]\[\0&lt;/span&gt;&lt;span class="s2"&gt;33[38;5;10m&lt;/span&gt;&lt;span class="se"&gt;\]\w\[&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;tput sgr0&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="se"&gt;\]\[\0&lt;/span&gt;&lt;span class="s2"&gt;33[38;5;15m&lt;/span&gt;&lt;span class="se"&gt;\]&lt;/span&gt;&lt;span class="s2"&gt;] &lt;/span&gt;&lt;span class="se"&gt;\[&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;tput sgr0&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="se"&gt;\]&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;PS1&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$PS1_def&lt;/span&gt;
&lt;span class="nv"&gt;EDITOR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/usr/bin/nano
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In the end, I am happy with this setup.  I have all my $PATH and $LIBs set in my .bashrc, and all my convenience functions, prompts, etc set in my .nickstuff file that is easy to move to a new machine.&lt;/p&gt;

&lt;p&gt;I hope you found this useful!  For me, it is much easier to manage my settings this way, but I'm sure that most of you have a solution that works well for you; please share in the comments!&lt;/p&gt;

</description>
      <category>bash</category>
      <category>minimalism</category>
    </item>
    <item>
      <title>Notes on Nativescript: my first steps into mobile development</title>
      <dc:creator>Nick W</dc:creator>
      <pubDate>Wed, 19 Apr 2017 08:47:40 +0000</pubDate>
      <link>https://forem.com/nickp60/notes-on-nativescript-my-first-steps-into-mobile-development</link>
      <guid>https://forem.com/nickp60/notes-on-nativescript-my-first-steps-into-mobile-development</guid>
      <description>&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Background
&lt;/h2&gt;

&lt;p&gt;I started listening to &lt;a href="http://www.programmingthrowdown.com/2016/11/episode-60-javascript-for-mobile.html"&gt;Programming Throwdown&lt;/a&gt; a few years back, when I first started making the transition from a wet-lab scientist to a computational biologist.  I exchanged my world of pipettes, centrifuges, and petri dishes for my trusty old thinkpad, slowly learning the lingo and skills needed to succeed.  PT helped acquaint me with the many languages and ecosystems in the programming world.  Last year, they ran an episode looking at Nativescript, and I was intrigued. As I did not know Swift or Java, I had figured mobile development was not in the cards for me, but their description of Nativescipt piqued my interest.  Could I really make mobile apps just using Javascript and XML?  I decided to try.&lt;/p&gt;

&lt;h2&gt;
  
  
  First things
&lt;/h2&gt;

&lt;p&gt;That being said, I knew nothing about JS or XML.  I read &lt;a href="http://eloquentjavascript.net/Eloquent_JavaScript.pdf"&gt;Eloquent Javascript&lt;/a&gt;, and set up a minimal dev environment after reading &lt;a href="https://dev.to/corgibytes/setting-up-a-minimal-yet-useful-javascript-dev-environment"&gt;Kamil's post&lt;/a&gt;, and slowly started building up the logic behind the app I hand in mind (essentially, a replacement to a years-old spreadsheet of lab calculations). I started to enjoy programming in JS; there are plenty of times I got caught by weird type conversions, but overall, it was similar enough to languages I already new (Python, R, C) to not be too tricky.  The amount of support available online is fantastic. &lt;/p&gt;

&lt;p&gt;What follows is simply a few reflections on my experience, and what I would recommend for anyone looking to get started.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;NOTE&lt;/em&gt;: I am in no way an expert; I simply want to share my experience working with  Nativescript as a non-expert, JS-novice, mobile-ignorant layman.&lt;/p&gt;

&lt;h1&gt;
  
  
  Nativescript Lessons
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Lesson #1: Avoid the paradox of choice
&lt;/h2&gt;

&lt;p&gt;Nativescript  has some of the best documentation of any framework I have used.  It has clearly worked minimal examples, and walks you through a increasingly complex grocery list app to get the hang of things. All was going well, so to jump in, I cloned a &lt;a href="https://github.com/gethuman/nativescript-sidedrawer/tree/master/demo"&gt;demo app&lt;/a&gt; that used the drawer navigation system I had in mind.&lt;/p&gt;

&lt;p&gt;And that is where I noticed something funny. This demo app was written in Typescript! Not a problem, I though, I will just javascript-ify it and move on.  But, that was the first of many such "huh?" moments.&lt;/p&gt;

&lt;p&gt;One of the beauties of Nativescript is its flexibility. You can write in TypeScript or JavaScript.  You can structure the project may different ways. It is endlessly extensible with plugin and modules. However, that can make finding template examples tricky to work with.  Often, if you try to implement a minimal example from an interesting plugin, you may well find that it requires a lot of reworking to get working. So, before starting, look at as many high-quality example repos as you can: find the one that makes the most sense to you, and dive in.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lesson #2: Multiple ways to skin a cat
&lt;/h2&gt;

&lt;p&gt;Similar to the last lesson, Nativescript itself is very flexible. When I first got started, it seemed straightforward enough: js for the logic, xml for the structure, and css for the style.  How hard can it be?&lt;/p&gt;

&lt;p&gt;What I learned after a while working on my app was that that understanding is a simplified version of reality.  If you want (and you probably will, once you see how it can help), you can set the style in the xml sheet, and set the structure of the page in js.  Why would you want to do that?  Simply, it allows you to bind application logic to the layout of pages, so that you can dynamically change the UI based on certain things.  This is an incredible useful feature, but (I felt) poorly explained in the literature.&lt;/p&gt;

&lt;p&gt;This led to lots of "huh?" moments looking at examples.  The Nativescript docs do have examples of the different ways of doing things, but the way the tutorials go, it is not immediately apparent.  Look at the example below for making a grid-layout  from the docs, for instance.&lt;/p&gt;

&lt;p&gt;The xml:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;GridLayout&lt;/span&gt; &lt;span class="na"&gt;columns=&lt;/span&gt;&lt;span class="s"&gt;"80, *, auto"&lt;/span&gt; &lt;span class="na"&gt;rows=&lt;/span&gt;&lt;span class="s"&gt;"auto, *"&lt;/span&gt; &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
 &lt;span class="nt"&gt;&amp;lt;Button&lt;/span&gt; &lt;span class="na"&gt;col=&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
 &lt;span class="nt"&gt;&amp;lt;Button&lt;/span&gt; &lt;span class="na"&gt;col=&lt;/span&gt;&lt;span class="s"&gt;"1"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
 &lt;span class="nt"&gt;&amp;lt;Button&lt;/span&gt; &lt;span class="na"&gt;col=&lt;/span&gt;&lt;span class="s"&gt;"2"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
 // by default column and row are set to 0
 &lt;span class="nt"&gt;&amp;lt;Button&lt;/span&gt; &lt;span class="na"&gt;row=&lt;/span&gt;&lt;span class="s"&gt;"1"&lt;/span&gt; &lt;span class="na"&gt;colSpan=&lt;/span&gt;&lt;span class="s"&gt;"3"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/GridLayout&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or, the js:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//var layout = require("ui/layouts/grid-layout");&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;gridLayout&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;GridLayout&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;btn1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;btn2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;btn3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;btn4&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;gridLayout&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;btn1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;gridLayout&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;btn2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;gridLayout&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;btn3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;gridLayout&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;btn4&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;GridLayout&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setColumn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;btn1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;GridLayout&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setColumn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;btn2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;GridLayout&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setColumn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;btn3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;GridLayout&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setColumnSpan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;btn4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


&lt;span class="c1"&gt;// ItemSpec modes of the column refers to its width.&lt;/span&gt;
&lt;span class="c1"&gt;// Absolute size of the column&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;firstColumn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;ItemSpec&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;GridUnitType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pixel&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// Star width means that this column will expand to fill the gap left from other columns&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;secondColumn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;ItemSpec&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;GridUnitType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;star&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// Auto size means that column will expand or shrink in order to give enough place for all child UI elements.&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;thirdColumn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;ItemSpec&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;GridUnitType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Star and Auto modes for rows behave like corresponding setting for columns but refer to row height.&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;firstRow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;ItemSpec&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;GridUnitType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;secondRow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;ItemSpec&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;GridUnitType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;star&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;gridLayout&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addColumn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;firstColumn&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;gridLayout&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addColumn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;secondColumn&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;gridLayout&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addColumn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;thirdColumn&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;gridLayout&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addRow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;firstRow&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;gridLayout&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addRow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;secondRow&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Its a bit hard to see whats going in in the js example. The xml is pretty clear: define a grid with some rows and columns, and place 4 buttons there.&lt;/p&gt;

&lt;p&gt;The js does the exact same thing, but from the js file instead of the xml. &lt;/p&gt;

&lt;p&gt;That is cool, but it is hard to see immediately what is going on.  I found that when I was trying to reuse code examples, a lot of time ended up being spent figuring out whats  going on.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lesson #3: Choose a binding scheme and stick with it.
&lt;/h2&gt;

&lt;p&gt;I didn't come from a web background, so I wasn't familiar with DOM issues that Nativescript attempts to get around.  I found the binding schemes available in Nativescript very confusing. Again, the &lt;a href="https://docs.nativescript.org/core-concepts/data-binding"&gt;docs&lt;/a&gt; are good, but it took some serious tinkering to understand what was going on with static, one-way, two-way, parents, children, inheritance, etc.  What further complicated things is the way different people handle it.  &lt;/p&gt;

&lt;p&gt;I followed the scheme set up by the groceries app for version 0.1 of my app.  But as things got more complex, I came across &lt;a href="https://github.com/rbonillajr/nativescript-style-guide"&gt;this guide&lt;/a&gt; that re-defined how I looked at the binding model.  The one laid out in that guide made more sense to me (I needed events to update in real time without waiting for a "submit" event), so I ended up re-writing a lot of the previous logic to reflect the new model for the next version.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusions
&lt;/h1&gt;

&lt;p&gt;All this to say, read lots and look around at different ways of using Nativescript before getting started.  I started off with very little idea of what I was doing, and ended up spending a lot of time reworking things as my understanding of the framework was updated. That being said, it is a great framework, and I look forward to using it more in the future for other projects! &lt;/p&gt;

</description>
      <category>nativescript</category>
      <category>mobile</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
