Start with Ionic

Ionic is a open source framework which is used to build Android and IOS apps  with “HTML 5, CSS & JavaScript”. Ionic helps you to write applications which can be used either in Android/IOS. Ionic along with “Apache cordova” provides support to build hybrid apps. Ionic is completely built based on “AngularJs”. So If you know angular, you know Ionic

How to start ?

1. Install Nodejs (node pakage manager) & GitHub (source control)
2. Install Java, Android sdk & apache-ant & configure your environmental variables

%PATH%;%JAVA_HOME%\bin;C:\Users\nandu\AppData\Roaming\npm;C:\apache-ant-1.9.6\bin;C:\Users\nandu\AppData\Local\Android\sdk;C:\Users\nandu\AppData\Local\Android\sdk\build-tools\23.0.1

3. Install Cordova, unorm, cordova-common, cordova-registry-mapper

npm install -g cordova
npm install -g unorm
npm install -g cordova-common
npm install -g cordova-registry-mapper

4. Install ionic

npm install -g ionic

5. Create new project on desktop

ionic start <<project-name>> blank

6. Add platform you app wants to run on like Android or OS. I’m showing Android here

ionic platform add android

7. Build and emulate your project. I’m considering only Android. In order “emulate” command to you need to install android sdk in our system.

ionic build android
ionic emulate android

8. Android emulate is very slow and will consume lot of time. So install “Genymotion” . It provides an actual android device, as if you connected one through usb. In order to use the device created in Genymotion, start the device and run the below command from application page

ionic run android

9. Ionic creates a whole project for you with the structure of real-time application. “www” is the folder where you need to write everything regarding your application like css, js, html etc…

10. In order to deploy application into virtual machine, start the device from Genymotion and run “ionic run android”. If you want to test the changes in browser run “ionic serve”. This will open your application on browser.
12. Once your application is ready run following commands from project folder to create and sign apk.

cordova build –release android

keytool -genkey -v -keystore my-release-key.keystore -alias alias_name -keyalg RSA -keysize 2048 -validity 10000

jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore my-release-key.keystore platforms/android/build/outputs/apk/android-release-unsigned.apk alias_name

zipalign -v 4 android-release-unsigned.apk <<app-name>>.apk

Oh!!! you are ready to go ?? Go and install the application in your android device and test it

I have came up with this steps after referring to Ionic website. Refer to Ionic website for detailed information.

AngularJs Tip: Don’t use $watch on $scope

Try to use “ng-change” instead of “$watch” when you want to watch a particular value. There are couple of benefits like performance improvement because of no overhead on digest cycle & writing test cases for ng-change is very easy compared to writing them on $watch.

AngularJs: Understanding loading Modules – II

This is my last post in the series to understand workflow for loading modules into Angular, Dependency Injection. Here is the workflow diagram created by me. This is as per my understanding of the concepts. Feel free to correct me if I’m wrong.angular_module_overview1

AngularJs: Understanding Loading modules

Banging my head for 2 days gave me some insight into how AngularJs loads modules. In the previous posts I have been talking about $injector, $provider, DI, createInjector bla bla bla.. All the information I have shared researching online material gave me bits and pieces of information but not a complete picture. Then I have decided to go through source code, with the knowledge gained from previous research I was able to understand how it’s achieved.

This post is going to be a bit longer. concepts like $injector, $provider, DI are touched in this post, which are covered in detail in my previous posts.

*Click on images to open in new tab for reading explanation for the code.

So let’s begin the show 🙂

When we write a simple angular program –  There are lot many questions that might be araising in our head

  1. When was core ng-module loaded
  2. How AngularJs was able to fetch my dependencies like $location, $window, $scope etc.. by just passing string into array or function
  3. How our module dependencies are loaded

and lot more.. By End of this post you will get answers to most of your questions.

First of all angular.js is a self invoking function which takes two parameters window & document. When we include this script file in html all the code is executed once and variables are set if any. This will help AngularJs to publish it’s internal methods which can be accessed via keyword angular.

Example: angular.extend, angular.bootstrap, angular.injector, angular.toLowerCase etc..

angular is added as property to window object whose value is empty object.

angular = window.angular || (window.angular = {})

Since angular is a self invoking function, at the end of script file there are three methods called

  1. bindJQuery()
  2. publishExternalAPI(angular) – makes available list of commonly used methods globally.
  3. angularInit(document, bootstrap) – This will bootstrap module provided on document via ngApp or using angular.injector().

Before looking into publishExternalAPI and angularInit, let’s have look at setupModuleLoader function

This is called within publishExternalAPI and bootstrap to create moduleInstance, like what needs to be returned when module is created and called. I have placed my comments directly in the source code for better understanding. Refer image below for more details on setupModuleLoader

SetupModuleLoad

In short, setupModuleLoader will add  module to angular.module.modules object with moduleInstance contaning controller, filter, provider, factory, value, constant, config run, _invokeQueues and _runBlocks these 2 queues get filled when invoke function is called on any of the above functions are called on module, refer image for better understanding.

publishExternalAPI: This is the most interesting and one of the core modules that drives AngularJs. I’m explaining all the important points right beside code for easier understanding. Enlarge picture for more informationPublish External API

