Real Time Angular 2 – Components vs. Controllers/$scope – Dependency Injection



Real Time Angular 2 – Components vs. Controllers/$scope – Dependency Injection

2 2


real-time-angular2

Real Time Angular 2 examples and slides using Syncano

On Github devintyler / real-time-angular2

Real Time Angular 2

Let me introduce myself, my name is Devin, I'm from the United States, and the only reason why I'm here is because I love pierogies. I want to talk about real time data sync with Angular 2 and build an example in ES5, but first I want to quickly go over some differences between Angular 1.x and Angular 2

Angular 2: Revamped and Improved

Quick general overview of the changes

If you have been keeping up with Angular 2, you know it's still in alpha stages, and still very unstable. I decided to learn how to use it with ES5 as a bit of a challenge to myself. There are very little resources available for ES5 versions of Angular 2 The problem with this was that it was hard to figure out how to set up the class, and also how to use the built-in directives.

Components vs. Controllers/$scope

CONTROLLERS AND $SCOPE ARE GONE!

Components

  • Angular 2 is following other frameworks (React, Polymer) with components
  • Components are directives with templates
  • Focus is on building component in your app's single javascript file
- directive is a marker on a DOM element that tells the compiler to attach behavior to that element

Code difference:

Angular 1.x

ng-controller="myController"

Angular 2.0

<my-component></my-component>

Dependency Injection

Dependency Injection (DI) is a software design pattern that deals with how components get hold of their dependencies. The Angular injector subsystem is in charge of creating components, resolving their dependencies, and providing them to other components as requested.

Things to Fix From Angular 1.x DI

  • Allow for easier minification of DI
  • Create lifetime/scope control
  • Allow child injectors

TypeScript vs. Javascript

I actually like TypeScript, it's not much different than JS

Typescript is basically Javascript with:

  • Classes
  • Static Types
  • Annotations
  • Decorations
  • ES6

Bootstrapping

Previously, bootstrapping was done through binding your app and controller to the template or index page.

Example Bootstrap:

document.addEventListener('DOMContentLoaded', function() {
	ng.bootstrap(Component);
});
Now, since components are being used, the bootstrapping is called in your app file with the components being used as the parameters. The important thing is that you don't bootstrap until after DOMContentLoaded.

Other Changes

  • Event Emitters
  • Models - {{modelTest}} - [(ng-model)]="modelTest"
  • Form/validation
  • (click) instead of 'ng-click'. No more 'ng-'

Zone.js

- what is zone.js? - written by Brian Ford - inspired by Dart
"In a nutshell, Zone provides what you might consider a 'thread execution' context for JavaScript."

- Jeremy Likness

- quote by Jeremy - basically, Zone.js allows you to run sync and async functions, and have wrap them all in a zone or "execution context" - I like to think of it as a step between the global context and the function context, depending on where the zone is

Why is this useful?

- while in a zone, the call stack is preserved - this means traces can follow all of the calls, and show you exactly where an error might originate - you can also use it to trace the time from true start and end of all calls

How does Zone.js apply to real time?

  • watches 'this' for changes
  • eliminates the need to '$scope.$apply()'
- Since zones watch out for changes made by all calls, it also watches out for changes to 'this' - Zone.js is the reason why you no longer need to use scope.apply, it watches your variables and triggers a digest cycle when they are changed - basically, when your data is update in real time, zone.js automatically preserves the real time aspect by also updating the UI/front-end seamlessly

For deeper explanation...

Angular 2 site: angular.io

Victor Savkin's Blog: victorsavkin.com

"Google"

What is real time web?

"...a Web that is as close to instant as you can get."

- Ars Technica

Services

  • Syncano
  • Firebase
  • Parse
There are a few services that provide real time data solutions. I chose to use Syncano's Real Time API for the example app we'll walk through later.

Real Time with Syncano

You could build a real time database with Firebase or Parse, or even build it yourself, but I chose to use Syncano for mine.

Channels

Syncano uses Channels to poll for real time updates

Channels are a way of providing realtime communication functionality in Syncano. Users can subscribe to Channels in order to get notifications about changes that happen to Data Objects connected to those Channels. - Syncano.io

Data Object Changes

  • Create
  • Update
  • Delete
  • Error

What does this look like with Angular 2?

Everything that Angular displays on the front end is being polled from Syncano on the backend in real time.

Examples of when to use real time

  • Live Chat
  • Synced List
  • Live Stats
  • Basically anything "live"

Let's Build! (ES5)

Follow along: http://bit.ly/21ygVcT

index.html

<!DOCTYPE html>
<html>

<head>
  <link rel="stylesheet" href="style.css" />
  <script src="https://code.angularjs.org/2.0.0-alpha.44/angular2.sfx.dev.js"></script>
  <script src="syncano.min.js"></script>
  <script src="app.js"></script>
