NativeScript button event not firing

I spent a bit of time trying to understand why a tap event failed to fire on a button in NativeScript. Here was the original code segments:

Button Code

view plain print about
1<Button text="Pay Debt" tap="payDebtAction" visibility="{{ debt===0 ? 'collapse', 'visible'}}" />

Tap Event Handler Function

view plain print about
1exports.payDebtAction = function(args){
2 var page = args.object;
3 console.log("paydebt");
4}

The intent of this code was to hide the Pay Debt button if there was no debt. In exports.payDebtAction(), there was a call to the view-model to reduce the debt by the appropriate amount. When I ran the code, I did not get any output in the console. Thus, the code to reduce the debt never ran and the button never disappeared from the view.

Using the Throw-Stuff-At-The-Wall method, I eventually removed the visibility attribute from the Button declaration, and handled hiding the button in the code behind file like this:

view plain print about
1<Button text="Pay Debt" tap="payDebtAction" id="payDebtButton" />

Tap Event Handler Function

view plain print about
1exports.payDebtAction = function(args){
2 var page = args.object;
3 console.log("paydebt");
4 GameViewModel.payDebt();
5 var debt = GameViewModel.get("debt");
6 if( debt < 1){
7 View.getViewById(page, "payDebtButton").visibility='collapse';
8 }
9};

Notice the id attribute on the button. I use that ID to get a reference to the control, then set the visibility property in javascript, not in the view XML. This code works as expected.

I'm not 100% sure what I learned, but perhaps if there is a way to sum it up, is to not try to do so much in the XML layer. The JS layer is a lot more powerful anyways.

Updating from NativeScript 1.4 to NativeScript 1.5

I ran into an issue updating NativeScript 1.4 to NativeScript 1.5. The symptom:

view plain print about
1> nativescript@1.5.0 postinstall C:\Users\DanWilson\AppData\Roaming\npm\node_modules\nativescript
2> node postinstall.js