Till now publishing methods on angular to external world is done and there are two modules added to angular.module.modules section

  1. ngLocale
  2. ng – This module has configFn where all the setup related to inbuild services & directives is there.

angularInit(document, bootstrap): angularInit is the place where bootstrapping is done, This is where module loading and Dependency Injection starts. After some initial startup angularInit finally calls bootstrap function on the element.

Bootstrap: After some initial setup bootstrap calls doBootStrap function which finally returns our eagerly waiting $injector on successful loading of modules. Enlarge picture for more details on what doBootstrap does. Do Bootstrap

Bootstrap calls createInjector method with list of modules that needs to be loaded. This includes ng module as well, what does createInjector method with the array of modules given to it ?

createInjector – This is where actually modules are loaded, before loading modules there is another setup createInjector does for us. It creates 2 cache objects for us

  1. providerCache – contains 2 objects
    • $provider – with six methods on it provider, value, constant, service, factory and decorator.
    • $injector
  2. instanceCache – contains $injector method on it and this injector will be returned by createInjector method.

Let’s see what exactly code does in createInjector.Create InjectorI’m not going to discuss in detail about what createInternalInjector does . I have already covered that in detail in my previous post. In short createInternalInjector returns a object which contains five methods on it

  1. invoke – invokes original method by calling javascript’s apply on it
  2. instantiate – creates new service object.
  3. getService – fetches the service from cache
  4. annotate – process the input function and returns array of dependencies that need to be injected
  5. has – checks whether the service present or not in cache.

so only part left is loadModules, let’s explore it. click on image to open in new tab to read comments beside code for more information.

loadModules

This is how modules are loaded into AngularJs Application. This is a very big post and might be confusing as well because of not using proper english. Share your questions via comments and I would be happy to help

 

AngularJs Tip: bootstrap !!

  1. Using ngApp will auto bootstrap your application.
  2. Only one AngularJs application can be auto-bootstraped for one html document. To run multiple applications in an html document we must manually bootstrap them using angular.bootstrap
  3. AngularJs applications cannot be nested within each other.

Javascript Tip: How to find whether object is window object or not

For the object to be window object. It should pass the below condition

obj && obj.document && obj.location && obj.alert && obj.setInterval

AngularJs: Loading modules

Loading modules is the most important step. Let’s see how it’s done !!

function loadModules(modulesToLoad){
    var runBlocks = [], moduleFn, invokeQueue, i, ii;
    forEach(modulesToLoad, function(module) {
      if (loadedModules.get(module)) return;
      loadedModules.put(module, true);

      try {
        if (isString(module)) {
          moduleFn = angularModule(module);
          runBlocks = runBlocks.concat(loadModules(moduleFn.requires)).concat(moduleFn._runBlocks);

          for(invokeQueue = moduleFn._invokeQueue, i = 0, ii = invokeQueue.length; i &amp;lt; ii; i++) {
            var invokeArgs = invokeQueue[i],
                provider = providerInjector.get(invokeArgs[0]);

            provider[invokeArgs[1]].apply(provider, invokeArgs[2]);
          }
        } else if (isFunction(module)) {
            runBlocks.push(providerInjector.invoke(module));
        } else if (isArray(module)) {
            runBlocks.push(providerInjector.invoke(module));
        } else {
          assertArgFn(module, 'module');
        }
      } catch (e) {
        if (isArray(module)) {
          module = module[module.length - 1];
        }
        if (e.message &amp;amp;&amp;amp; e.stack &amp;amp;&amp;amp; e.stack.indexOf(e.message) == -1) {
          // Safari &amp;amp; FF's stack traces don't contain error.message content
          // unlike those of Chrome and IE
          // So if stack doesn't contain message, we create a new string that contains both.
          // Since error.stack is read-only in Safari, I'm overriding e and not e.stack here.
          /* jshint -W022 */
          e = e.message + '\n' + e.stack;
        }
        throw $injectorMinErr('modulerr', "Failed to instantiate module {0} due to:\n{1}",
                  module, e.stack || e.message || e);
      }
    });
    return runBlocks;
  }

runBlocks and invokeQueues are two important aspects in module loading.

A module in angular is setup as follows:

angular.module(‘myModule’, [dependency]);

First we retrieve the module object using the angularModule function. When the module is setup two arrays are populated runBlocks and invokeQueues.

runBlocks

This is an array that contains list of run blocks angular.module(‘test’, []).run which needs to be run immediately after modules loaded.

invokeQueue

These are populated with each service that is added to the module using the familiar angular.module('myModule').controller, angular.module('myModule').directive

Each item in the queue is an array with three elements. The first is the provider that will invoke the service, the second is the method on the provider to use and the third element is an array of any arguments passed to the service.

Let’s see example:

angular.module('test', [])
		.controller('testController', function($scope) {
			console.log('setting up controller');
		});

When controller is setup like this invokeQueue for this controller looks like [‘$controllerProvider’, ‘register’, [‘test’, function($scope) {…}]] 

$controllerProvider – built-in Angular provider that enables registering controllers.

register – This will add service to the list of available controllers. Note that nothing gets added to the injectors cache. This means controllers cannot be injected into a service. If you really needed to get access to a controller (you do when unit testing) you would inject the $controller provider and retreive the controller by calling get(controllerName).