AngularJs components in Angular

I love AngularJs as much as I love new Angular framework. (Note: Angular 1 refers to AngularJs and Angular 2/4/5 versions as Angular). All my new personal projects I'm building with Angular. At my work place, I have to work with AngularJs.

I have been searching for a good solution for using Angular 2/4/5 code inside AngularJs application. I came across different options like NgForword but the only thing worked for me is Angular's official 'NgUpgrade' module.
Techumber- AngularJs components in Angular

The goal of this tutorial is to use AngularJS, Angular components in a single Angular Application. We are not gonna discuss Angular services in this post.

We will create component using AngularJS and using Angular and use them together.

You can download the complete source code from below link.


Download

This is complete code in case if you are like me just want to try out first. Below I explained code in detail.

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';


import { NgModule,Component } from '@angular/core';  
import { BrowserModule } from '@angular/platform-browser';  
import { UpgradeModule, downgradeComponent } from '@angular/upgrade/static';

/** This is AngularJs component object **/
export const ng1AppComponent = {  
  template: '<h2>This is Angular 1 Component</h2>',
  controller: class AppCtrl {
 constructor() {}
  }
};

/** AngularJs Module **/
export const ng1Module = angular.module('ng1Module', []);  
ng1Module.component('ng1AppComponent', ng1AppComponent);

/** Angular Component **/
@Component({
    selector: 'ng4-app-component',
    template: `
        <h2>Wow!! this is Angular4 component.</h2>
    `
})
export class ng4AppComponent {

};
/** Downgrade Angular components to use them in AngularJs **/
ng1Module.directive('ng4AppComponent', downgradeComponent({component: ng4AppComponent}));

/** Angular 2 Module **/
@NgModule({
  declarations: [
    ng4AppComponent
  ],
  imports: [
    BrowserModule,
    UpgradeModule
  ],
  entryComponents: [
    ng4AppComponent
  ]
})
export class AppModule {  
  constructor(private upgrade: UpgradeModule) {}

  ngDoBootstrap() {
    /** bootstrap  Angularjs here**/
    this.upgrade.bootstrap(document.body, [ng1Module.name]);
  }
}

/*Bootstrap Angular here*/
platformBrowserDynamic().bootstrapModule(AppModule);  

That's it. It's really it. This is how you can use both Angular and AngularJs app with in the same application.

Go on read the rest.

Let's First Build simple AngularJs application.

index.html

<!DOCTYPE html>  
<html lang="en">  
<head>  
    <meta charset="UTF-8">
    <title>Angular Hybrid</title>
    <!-- AngularJs -->
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.5/angular.min.js"></script>
    <!-- app code -->
    <script src="./ng1/app.module.js"></script>
</head>  
<body ng-app="ng1Module">  
    <ng1-app-component></ng1-app-component>
</body>  
</html>  

Simple AngularJs boilerplate bootstrap the application with ng-app directive.

/ng1/app.module.js

import { ng1AppComponent } from './app.component';

// Access global AngularJS 1.x object
export const ng1Module = angular.module('ng1Module', []);  
ng1Module.component('ng1AppComponent', ng1AppComponent);  

/ng1/app.component.ts

I'm using ES6 to write our AnguarJs Applicaiton. But you can use ES5 as well. Here we exporting ng1Module module that we gonna use later.

export const ng1AppComponent = {  
  template: '<h2>This is Angular 1 Component</h2>',
  controller: class AppCtrl {
 constructor() {}
  }
};

It's just simple AngularJs component.

Now let's write Angular Application.

<!DOCTYPE html>  
<html lang="en">  
<head>  
    <meta charset="UTF-8">
    <title>Angular Hybrid</title>
    <!-- AngularJs -->
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.5/angular.min.js"></script>
    <!-- packages for Angular -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/typescript/2.1.1/typescript.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/core-js/2.4.1/core.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/zone.js/0.8.4/zone.min.js"></script>
    <script src="https://unpkg.com/zone.js/dist/long-stack-trace-zone.js"></script>
    <script src="https://unpkg.com/reflect-metadata@0.1.3/Reflect.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.41/system.js"></script>
    <!-- SystemJs and bootstrap -->
    <script src="systemjs.config.js"></script>
    <script>
        System
            .import('src/_bootstrap.ts')
            .catch(console.error.bind(console));
    </script>
