PhoneGap – getting started

PhoneGap

 

Create a sample web app

Download PhoneGap, take cordova.js

Install Ripple extension to Chrome.

Test your app.

If doesn’t work – put it on a web server.

 

Zip it

Create account on https://build.phonegap.com

Create an app there

Upload zip file.

Download apk package for Android.

Install Android SDK.

Create emulator.

Put downloaded app to sd card of emulator.

Run.

 

——–

To access file system on emulator

adb shell

This will open a command prompt

 

To install app on emulator

adb install AndroidPdfViewer_1_0_0b.apk

 

JavaScript – some notes

Recently we’ve been using JS quite extensively.

Here’s a few things in JS that should be watched for (as they’re not obvious and not well known):

 

Numbers are doubles. This means they’re approximations, so don’t expect an exact result:

var d = 0.1 + 0.2; // result is 0.30000000000000004

 

Loops can have labels, which can be used to break out from those loops:

loopOne: for (var i = 0; i < 10; i++) {
        for (var j = 0; j < 10; j++) {
            if (j == 3)
                break loopOne;
            console.log(i + " " + j);
        }
    }

This will stop after printing “0 2”

 

The ‘for..in’ loop will list properties of a prototype object as well (not unexpected), if you want to test if the property was defined on this specific object – double check with hasOwnProperty() method:   

var parent = {
        name:"Bob",
        gender:"male"
    };

    var child = function () {
        this.age = 20;
    };

    child.prototype = parent;
    var ch = new child();
    for (p in ch) {
        console.log(p + ", is own property: " + ch.hasOwnProperty(p));
    }

will print

age, is own property: true 
name, is own property: false 
gender, is own property: false

 

Setting a parent to null or undefined will have no effect on child, but changing its properties value will:

parent.name = "Bill";
delete parent.gender;
for (p in ch) {
    console.log(p + ", is own property: " + ch.hasOwnProperty(p) + ", value: " +  ch[p]);
}
will print 
age, is own property: true, value: 20 
name, is own property: false, value: Bill

 

  Blocks don’t have their own scope. Variables defined in blocks will be accessible outside:

for (var i = 0; i < 2; i++) {
        var boo = 33;
}
console.log(boo);

will print 33

 

JS has constructor for its types, which generally should be avoided:

var ba = new Boolean(false);
var bb = false, bc = false;
console.log(bb === bc); // true
console.log(ba == bb); // true
console.log(ba === bb); // FALSE! 

 

Be careful when using typeof operator:

console.log(typeof {}); // object
console.log(typeof 2); // number
console.log(typeof "abc"); // string
console.log(typeof null); // OBJECT - this is wrong!
console.log(typeof []); // object - not helpful

Angular.js – methods of element

This is  a list of methods/properties defined on angular’s element. It’s not in docs (or I didn’t find it), but angular uses JQLite for it’s element.

 

length    inheritedData  prop    replaceWith  addClass 
ready    scope    text    children    removeClass 
toString    controller  val    contents    toggleClass 
eq    injector    html    append    parent 
push    removeAttr  removeData  prepend    next 
sort    hasClass    dealoc    wrap    find 
splice    css    bind    remove    clone
data    attr    unbind    after     

Angular.js: directive names should be lower-case

A quirk with directive names I ran into:

When creating new modules, then names should be camel-cased, starting with lower case, e.g. ‘myDirective’.

When making use of directive, the name HAS to be translated to snake-case, otherwise it won’t fire.

 The directive can be invoked by translating the camel case name into snake case with these special characters :-, or _. Optionally the directive can be prefixed with x-, or data- to make it HTML validator compliant. 

If you have directive like
angular.module('directives', [])
    .directive('myDirective', function () {
        // your code here
    });

and then

<span myDirective><span> // won't work
<span my-directive><span> // works

Marrying SignalR and Angular.js

Another quick post on how to use SignalR with Angular.

In short – just put SignalR js code inside the controller function, and it works, with a few catches.

 

Basic hub:

public class AdminHub : Hub
{
	public void Send(string text)
	{
	    this.Clients.receive("You have sent this -> " + text);
	}
}

HTML code:

 

<!DOCTYPE html>
<html>
<head>

    <link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
    <script src="@Url.Content("~/Scripts/jquery-1.8.0.min.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/jquery.signalR-0.5.2.min.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/angular.js")" type="text/javascript"></script>
    <script src="/signalr/hubs" type="text/javascript"></script>
</head>
<body>
    <div id="content" ng-controller="SignalController">
        <input type="text" id="txt" placeholder="enter your text here" ng-model="txt" />
        <input type="button" id="btn" value="push" ng-click="send()" /><br />
        <br />
        Received: <span>{{txt2}}</span>
    </div>

    <script type="text/javascript">
        $(function () {
            angular.bootstrap(document, []);
        });


        function SignalController($scope) {
            var adminHub = $.connection.adminHub;
            $.connection.hub.start();

            $scope.send = function () {
                adminHub.send($scope.txt.toString());
            }

            adminHub.receive = function (data) {
                $scope.$apply($scope.txt2 = "'" + data + "'");
            }
        }
    </script>
</body>
</html>

 

 

Two things to watch for:

The angular’s model is being updated from outside of angular context, so we need to call $apply function.

Hub returns a string, and when assigning the property in $scope – make sure the value is wrapped in quotes.