Basically, after uninstalling and reinstalling NativeScript on Windows 7 (maybe other OS's are affected also), the process would hang at the node postinstall.js. By hang, I mean it was stuck at the above status for 15 minutes. I looked at the source for postinstall.js and nothing specifically stood out to me as potentially the problem. Hat tip to Jen Looper for the suggestion to upgrade Node.js. Upgrading to the latest 4.x fixed the issue for me.

Why were you running an out of date Node.js DAN?

The NativeScript Getting Started Documentation stipulated Node .12 at the time. Since NativeScript has been released, they have updated the documentation to now include Node 4.x.

It is possible a fresh install might work on .12 or an older version of Node, however once I updated to the latest Node Binaries, the install for NativeScript 1.5 finished promptly. If you have issues upgrading to NativeScript 1.5, freshen up your Node.js version and that should take care of it.

Application Upgrade

Another thing I noticed, was a difference in the values in the root package.json for the value "tns-core-modules" was 1.4.0. I manually changed that value to 1.5.0 and the application built and deployed successfully. I'm not sure if you HAVE to do that, but I did it and saw no ill effect.

Before manually changing tns-core-modules

Before I manually changed the value of tns-core-modules, I ran npm install to ensure my dependencies were set correctly. Here is what happened:

view plain print about
1C:\_web\NativeScript\TradeOMatic>npm install
2npm WARN package.json @ No description
3npm WARN package.json @ No repository field.
4npm WARN package.json @ No README data
5npm WARN package.json @ No license field.

After manually changing tns-core-modules

view plain print about
1C:\_web\NativeScript\TradeOMatic>npm install
2npm WARN package.json @ No description
3npm WARN package.json @ No repository field.
4npm WARN package.json @ No README data
5npm WARN package.json @ No license field.
6tns-core-modules@1.5.0 node_modules\tns-core-modules

As you can see from the final line, the tns-core-modules for my specific project were updated to the 1.5.0 version.

The best way to develop and run NativeScript projects in an emulator

I develop NativeScript on Windows. As in most new, shiny technology, developing on Windows has it's quirks. In this post, we'll talk about 3 different ways to run your NativeScript project in an emulator, as well as the pros and cons of each method. I'm also going to use the Android platform. The iOS commands are the same, except for swapping iOS for the keyword android in the command.

All methods assume you have an emulator for your platform, with a device profile created. Additionally, at least on Android, it is necessary to start the device emulator you wish to target using the Android Virtual Device Manager, or some other mechanism.

Basic: tns run android --emulator

Run this command every time you want to push the latest version of your code to the emulator.

Pros:

  • You get to see any console output. This means you can debug your application using console.log("foo") statements and see the output.
  • You will stay up to date on your facebook feeds. See Cons below for explanation.

Cons:

  • The console logs are VERY chatty. There are heaps of measurement logging and other things not immediately relevant to the application. The sheer amount of logs, can make it hard to find your output.
  • You'll pay a 2 minute tax, at least, waiting on the emulator to get your changes. Change a single character and use this method again? Then you'll pay the 2 minute tax again. (I'm using an SSD laptop with 16GB of RAM.)
  • Because of the latency between updates, I am painfully reminded of my poor typing skills.
  • If this was the only option to write Native mobile applications, I'd probably decide it wasn't for me and go do something else.

Tip:

At this stage, I can not see a single positive reason to use tns run android --emulator that can't be achieved with one of the below options. In short, you probably don't want to use the workflow tns run android --emulator. As a stretch, perhaps you need to see the Native logs, like all of the measurement logging. Right now I don't need that, so this method is pointless and masochistic.

Interactive: tns livesync android --emulator --watch

This process watches for source code changes and will automatically build and push the latest version of your code to the emulator.

Pros:

  • The time between making a source code change, and seeing the effect of the change in the emulator, is WAY faster than tns run android --emulator. This is somewhat comparable to running a browser based application.
  • I prefer this method when I'm working on layouts, visual changes, or light work inside view-models.
  • Did I mention how fast changes are propagated?
  • If there is an error, you will get a stack trace on your emulator screen.
  • As of NativeScript 1.5, you will see console.log() outputs in your terminal window. YAY!

Cons:

  • You get NO console output. All console.log() statements are /dev/null'd.This is no longer true as of {N} 1.5. Console.log() output is streamed to the terminal, without the chattiness of the above method.

Tip:

If you want more options with how to deal with non-visual logging in NativeScript, write a custom TraceWriter and push the output you want into a frame of your application, or send it over an API or whatever. You can find out more here: tracing-nativescript-applications. Just search for Writing a Custom TraceWriter for an example of your options.

Genymotion: tns debug android --geny "Google Nexus 4 - 5.1.0 - API 22 - 768x1280" --debug-brk

This process watches for source code changes and will automatically build and push the latest version of your code to the emulator and start a debugging session in Google Chrome.

Pros:

  • Changes are propagated quickly, much like tns livesync android --emulator --watch
  • You have introspection, breakpoint and other tools using Google Developer Tools.
  • From my informal testing, the time to complete the initial build and show the app on the screen is less with Genymotion, than it is with the tns livesync android --emulator --watch process.

Cons:

  • This requires a separate account with Genymotion. There is a free personal account and several paid options.
  • No matter what I do, this doesn't work on my platform. It's the albino tiger of debugging. If you can see it working, then you have something special. However, Genymotion never comes out of the cave to perform for me.

Which one should you use?

Once your environment is successfully set up, spend some time to get Genymotion installed. If you can get it working on your system, then you have the Holy Grail of NativeScript debugging. Fast change propagation, interactive debugging, variable inspection and so on. If this does not work for you, then you are probably best served using tns livesync android --emulator --watch. Now that console.log() statements are sent into the terminal, you can debug iteratively, though without the breakpoints and introspection you'd get in a Google Chrome debug session.

Appendix: why doesn't Genymotion work on your platform?

If I knew the answer to that, I wouldn't have been inspired to write this article. I'd just use Genymotion and be happy.

On my system, I can start the Genymotion emulator, connect with a debugging session in Google Chrome and see my application successfully deployed. What does not work is the debugging session. I get the following error in my javascript console:

view plain print about
1Page.getResourceTree failed.
2ReferenceError: process is not defined

While googling for a resolution, I can see others report a similar issue, however no combination of repudiation steps makes this error go away. Thus, the debugging session is not enabled and I get none of the benefits of using Genymotion.

It is a shame, but I make do with the combination of tns run android --emulator and tns livesync android --emulator --watch as needed.

TNS Build Android Hangs

Occasionally, while running a NativeScript application on android, the process hangs and does not complete. I have not gotten to the bottom of this, but I can tell you how I resolve the issue to continue running my application.

Symptoms - one of these

view plain print about
1C:\_web\NativeScript\TradeOMatic>tns livesync android --emulator --watch
2Project successfully prepared
3The application with id "org.nativescript.TradeOMatic" is not installed on the device yet.
4Project successfully prepared
view plain print about
1C:\_web\NativeScript\TradeOMatic>tns build android
2Project successfully prepared

In the above cases, the behavior is the terminal is stuck at the Project successfully prepared status and does nothing. I can watch which binaries are in control of the process, and on Windows, it gets stuck on find.exe.

If the tns livesync android --emulator --watch command hangs, I usually just run tns build android. Usually, this kicks off the build process. If it doesn't, I'll run tns build android again. This almost always works.

If, for some reason, no combination of the commands executed the build process. I remove the Android specific platform processes, then added them again. Example:

view plain print about
1C:\_web\NativeScript\TradeOMatic>tns platform remove android
2 C:\_web\NativeScript\TradeOMatic>tns platform add android

When the build process runs, you will see a lot of console output. Example:

view plain print about
1Project successfully prepared
2execute: copyAarDependencies, addAarDependencies before configuration
3:preBuild UP-TO-DATE
4:preDebugBuild UP-TO-DATE
5:checkDebugManifest
6:preReleaseBuild UP-TO-DATE
7:prepareComAndroidSupportAppcompatV72311Library UP-TO-DATE
8:prepareComAndroidSupportSupportV42311Library UP-TO-DATE
9:prepareDebugDependencies
10:compileDebugAidl UP-TO-DATE
11:compileDebugRenderscript UP-TO-DATE
12:generateDebugBuildConfig UP-TO-DATE
13:deleteJavaDir UP-TO-DATE
14:cleanLocalAarFiles UP-TO-DATE
15:collectAllJars UP-TO-DATE
16:ensureMetadataOutDir UP-TO-DATE

Then the changes made to the application are ready for deployment. You can use your favorite emulator command to push the build. I prefer tns livesync android --emulator --watch because changes are picked up and deployed automatically, significantly reducing the amount of time needed to validate each change on the emulator.

How to fix a Node.js package error when installing NativeScript

NativeScript is a free open source offering from Telerik allowing mobile development in Javascript with 100% Access to Native Platform APIs in iOS, Android and Windows Phone. With NativeScript, the entire native platform functionality is available in the JavaScript layer. I've finally found the packaging and tooling I want to use to develop native applications in iOS and Android, while using a single language.

I develop in Windows and I love it for my daily work. However, occasionally, using Node.js on windows is a bit more complicated than on other platforms. While following the very comprehensive Getting started guide for NativeScript, I ran in to a sticky issue. Here is the issue and resolution in case it helps you, my weary web traveler friend.

Firstly, the root cause of the error was my fault. Even though the Getting Started Guide stated I needed to install "The latest Node.js 0.10.x or 0.12.x stable official release", I went off-script and installed Node 4.x. Surely this would work, right?

After spending a fair amount of time struggling with the CLI command to install NativeScript, I re-read the install docs and figured out my Node version was not the right version, so I uninstalled Node.js 4.x and installed Node 0.12.x.

After running the installer again, I still ran into issues. Part of the issue was the C++ compiler not being available. The standard way to get a C++ compiler is to install Visual Studio, though through research, I found Microsoft is offering a standalone C++ compiler specifically to help out with node. This comment by Sara Itani, discusses the new compiler, how it was tested and has the links to download what you need.

I applaud the new and improved Microsoft for their work to support the more modern development platforms like Node.

Once I had the compiler installed, I hit another error. This error was caused because the earlier version of Node.js 4.x left some paths out there that no longer resolved. Once I fixed the paths in the \nodejs\nodevars.bat, and ensured they pointed to the current install of Node 0.12.x, I was able to complete the install. Below is an example of the NativeScript install script output before the error.

view plain print about
1[C:\Users\DanWilson]npm i -g nativescript
2npm WARN excluding symbolic link docs\stylesheets\hightlight.css ->
../../node_m
3odules/highlight.js/src/styles/solarized_light.css
4npm WARN excluding symbolic link docs\assets\ir_black.css -> ../../node_modules/
5highlight.js/src/styles/ir_black.css
6npm WARN excluding symbolic link docs\stylesheets\hightlight.css -> ../../node_m
7odules/highlight.js/src/styles/solarized_light.css
8npm WARN engine xmlbuilder@2.2.1: wanted: {"node":"0.8.x || 0.10.x"} (current: {
9"node":"0.12.7","npm":"2.11.3"})
10|
11
12
13> utf-8-validate@1.0.1 install C:\Users\DanWilson\AppData\Roaming\npm\node_modul
14es\nativescript\node_modules\utf-8-validate
15> node ./build.js
16
17`win32-ia32-v8-3.28` exists; testing
18Binary is fine; exiting
19npm WARN excluding symbolic link examples\TestFramework\Test Framework.framework
20\Resources -> Versions/Current/Resources
21npm WARN excluding symbolic link examples\TestFramework\Test Framework.framework
22\Test Framework -> Versions/Current/Test Framework
23npm WARN excluding symbolic link examples\TestFramework\Test Framework.framework
24\Versions\Current -> A
25npm WARN excluding symbolic link docs\stylesheets\hightlight.css -> ../../node_m
26odules/highlight.js/src/styles/solarized_light.css
27
28
29> bufferutil@1.0.1 install C:\Users\DanWilson\AppData\Roaming\npm\node_modules\n
30ativescript\node_modules\bufferutil
31> node ./build.js
32
33`win32-ia32-v8-3.28` exists; testing
34Binary is fine; exiting
35
36> fibers@1.0.6 install C:\Users\DanWilson\AppData\Roaming\npm\node_modules\nativ
37escript\node_modules\fibers
38> node build.js || nodejs build.js
39
40`win32-ia32-v8-3.28` exists; testing
41Binary is fine; exiting
42-
43
44
45> ref@1.1.3 install C:\Users\DanWilson\AppData\Roaming\npm\node_modules\nativesc
46ript\node_modules\ref
47> node ./build.js
48
49`win32-ia32-v8-3.28` exists; testing
50Binary is fine; exiting
51npm WARN excluding symbolic link docs\assets\ir_black.css -> ../../node_modules/
52highlight.js/src/styles/ir_black.css
53npm WARN excluding symbolic link examples\TestFramework\Test Framework.framework
54\Resources -> Versions/Current/Resources
55npm WARN excluding symbolic link examples\TestFramework\Test Framework.framework
56\Test Framework -> Versions/Current/Test Framework
57npm WARN excluding symbolic link examples\TestFramework\Test Framework.framework
58\Versions\Current -> A
59npm WARN excluding symbolic link docs\stylesheets\hightlight.css -> ../../node_m
60odules/highlight.js/src/styles/solarized_light.css
61npm WARN excluding symbolic link docs\stylesheets\hightlight.css -> ../../node_m
62odules/highlight.js/src/styles/solarized_light.css
63-
64
65
66> ws@0.4.32 install C:\Users\DanWilson\AppData\Roaming\npm\node_modules\nativesc
67ript\node_modules\node-inspector\node_modules\ws
68> (node-gyp rebuild 2> builderror.log) || (exit 0)
69
70if not defined npm_config_node_gyp ( node "%~dp0\..\..\node_modules\node-gyp\bin
71\node-gyp.js" %* ) else ( node %npm_config_node_gyp% %* )
72\
73
74
75> ffi@2.0.0 install C:\Users\DanWilson\AppData\Roaming\npm\node_modules\nativesc
76ript\node_modules\ffi
77> node ./build.js
78
79`win32-ia32-v8-3.28` exists; testing
80Binary is fine; exiting
81npm ERR! Windows_NT 6.1.7601
82npm ERR! argv "C:\\Program Files (x86)\\nodejs\\\\node.exe" "C:\\Program Files (
83x86)\\nodejs\\node_modules\\npm\\bin\\npm-cli.js" "i" "-g" "nativescript"
84npm ERR! node v0.12.7
85npm ERR! npm v2.11.3
86npm ERR! code ELIFECYCLE
87
88npm ERR! ws@0.4.32 install: `(node-gyp rebuild 2> builderror.log) || (exit 0)`
89npm ERR! Exit status 1
90npm ERR!
91npm ERR! Failed at the ws@0.4.32 install script '(node-gyp rebuild 2> builderror
92.log) || (exit 0)'.
93npm ERR! This is most likely a problem with the ws package,
94npm ERR! not with npm itself.
95npm ERR! Tell the author that this fails on your system:
96npm ERR! (node-gyp rebuild 2> builderror.log) || (exit 0)
97npm ERR! You can get their info via:
98npm ERR! npm owner ls ws
99npm ERR! There is likely additional logging output above.
100
101> nativescript@1.4.3 preuninstall C:\Users\DanWilson\AppData\Roaming\npm\node_mo
102dules\nativescript
103> node preuninstall.js
104
105Trying to kill adb server. Some running Android related operations may fail.
106
107npm ERR! Please include the following file with any support request:
108npm ERR! C:\Users\DanWilson\npm-debug.log

What I found annoying about this error, and the reason why I'm posting it here, is because the error points to a failure in the ws package.

view plain print about
1npm ERR! ws@0.4.32 install: `(node-gyp rebuild 2> builderror.log) || (exit 0)`
2npm ERR! Exit status 1
3npm ERR!
4npm ERR! Failed at the ws@0.4.32 install script '(node-gyp rebuild 2> builderror
5.log) || (exit 0)'.
6npm ERR! This is most likely a problem with the ws package,
7npm ERR! not with npm itself.
8npm ERR! Tell the author that this fails on your system:
9npm ERR! (node-gyp rebuild 2> builderror.log) || (exit 0)
10npm ERR! You can get their info via:
11npm ERR! npm owner ls ws
12npm ERR! There is likely additional logging output above.