</head>  
<body>  
    <ng4-app-component></ng4-app-component>
</body>  
</html>  

/systemjs.config.js

System.config({  
    transpiler: 'typescript',
    typescriptOptions: {
        emitDecoratorMetadata: true,
        experimentalDecorators: true,
    },
    paths: {
        'npm:': 'https://unpkg.com/'
    },
    packages: {
        'src': {
            defaultExtension: 'ts'
        },
        'vendor': {
            defaultExtension: 'js'
        }
    }
});

System.config({  
    map: {
        'main': 'main.js',

        // angular bundles
        '@angular/core': 'npm:@angular/core/bundles/core.umd.js',
        '@angular/common': 'npm:@angular/common/bundles/common.umd.js',
        '@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js',
        '@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js',
        '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
        '@angular/upgrade/static': 'npm:@angular/upgrade/bundles/upgrade-static.umd.js',
        // other libraries
        'rxjs': 'npm:rxjs@5.0.1',
        'ts': 'npm:plugin-typescript@5.2.7/lib/plugin.js',
        'typescript': 'npm:typescript@2.3.2/lib/typescript.js',
    },
    packages: {
        // Thirdparty barrels.
        'rxjs': { main: 'index' },
    }
});

This is our minimal systemjs config to run Angular app in Browser without worrying about installing packages.

_bootstrap.ts

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';  
import { AppModule } from './ng4/_app.module';

platformBrowserDynamic().bootstrapModule(AppModule);  

ng4/_app.module.ts

import { NgModule,Component } from '@angular/core';  
import { BrowserModule } from '@angular/platform-browser';  
import { ng4AppComponent } from './_app.component'; 

@NgModule({
  declarations: [
    ng4AppComponent
  ],
  imports: [
    BrowserModule,
    UpgradeModule
  ],
  bootstrap: [
    ng4AppComponent
  ]
})
export class AppModule {  
}

Nothing much to explain here. It's a simple Angular module.

/ng4/_app.component.ts

import { Component, NgModule } from '@angular/core';

@Component({
    selector: 'ng4-app-component',
    template: `
        <h2>Wow!! this is Angular4 component.</h2>
    `
})
export class ng4AppComponent {

};

Ok, Now we have both AnguarJs and Angular applications.

Change all your javascript file extension from '.js' to '.ts'. Don't worry we don't have to change any code inside it because typescript is a superset of ES5 and ES6. So it's cool!!!.

Angular 1 bootstraps application using ng-app directive. The other way is to use angular.bootstrap.

angular.bootstrap(document.body, ['ng1Module'], { strictDi: true });  

NgUpgrade have same bootstrap method on it. We need to run it inside our Angular 2 Module.

import { NgModule,Component } from '@angular/core';  
import { BrowserModule } from '@angular/platform-browser';  
import { UpgradeModule,downgradeComponent } from '@angular/upgrade/static';  
import { ng4AppComponent } from './_app.component';  
import { ng1Module } from '../ng1/app.module';

@NgModule({
  declarations: [
    ng4AppComponent
  ],
  imports: [
    BrowserModule,
    UpgradeModule
  ],
  entryComponents: [
    ng4AppComponent
  ]
})
export class AppModule {  
  constructor(private upgrade: UpgradeModule) {}

  ngDoBootstrap() {
    this.upgrade.bootstrap(document.body, [ng1Module.name]);
  }
}

Here we bootstrapping AnguarJs app after Angular app get bootstrapped by using ngDoBootstrap function.

Now we need to downgrade all our Angular components to use them inside our Angular js application.

import { downgradeComponent } from '@angular/upgrade/static';

// Downgrade Angular components for AngularJs
ng1Module.directive('ng4AppComponent', downgradeComponent({component: ng4AppComponent}));

All Angular Components to entryComponents list

import { ng4AppComponent } from './_app.component'; 

@NgModule({
  .....
  .....
  entryComponents: [
    ng4AppComponent
  ]
})

That's it. Now you should be able to run both Angular and AngularJs side by side.

Update you index.html

.........
</head>  
<body>  
    <ng4-app-component></ng4-app-component>
    <ng1-app-component></ng1-app-component>
</body>  
.....

Get posts by email

Like what you're reading? Get these posts delivered to your inbox.