Introduction

Background

I started listening to Programming Throwdown 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.

First things

That being said, I knew nothing about JS or XML. I read Eloquent Javascript, and set up a minimal dev environment after reading Kamil’s post, 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.

What follows is simply a few reflections on my experience, and what I would recommend for anyone looking to get started.

NOTE: 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.

Nativescript Lessons

Lesson #1: Avoid the paradox of choice

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 demo app that used the drawer navigation system I had in mind.

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.

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.

Lesson #2: Multiple ways to skin a cat

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?

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.

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.

The xml:

<GridLayout columns="80, *, auto" rows="auto, *" >
 <Button col="0" />
 <Button col="1" />
 <Button col="2" />
 // by default column and row are set to 0
 <Button row="1" colSpan="3" />
</GridLayout>

or, the js:

//var layout = require("ui/layouts/grid-layout");
var gridLayout = new GridLayout();

var btn1 = new Button();
var btn2 = new Button();
var btn3 = new Button();
var btn4 = new Button();
gridLayout.addChild(btn1);
gridLayout.addChild(btn2);
gridLayout.addChild(btn3);
gridLayout.addChild(btn4);

GridLayout.setColumn(btn1, 0);
GridLayout.setColumn(btn2, 1);
GridLayout.setColumn(btn3, 2);

GridLayout.setColumnSpan(btn4, 3);


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

// Star and Auto modes for rows behave like corresponding setting for columns but refer to row height.
var firstRow = new ItemSpec(1, GridUnitType.auto);
var secondRow = new ItemSpec(1, GridUnitType.star);

gridLayout.addColumn(firstColumn);
gridLayout.addColumn(secondColumn);
gridLayout.addColumn(thirdColumn);
gridLayout.addRow(firstRow);
gridLayout.addRow(secondRow);

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.

The js does the exact same thing, but from the js file instead of the xml.

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.

Lesson #3: Choose a binding scheme and stick with it.

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 docs 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.

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 this guide 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.

Conclusions

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!