{"id":13990,"date":"2017-03-17T09:00:46","date_gmt":"2017-03-17T00:00:46","guid":{"rendered":"http:\/\/www.techscore.com\/blog\/?p=13990"},"modified":"2018-11-14T16:33:43","modified_gmt":"2018-11-14T07:33:43","slug":"creating-a-hybrid-environment-in-angular-using-upgrademodule","status":"publish","type":"post","link":"https:\/\/www.techscore.com\/blog\/2017\/03\/17\/creating-a-hybrid-environment-in-angular-using-upgrademodule\/","title":{"rendered":"Creating a hybrid environment in Angular using UpgradeModule"},"content":{"rendered":"<ul>\nJust to clarify, I will be referring to the following terms as below:<\/p>\n<p>&nbsp;<\/p>\n<ul>\n<li>Angular 1 as AngularJS<\/li>\n<li>Angular 2 as Angular<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<p>Google released the first stable version of Angular by the end of 2016 and since Angular has been completely rewritten and is not an upgrade of AngularJS, it is a big break change for companies that already have quite robust system built in AngularJS in their frontend.<\/p>\n<p>Having said that, I decided to write and explain step by step how to utilize UpgradeModule library from Angular and have an AngularJS application that allows Angular components within in its application, and not only that but also by utilizing it, it is also possible achieve communication between AngularJS controllers and Angular services and vice versa.<\/p>\n<h2>Setting the environment in Plunker<\/h2>\n<p>For demonstration purposes, I will be using <a href=\"https:\/\/plnkr.co\/\">Plunker<\/a>. I will also explain step by step how to set the correct hybrid environment in Plunker as well.<\/p>\n<p>From <a href=\"https:\/\/plnkr.co\/edit\/\">here<\/a>\u00a0click on the new dropdown button and select \u201cAngular 1.5\u201d, exclude the \u201cAngular 1.5 + Typescript\u201d option because in future articles I want to show how AngularJS controllers, directives, services completely written in Javascript communicate with Angular components.<\/p>\n<p><a href=\"https:\/\/www.techscore.com\/blog\/wp\/wp-content\/uploads\/2017\/03\/new_project_plunkr.png\" rel=\"facebox\" rel=\"attachment wp-att-14096\"><img loading=\"lazy\" src=\"https:\/\/www.techscore.com\/blog\/wp\/wp-content\/uploads\/2017\/03\/new_project_plunkr-300x277.png\" alt=\"\" width=\"300\" height=\"277\" class=\"alignnone size-medium wp-image-14096\" srcset=\"https:\/\/www.techscore.com\/blog\/wp\/wp-content\/uploads\/2017\/03\/new_project_plunkr-300x277.png 300w, https:\/\/www.techscore.com\/blog\/wp\/wp-content\/uploads\/2017\/03\/new_project_plunkr-768x708.png 768w, https:\/\/www.techscore.com\/blog\/wp\/wp-content\/uploads\/2017\/03\/new_project_plunkr-1024x944.png 1024w, https:\/\/www.techscore.com\/blog\/wp\/wp-content\/uploads\/2017\/03\/new_project_plunkr.png 1453w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<h2>Mapping core Angular libraries<\/h2>\n<p>Then, from the menu on the left, create a new file named \"config.js\". That file will utilize a module loader, which will be mapping and telling Angular where to look when a library is being invoked.<\/p>\n<p>This file will be utilizing <a href=\"https:\/\/github.com\/systemjs\/systemjs\">SystemJS<\/a>, but there are some other options such as <a href=\"http:\/\/webpack.github.io\">Webpack <\/a><\/span><span lang=\"en-US\">\u00a0and <a href=\"http:\/\/browserify.org\/\">Browserify<\/a>.<\/span><br \/>\nAfter creating the file, we just can copy and paste the following code that includes the libraries we will be utilizing this time.<\/p>\n<p>config.js<\/p>\n<pre class=\"\">System.config({\r\n  \/\/use typescript for compilation\r\n  transpiler: 'typescript',\r\n  \/\/typescript compiler options\r\n  typescriptOptions: {\r\n    emitDecoratorMetadata: true\r\n  },\r\n  paths: {\r\n    'npm:': 'https:\/\/unpkg.com\/'\r\n  },\r\n  \/\/map tells the System loader where to look for things\r\n  map: {\r\n\r\n    'app': '.\/src',\r\n    '@angular\/core': 'npm:@angular\/core\/bundles\/core.umd.js',\r\n    '@angular\/common': 'npm:@angular\/common\/bundles\/common.umd.js',\r\n    '@angular\/compiler': 'npm:@angular\/compiler\/bundles\/compiler.umd.js',\r\n    '@angular\/platform-browser': 'npm:@angular\/platform-browser\/bundles\/platform-browser.umd.js',\r\n    '@angular\/platform-browser-dynamic': 'npm:@angular\/platform-browser-dynamic\/bundles\/platform-browser-dynamic.umd.js',\r\n    '@angular\/http': 'npm:@angular\/http\/bundles\/http.umd.js',\r\n    '@angular\/router': 'npm:@angular\/router\/bundles\/router.umd.js',\r\n    '@angular\/forms': 'npm:@angular\/forms\/bundles\/forms.umd.js',\r\n\r\n    '@angular\/core\/testing': 'npm:@angular\/core\/bundles\/core-testing.umd.js',\r\n    '@angular\/common\/testing': 'npm:@angular\/common\/bundles\/common-testing.umd.js',\r\n    '@angular\/compiler\/testing': 'npm:@angular\/compiler\/bundles\/compiler-testing.umd.js',\r\n    '@angular\/platform-browser\/testing': 'npm:@angular\/platform-browser\/bundles\/platform-browser-testing.umd.js',\r\n    '@angular\/platform-browser-dynamic\/testing': 'npm:@angular\/platform-browser-dynamic\/bundles\/platform-browser-dynamic-testing.umd.js',\r\n    '@angular\/http\/testing': 'npm:@angular\/http\/bundles\/http-testing.umd.js',\r\n    '@angular\/router\/testing': 'npm:@angular\/router\/bundles\/router-testing.umd.js',\r\n    '@angular\/upgrade': 'npm:@angular\/upgrade\/bundles\/upgrade.umd.js',\r\n    '@angular\/upgrade\/static': 'npm:@angular\/upgrade\/bundles\/upgrade-static.umd.js',\r\n    'rxjs': 'npm:rxjs',\r\n    'typescript': 'npm:typescript@2.0.2\/lib\/typescript.js'\r\n  },\r\n  \/\/packages defines our app package\r\n  packages: {\r\n  \/\/this file will be used for bootstrapping our application.\r\n    app: {\r\n      main: '.\/main.ts',\r\n      defaultExtension: 'ts'\r\n    },\r\n    app_component_ts: {\r\n      \/\/ this will our future file where we will create our Angular component.\r\n      main: '.\/my-university.ts',\r\n      defaultExtension: 'ts'\r\n    },\r\n    rxjs: {\r\n      defaultExtension: 'js'\r\n    }\r\n  }\r\n});\r\n<\/pre>\n<h2>Adding core libraries to index.html<\/h2>\n<p>Then we have to prepare the index.html so that it loads the config.js we just created and some core libraries needed (zonejs, reflectjs, systemjs) by Angular. \u00a0Also we need to delete the AngularJS code created by plunker so that it does not bootstrap.<\/p>\n<p>Later on after editing the AngularJS controller created by Plunker(app.js) and creating a new Angular component, we will return to this file to call both components (AngularJS and Angular) from here.<\/p>\n<p>After editing index.html, it should look something similar as below.<\/p>\n<p>index.html<\/p>\n<pre>  \r\n  <html>\r\n\r\n  <head>\r\n    <meta charset=\"utf-8\" \/>\r\n    <title>AngularJS Plunker<\/title>\r\n\r\n    <script data-require=\"angular.js@1.5.x\" src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/angular.js\/1.5.10\/angular.min.js\" data-semver=\"1.5.10\"><\/script>\r\n    <script src=\"https:\/\/unpkg.com\/zone.js\/dist\/zone.js\"><\/script>\r\n    <script src=\"https:\/\/unpkg.com\/zone.js\/dist\/long-stack-trace-zone.js\"><\/script>\r\n    <script src=\"https:\/\/unpkg.com\/reflect-metadata@0.1.3\/Reflect.js\"><\/script>\r\n    <script src=\"https:\/\/unpkg.com\/systemjs@0.19.31\/dist\/system.js\"><\/script>\r\n    <script src=\"config.js\"><\/script>\r\n    <script src=\"app.js\"><\/script>\r\n\r\n\r\n  <script>\r\n    System.import('app')\r\n      .catch(console.error.bind(console));\r\n  <\/script>\r\n\r\n  <\/head>\r\n\r\n  <body>\r\n\r\n\r\n  <\/body>\r\n\r\n<\/html>\r\n\r\n<\/pre>\n<h2>Creating an Angular component<\/h2>\n<p>Next we create the sample Angular component that we want to display later display it in our app. This time I am calling it\u00a0src\/my-uniservity.ts (note the file's path), this file is also mapped in the previously created \"config.js\" file.<\/p>\n<p>Inside we will assign a moduleID, selector and template. The component, my-university, will be called by using its selector as html tag in the template. Lastly, we will export its class so that other classes can access it.<\/p>\n<p>src\/my-university.ts<\/p>\n<pre>\r\n\r\nimport { Component } from '@angular\/core';\r\n\r\n@Component({\r\n  moduleId: __moduleName,\r\n  selector: 'my-university',\r\n  template: `\r\n<h1>{{title}}<\/h1>\r\n`, }) export class AppComponent { title = 'Tokyo University'; }\r\n<\/pre>\n<h2>Creating and organizing NgModule<\/h2>\n<p>Next we create \"src\/app.module.ts\", which includes NgModule. This last one, will help us to organize the entire application into blocks. It receives a metadata object then Angular interprets it and compiles our components.<\/p>\n<p>This file also will be importing\u00a0UpgradeModule that will help us to prevent Angular from bootstrapping utilizing the ngDoBootstrap method.<\/p>\n<p>Note that this file will be also importing the previously created \"src\/my-university.ts\" file<br \/>\n&nbsp;<br \/>\nsrc\/app.module.ts<\/p>\n<pre class=\"\">\r\nimport { NgModule }      from '@angular\/core';\r\nimport { UpgradeModule } from '@angular\/upgrade\/static';\r\nimport { BrowserModule } from '@angular\/platform-browser';\r\nimport { FormsModule }   from '@angular\/forms';\r\nimport { RouterModule }   from '@angular\/router';\r\nimport { AppComponent }  from '.\/my-university.ts';\r\n\r\n@NgModule({\r\n  imports: [\r\n    UpgradeModule,\r\n    BrowserModule,\r\n    FormsModule\r\n  ],\r\n  declarations: [\r\n    AppComponent\r\n  ],\r\n  bootstrap: [ AppComponent ]\r\n})\r\nexport class AppModule { }\r\n<\/pre>\n<h2>Implementing UpgradeModule<\/h2>\n<p>Then we create another file called \"src\/main.ts\" which it is the one that will invoke the UpgradeModule class and bootstrap our application. It should look as below.<br \/>\n&nbsp;<br \/>\nsrc\/main.ts<\/p>\n<pre class=\"\">import { platformBrowserDynamic } from '@angular\/platform-browser-dynamic';\r\nimport { UpgradeModule } from '@angular\/upgrade\/static';\r\nimport { AppModule } from '.\/app.module';\r\n\r\n\r\ndeclare var angular: any;\r\n\r\n\r\nplatformBrowserDynamic().bootstrapModule(AppModule).then(platformRef => {\r\n  const upgrade = platformRef.injector.get(UpgradeModule) as UpgradeModule;\r\n  upgrade.bootstrap(document.body, ['my-app'], {strictDi: true});\r\n});\r\n<\/pre>\n<h2>Creating an AngularJS controller<\/h2>\n<p>Now we delete all the source code created by plunker in the file \"app.js\", rename it to \"university-controller.js\" and create a new Controller inside of it. This controller be called from index.html<\/p>\n<p>university-controller.js<\/p>\n<pre>    \r\nangular.module('my-app', [])\r\n  .controller('UniversityController', ['$scope', function ($scope) {\r\n    $scope.universityName = 'UBC University';\r\n  }]);\r\n<\/pre>\n<h2>Invoking both, an Angular component and an AngularJS controller<\/h2>\n<p>Finally we return to the \"index.html\" file and make it call our AngularJS controller and Angular component by using their selectors inside the body tags.<br \/>\n&nbsp;<br \/>\nindex.html<\/p>\n<pre>\r\n<html>\r\n\r\n  <head>\r\n    <meta charset=\"utf-8\" \/>\r\n    <title>AngularJS Plunker<\/title>\r\n\r\n    <script data-require=\"angular.js@1.5.x\" src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/angular.js\/1.5.10\/angular.min.js\" data-semver=\"1.5.10\"><\/script>\r\n    <script src=\"https:\/\/unpkg.com\/zone.js\/dist\/zone.js\"><\/script>\r\n    <script src=\"https:\/\/unpkg.com\/zone.js\/dist\/long-stack-trace-zone.js\"><\/script>\r\n    <script src=\"https:\/\/unpkg.com\/reflect-metadata@0.1.3\/Reflect.js\"><\/script>\r\n    <script src=\"https:\/\/unpkg.com\/systemjs@0.19.31\/dist\/system.js\"><\/script>\r\n    <script src=\"config.js\"><\/script>\r\n    <script src=\"university-controller.js\"><\/script>\r\n\r\n\r\n  <script>\r\n    System.import('app')\r\n      .catch(console.error.bind(console));\r\n  <\/script>\r\n\r\n  <\/head>\r\n\r\n  <body>\r\n    <h1 ng-controller=\"UniversityController\">\r\n      {{universityName}}\r\n    <\/h1>\r\n    <my-university>Loading...<\/my-university>\r\n\r\n  <\/body>\r\n\r\n<\/html>\r\n\r\n<\/pre>\n<p>The screen in Plunker should look as below.<\/p>\n<p><a href=\"https:\/\/www.techscore.com\/blog\/wp\/wp-content\/uploads\/2017\/03\/Screen-Shot-2017-03-01-at-12.25.52.png\" rel=\"facebox\" rel=\"attachment wp-att-14010\"><img loading=\"lazy\" class=\"alignnone size-medium wp-image-14010\" src=\"https:\/\/www.techscore.com\/blog\/wp\/wp-content\/uploads\/2017\/03\/Screen-Shot-2017-03-01-at-12.25.52-300x192.png\" alt=\"\" width=\"300\" height=\"192\" srcset=\"https:\/\/www.techscore.com\/blog\/wp\/wp-content\/uploads\/2017\/03\/Screen-Shot-2017-03-01-at-12.25.52-300x192.png 300w, https:\/\/www.techscore.com\/blog\/wp\/wp-content\/uploads\/2017\/03\/Screen-Shot-2017-03-01-at-12.25.52-768x491.png 768w, https:\/\/www.techscore.com\/blog\/wp\/wp-content\/uploads\/2017\/03\/Screen-Shot-2017-03-01-at-12.25.52-1024x655.png 1024w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>Here is a direct link to the plunker <a href=\"https:\/\/plnkr.co\/edit\/MstPm7TF3TR88b72lQdK?p=preview\">sample<\/a>.<\/p>\n<p>In future articles I will demonstrate how to achieve communication between AngularJS services with Angular components and vice versa.<\/p>\n<h2>References<\/h2>\n<p><a href=\"https:\/\/angular.io\/docs\/ts\/latest\/guide\/upgrade.html\">Upgrading from AngularJS<\/a><br \/>\n<a href=\"https:\/\/docs.angularjs.org\/guide\/directiveectives\">Creating Custom Directives<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Just to clarify, I will be referring to the following terms as below:<\/p>\n<p>&nbsp;<\/p>\n<p> \tAngular 1 as <br \/><a href=\"https:\/\/www.techscore.com\/blog\/2017\/03\/17\/creating-a-hybrid-environment-in-angular-using-upgrademodule\/\">\u7d9a\u304d\u3092\u8aad\u3080...<\/a><\/p>\n","protected":false},"author":61,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[18],"tags":[],"_links":{"self":[{"href":"https:\/\/www.techscore.com\/blog\/wp-json\/wp\/v2\/posts\/13990"}],"collection":[{"href":"https:\/\/www.techscore.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.techscore.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.techscore.com\/blog\/wp-json\/wp\/v2\/users\/61"}],"replies":[{"embeddable":true,"href":"https:\/\/www.techscore.com\/blog\/wp-json\/wp\/v2\/comments?post=13990"}],"version-history":[{"count":47,"href":"https:\/\/www.techscore.com\/blog\/wp-json\/wp\/v2\/posts\/13990\/revisions"}],"predecessor-version":[{"id":14097,"href":"https:\/\/www.techscore.com\/blog\/wp-json\/wp\/v2\/posts\/13990\/revisions\/14097"}],"wp:attachment":[{"href":"https:\/\/www.techscore.com\/blog\/wp-json\/wp\/v2\/media?parent=13990"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.techscore.com\/blog\/wp-json\/wp\/v2\/categories?post=13990"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.techscore.com\/blog\/wp-json\/wp\/v2\/tags?post=13990"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}