However, I could install the WS package separately with no issue.

Good luck and happy developing with NativeScript!

Getting USB Device Drivers Working for HTC Android Development

I set up a new Eclipse environment today and wanted to use my HTC Thunderbolt for testing. Usually, the way this works is you right click on your project then select your manual run target of your phone. My HTC Thunderbolt was not recognized for some reason.

After digging around for a bit, I found the USB device driver provided by Google does not support some HTC phones out of the box. I have no idea why. However, fixing it is pretty simple.

All you have to do is update the device driver .inf file. It's pretty simple to do this. Here is what you do:

  1. Follow the steps here: http://developer.android.com/guide/developing/device.html to start the process (if you found this blog article, you have likely done this step already)
  2. If you are on Windows, you'll have to get the Microsoft specific USB driver at the Google Windows USB Driver link.
  3. Once you install the Google Windows USB Driver and follow the instructions on that page for your specific OS, your device will not be recognized.
  4. Use the Device Manager to find your phone. Right Click and choose properties, then choose the Details Tab. On the Details Tab, Change the Property selector to Hardware Ids. Write down the (4?) digits in the VID_1234 (where 1234 is likely different for you) and for PID_1234 (where once again 1234 is likely different for you) You will need them later. If this is confusing, check the screenshot at the bottom of this page.
  5. Use a text editor to open [Android SDK Root]\android-sdk\extras\google\usb_driver\android_winusb.inf
  6. Find the section [Google.NTx86] and copy the lines for the HTC Dream. Paste them and change the dream to your HTC phone model.
  7. Then, update the driver specific lines with the VID_1234 number and PID_1234 number you copied above. Mine looks like this:
    view plain print about
    1; HTC Thunderbolt
    2%SingleAdbInterface% = USB_Install, USB\VID_0BB4&PID_0CA4
    3%CompositeAdbInterface% = USB_Install, USB\VID_0BB4&PID_0CA4&MI_01
    4%SingleBootLoaderInterface% = USB_Install, USB\VID_0BB4&PID_0CA4
  8. Copy and paste this code for the [Google.NTamd64] section also.
  9. When finished, try the driver update once again and you should have better luck this time.

This should improve the situation. Hat tip to Kostya Vasilyev on the Android Developers mailing list for the idea.