</head>

<body>
  <h1>Realtime Item List</h1>
  <cmp></cmp>
</body>

</html>

app.js - Component

var Cmp = ng.
  Component({
    selector: 'cmp',
    template:
      '<ul style="width:15em">' +
      '<li *ng-for="#item of list" id="{{item.id}}">' +
      '{{ item.name }} <button (click)="removeItem(item)" style="float:right;">X</button>' +
      '</li>' +
      '</ul>' +
      '<input id="textEntry" #textbox (keyup)="doneTyping($event)">' +
      '<button id="submitButton" (click)="addItem(textbox.value)">Add Item</button>',
    directives: [ng.NgModel, ng.FORM_DIRECTIVES, ng.NgFor]
  })
- selector: selects DOM element to inject component - template: HTML template - *ng-for different - #name is identifier for DOM element - directives: standard Angular 2 directives

app.js - Class

.Class({
  constructor: [function Cmp() {
	var self = this; // ES5
	this.list = []; // list of items
	...
  }]
});

app.js - Bootstrap

document.addEventListener('DOMContentLoaded', function() {
  ng.bootstrap(Cmp);
});

Syncano Setup

Syncano Variables

// Syncano variables
var sync = new Syncano({accountKey:myAccountKey}); // for creating obj
var instance = new Syncano({apiKey:myApiKey, instance:myInstance}); // for real time
var realtime = instance.channel(myChannel).watch(); // real time instance variable

Generate Initial List

// Initial List from Syncano
sync.instance(myInstance).class(myClass).dataobject().list()
  .then(function(res){
    for(i=0;i<res.objects.length;i++){
      self.list.push({ // push to array
        name: res.objects[i].name,
        id: res.objects[i].id
      });
    }
  })
  .catch(function(err){
    console.log(err);
  });

Real Time Event Listeners

// Realtime Event Listeners - (scroll down)
realtime.on('create', function(data) {
  self.list.push({ // push new item to array with Syncano data
    name: data.name,
    id: data.id
  });
});

realtime.on('delete', function(data) {
  for(var i = self.list.length - 1; i >= 0; i--) {
    if(self.list[i].id === data.id) {
      self.list.splice(i, 1); // remove from array
    }
  }
});

realtime.on('error', function(data) {
  console.log(data);
});

Class Functions

Add Item

this.addItem = function(item) { // add item to Syncano
  var newItem = {
    "name":item,
    "channel":"itemlist"
  };
  sync.instance(myInstance).class(myClass).dataobject().add(newItem)
    .then(function(res){
      console.log(res);
    })
    .catch(function(err){
      console.log(err);
    })
};

Remove Item

this.removeItem = function(item){ // remove item from Syncano
  sync.instance(myInstance).class(myClass).dataobject(item.id).delete()
    .then(function(res){
      console.log("Item: [" + item.name + "] was deleted");
    })
    .catch(function(err){
      console.log(err);
    });
};

When User is Done Typing..

this.doneTyping = function($event) { // watches for keys when done typing
  if($event.which === 13) { // 'enter' key
    this.addItem($event.target.value);
    $event.target.value = null;
  }
};

Live Example

http://bit.ly/1LRcsWX

Conclusion

We're in a world of real time web. As Angular moves towards using execution contexts to provide our apps with real time capabilities (even though some calls are asynchronous), we should focus on building our apps and web services for this real time web.

There are many data solutions out there, whether you build your own, or use one like Syncano provides that's up to you. I'm just excited that Angular is now providing us with a simple way to keep our back-end in sync in real time with our front-end, and we didn't have to touch the scope to do it.

Sources

http://eisenbergeffect.bluespire.com/all-about-angular-2-0/ http://davidshariff.com/blog/what-is-the-execution-context-in-javascript/ https://www.youtube.com/watch?v=3IqtmUscE_U https://gist.github.com/gdi2290/634101fec1671ee12b3e https://medium.com/@BuildMySite1/what-is-typescript-pros-and-cons-8dc5cdc3e78d#.xhivx0sdq http://www.infoworld.com/article/3010853/application-development/up-close-with-googles-angular-2-javascript-framework.html http://blog.thoughtram.io/angular/2015/07/06/even-better-es5-code-for-angular-2.html

Thanks!

Devin Visslailli - @devinviss

Developer Evangelist for Syncano

Live Slides: http://bit.ly/1OzGZ23

Github Slide Repo: http://bit.ly/1SzcRmp

Real Time Angular 2 Let me introduce myself, my name is Devin, I'm from the United States, and the only reason why I'm here is because I love pierogies. I want to talk about real time data sync with Angular 2 and build an example in ES5, but first I want to quickly go over some differences between Angular 1.x and Angular 2