Upgrade to Pro — share decks privately, control downloads, hide ads and more …

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

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.

Sunny Gleason

November 15, 2014

More Decks by Sunny Gleason

Other Decks in Technology


  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

    http://goo.gl/oce7fn Codepen 2b
 (Polymer Web Component) http://goo.gl/Ka9bU3 PubNub Trial http://goo.gl/oJnTpv
  4. 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
  5. 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)
  6. 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>
  7. 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()’
  8. 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
  9. 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
  10. 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
  11. 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
  12. // 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’
  13. 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
  14. js: presence events (7) // Register for presence events (optional)!

 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
  15. 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
  16. 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
  17. 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
  18. 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
  19. web component (3) <polymer-element name="pubnub-userlist" attributes="users">! <template>! <style>...</style>! ...! </template>!

 Polymer('pubnub-userlist', {! publish: { users: {value: [], reflect: true} },! users: [],! usersChanged: function() {! console.log("woot!", this.users);
 }! });
 </script>! </polymer-element> • Self-Contained State & Logic
  20. 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!
  21. 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
  22. 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
  23. 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