Real-Time Web Components with Polymer & AngularJS 
(in 90 seconds)

Ac1a1d449af259bfb7191105db5212a2?s=47 Sunny Gleason
November 15, 2014

Real-Time Web Components with Polymer & AngularJS 
(in 90 seconds)

The practice of building web and mobile web applications has
advanced rapidly over the past few years with the introduction of frameworks like AngularJS: it is now now only possible, but pleasant to build rich cross-platform apps in HTML5 and JavaScript. Polymer and Web Components are the next generation of patterns and best practices in modern web application design. In this presentation, we introduce a third technology that is changing the way developers think about building applications: Real-time, scalable data
streaming services are changing the model for applications
from generic data "pull" to real-time, individualized data "push". In
this talk, we go through an example of a Real-Time AngularJS
application using 3-way data binding and adapt it to take advantage
of Web Components using Polymer. All examples are provided as
codepens on codepen.io so developers can hack along as we go.

Ac1a1d449af259bfb7191105db5212a2?s=128

Sunny Gleason

November 15, 2014
Tweet

Transcript

  1. Real-Time Web Components with Polymer & AngularJS
 (in 90 seconds)

    Sunny Gleason Google Developer Group Boston / Polymer Hack Day November 15, 2014 http://goo.gl/rsqEZ8
  2. var self = this; • Sunny Gleason, All-Stack Engineer •

    Previous: Amazon (web services), Ning, Startup(1..N) • Current: SunnyCloud • Short Story: A-Team you can call on to help you build (or rescue) cloud services, web & mobile applications • Longer Story: Network of developers aiming to change the way businesses build applications
  3. take these… Codepen 1
 (AngularJS original) http://goo.gl/wtjF2h Codepen 2a
 (AngularJS+Polymer)

    http://goo.gl/oce7fn Codepen 2b
 (Polymer Web Component) http://goo.gl/Ka9bU3 PubNub Trial http://goo.gl/oJnTpv
  4. what’s in store…

  5. what’s AngularJS?

  6. what’s Polymer?

  7. what’s PubNub?

  8. hello codepen (this is the 90 seconds part)

  9. why is real-time important?

  10. why is real-time important?

  11. applications should must be 
 customer-focused 
 responsive Ǎ 


    live updating
  12. our demo application real-time chat user presence  message history


    
 … in 99 lines of HTML/JS
  13. what does it do? 
 į subscribe to a real-time

    channel display a list of online users show the list of recent messages publish messages to the channel
  14. demo (AngularJS)

  15. first up:

  16. the html (1) <script src=“https://cdn.pubnub.com/pubnub.min.js" />! <script src=“//ajax.googleapis.com/ajax/libs/angularjs/1.3.2/angular.min.js” />! <script

    src=“http://pubnub.github.io/pubnub-angular/lib/pubnub-angular.js" />! <link rel="stylesheet"
 href=“//netdna.bootstrapcdn.com/bootstrap/3.0.2/css/bootstrap.min.css" /> • include PubNub data stream network • include AngularJS library • include PubNub / AngularJS library • include Bootstrap styles (optional)
  17. the html (2) <div class="container"
 ng-app="PubNubAngularApp"
 ng-controller="ChatCtrl">! ...! </div> •

    Configure Application • Bind the Controller
  18. the html (3) <h4>Online Users</h4>! <ul>! <li ng-repeat="user in users">{{user}}</li>!

    </ul> • Display a dynamic list of users • Display a dynamic list of messages <div class="well">! <ul>! <li ng-repeat="message in messages">{{message}}</li>! </ul>! </div>
  19. the html (4) <form ng-submit='publish()'>! <input type="text" ng-model='newMessage' />! <input

    type="submit" value="Send" />! </form> • Create a form • Bind a text input as chat message input • Bind form submission to ‘publish()’
  20. on to the…

  21. js: app (1) angular.module('PubNubAngularApp', ["pubnub.angular.service"])! .controller('ChatCtrl', function($rootScope, $scope, PubNub) {

    • Create an AngularJS application • Depend on pubnub.angular.service • Create a controller • Inject $rootScope, $scope, PubNub
  22. js: init (2) // make up a user id (you

    probably already have this)! $scope.userId = "User " + Math.round(Math.random() * 1000);! // make up a channel name! $scope.channel = 'The Angular Channel';! // pre-populate any existing messages (just an AngularJS scope object)! $scope.messages = ['Welcome to ' + $scope.channel]; • Create a random user id • Put the channel name in $scope • Initialize messages array
  23. js: init (3) if (!$rootScope.initialized) {! // Initialize the PubNub

    service! PubNub.init({! subscribe_key: 'demo',! publish_key: 'demo',! uuid:$scope.userId! });! $rootScope.initialized = true;! } • Initialize the PubNub service • Use $rootScope for persistence
 across controllers
  24. js: subscribe (4) // Subscribe to the Channel! PubNub.ngSubscribe({ channel:

    $scope.channel }); • Subscribe to “The Angular Channel” • Enable AngularJS $broadcast events
 in the background for messages and
 presence events
  25. // Create a publish() function in the scope! $scope.publish =

    function() {! PubNub.ngPublish({! channel: $scope.channel,! message: "[" + $scope.userId + "] " + $scope.newMessage! });! $scope.newMessage = '';! }; js: publish (5) • Create a “publish()” function: • Call PubNub ngPublish() • Reset ‘newMessage’
  26. js: message events (6) // Register for message events! $rootScope.$on(PubNub.ngMsgEv($scope.channel),

    function(ngEvent, payload) {! $scope.$apply(function() {! $scope.messages.push(payload.message);! });! }); • Register for message events • Push message into the list • Call within $scope.$apply so AngularJS knows about it
  27. js: presence events (7) // Register for presence events (optional)!

    $rootScope.$on(PubNub.ngPrsEv($scope.channel),
 function(ngEvent, payload) {! $scope.$apply(function() {! $scope.users = PubNub.ngListPresence($scope.channel);! });! }); • Register for presence events • Get list of users from PubNub service • Update users list in $scope • Call inside $scope.$apply
  28. js: presence & history (8) // Pre-Populate the user list

    (optional)! PubNub.ngHereNow({! channel: $scope.channel! });! ! // Populate message history (optional)! PubNub.ngHistory({! channel: $scope.channel,! count: 500! }); • Call the ngHereNow() function to trigger an initial presence event • Call the ngHistory() function to trigger historical message events
  29. … and you’re done!

  30. why Polymer?

  31. why Polymer?

  32. why Polymer?

  33. directives & web components AngularJS Directive Web Component Integration Style:

    JavaScript HTML5 Import Resembles a: Mixin Standalone Object Scope / State is: Nested, Coupled Self-Contained Data Propagation: Implicit (Digest) Explicit Events
  34. web component (1) <polymer-element name="pubnub-userlist" attributes="users">! <template>! <style>...</style>! <h4>Online Users</h4>!

    <ul>! <template repeat="{{ user in users }}">! <li>{{user}}</li>! </template>! </ul>! </template>! <script>...</script>! </polymer-element> • Display a dynamic list of users
  35. web component (2) <polymer-element name="pubnub-userlist" attributes="users">! <template>! <style>
 li {

    color: gray; }
 </style>! ...! </template>! <script>...</script>! </polymer-element> • Self-contained CSS styles
  36. web component (3) <polymer-element name="pubnub-userlist" attributes="users">! <template>! <style>...</style>! ...! </template>!

    <script>
 Polymer('pubnub-userlist', {! publish: { users: {value: [], reflect: true} },! users: [],! usersChanged: function() {! console.log("woot!", this.users);
 }! });
 </script>! </polymer-element> • Self-Contained State & Logic
  37. web component (4) <polymer-element name="pubnub-userlist" attributes="users">! <template>! <link rel=“stylesheet” href="..."></link>!

    ...! </template>! <script src="..."></script>! </polymer-element> • Consider externalizing CSS & JS • Yay! CoffeeScript & Less are back!
  38. AngularJS & Polymer

  39. angupoly (for the brave) <html><head>
 ...! <script src="http://cdnjs.cloudflare.com/ajax/libs/polymer/0.2.3/platform.js"></script>! <script src="http://cdnjs.cloudflare.com/ajax/libs/polymer/0.2.3/polymer.js"></script>!

    <script src="https://rawgit.com/matjaz/angu-poly/master/angupoly.js"></script>! <link rel="import" href="http://codepen.io/sunnygleason/pen/mydwqL.html"></link>! </head><body>! <div class="container" ng-app="PubNubAngularApp" ng-controller="ChatCtrl">! ! <pubnub-userlist angupoly="{users:'users'}"></pubnub-userlist> • Include Polymer • Include angupoly • Import Web Component • Use the Element
  40. ng-polymer-elements (for the pure) <!DOCTYPE html>! <html ng-app="myModule">! <head>! <script

    src="platform.js"></script>! <!-- your imports here -->! </head>! <body unresolved>! <!-- your view here -->! <script src="angular.js"></script>! <script src="ng-polymer-elements.js"></script>! <!-- your scripts here -->! </body>! </html> • Include Polymer & AngularJS • Include ng-polymer-elements
  41. ng-polymer-elements (for the pure) <!DOCTYPE html>! <html ng-app="myModule">! <head>...</head>! <body

    unresolved>! ...
 <textarea ng-model="multilineText"></textarea>! <core-input ng-model="multilineText" multiline></core-input>! <paper-input ng-model="multilineText" multiline></paper-input>! </body>! </html> • Use Polymer Paper Elements • Enjoy AngularJS 2-Way Binding
  42. coming soon…

  43. … and you’re done! questions? thank you!