Converting an AngularJS 1.x App to Angular 7

If you’ve been using Angular for a while, then you probably already have production AngularJS 1 apps. Angular 7 is great, but there’s no way we can drop everything and rewrite our entire production apps in Angular 7. What we need is a way to incrementally upgrade our AngularJS 1 app. Thankfully, Angular 7 has a fantastic way to do that.

The interoperability of AngularJS 1 (ng1) and Angular 7 (ng2) works really well. In this chapter, we’re going to talk about how to upgrade your ng1 app to ng2 by writing a hybrid app. A hybrid app is running ng1 and ng2 simultaneously (and we can exchange data between them).

Peripheral Concepts

When we talk about interoperability between AngularJS 1 and Angular 7, there’s a lot of peripheral concepts. For instance:

Mapping AngularJS 1 Concepts to Angular 7: At a high level, ng2 Components are ng1 directives. We also use Services in both. However, this chapter is about using both ng1 and ng2, so we’re going to assume you have basic knowledge of both. If you haven’t used ng2 much, checkout the chapter on How Angular Works before reading this chapter.

Preparing ng1 apps for ng2: AngularJS 1.5 provides a new .component method to make “component-directives”. .component is a great way to start preparing your ng1 app for ng2. Furthermore, creating thin controllers (or banning them altogether) is a great way to refactor your ng1 app such that it’s easier to integrate with ng2.

Another way to prepare your ng1 app is to reduce or eliminate your use of two-way data-binding in favor of a one-way data flow. In-part, you’d do this by reducing $scope changes that pass data between directives and instead use services to pass your data around.

These ideas are important and warrant further exploration. However, we’re not going to extensively cover best-practices for pre-upgrade refactoring in this chapter.

Instead, here’s what we are going to talk about:

Writing hybrid ng1/ng2 apps: ng2 provides a way to bootstrap your ng1 app and then write ng2 components and services. You can write ng2 components that will mix with ng1 components and it “just works”. Furthermore, the dependency injection system supports passing between ng1 and ng2 (both directions), so you can write services which will run in either ng1 or ng2.

The best part? Change detection runs within Zones, so you don’t need to call $scope.apply or worry much about change-detection at all.

What We’re Building

In this chapter, we’re going to be converting an app called “Interest” - it’s a Pinterest-like clone. The idea is that you can save a “Pin” which is a link with an image. The Pins will be shown in a list and you can “fav” (or unfav) a pin.

Our completed Pinterest-like app

You can find the completed code for both the ng1 version and the completed hybrid version in the sample code download under code/upgrade/ng1 and code/conversion/hybrid

The hybrid app is written using Angular CLI. In order to run it, change into the directory and type:

npm install
npm start

Before we dive in, let’s set the stage for interoperability between ng1 and ng2

Mapping AngularJS 1 to Angular 7

From a high level, the five main parts of AngularJS 1 are:

Angular 7 changes this list significantly. You might have heard that at ngEurope 2014 Igor and Tobias from the Angular core team announced that they were killing off several “core” ideas in AngularJS 1 (video here). Specifically, they announced that Angular 7 was killing off:

Igor and Tobias killing off many APIs from 1.x. at ngEurope 2014. Photo Credit: Michael Bromley (used with permission)

As someone who’s built AngularJS 1 apps and is used to thinking in ng1, we might ask: if we take those things away, what is left? How can you build Angular apps without Controllers and $scope?

Well, as much as people like to dramatize how different Angular 7 is, it turns out, a lot of the same ideas are still with us and, in fact, Angular 7 provides just as much functionality but with a much simpler model.

At a high-level Angular 7 core is made up of:

Of course there’s tons of infrastructure required to make those things work. For instance, you need Dependency Injection to manage your Services. And you need a strong change detection library to efficiently propagate data changes to your app. And you need an efficient rendering layer to handle rendering the DOM at the right time.

Requirements for Interoperability

So given these two different systems, what features do we need for easy interoperability?

Angular 7 provides solutions for all of these situations and we’ll cover them in this chapter.

In this chapter we’re going to do the following:

The AngularJS 1 App

To set the stage, let’s go over the AngularJS 1 version of our app.

This chapter assumes some knowledge of AngularJS 1 and ui-router. If you’re not comfortable with AngularJS 1 yet, check out ng-book 1.

We won’t be diving too deeply into explaining each AngularJS 1 concept. Instead, we’re going to review the structure of the app to prepare for our upgrade to a ng2/hybrid app.

To run the ng1 app, cd into conversion/ng1 in the code samples, install the dependencies, and run the app.

cd code/upgrade/ng1  # change directories
npm install             # install dependencies
npm run go              # run the app

If your browser doesn’t open automatically, open the url: http://localhost:8080.

Note that the AngularJS 1 app in ng1 will run on port 8080 whereas the hybrid app (discussed below) will run on port 4200.

In this app, you can see that our user is collecting puppets. We can hover over an item and click the heart to “fav” a pin.

Red heart indicates a faved pin

We can also go to the /add page and add a new pin. Try submitting the default form.

Handling image uploads is more complex than we want to handle in this demo. For now, just paste the full URL to an image if you want to try a different image.

The ng1-app HTML

The index.html in our ng1 app uses a common structure:

    <!DOCTYPE html>
    <html ng-app='interestApp'>
    <head>
      <meta charset="utf-8">
      <title>Interest</title>
      <link rel="stylesheet" href="css/bootstrap.min.css">
      <link rel="stylesheet" href="css/sf.css">
      <link rel="stylesheet" href="css/interest.css">
    </head>
    <body class="container-fullwidth">
    
      <div class="page-header">
        <div class="container">
          <h1>Interest <small>what you're interested in</small></h1>
    
          <div class="navLinks">
            <a ui-sref='home' id="navLinkHome">Home</a>
            <a ui-sref='add' id="navLinkAdd">Add</a>
          </div>
        </div>
      </div>
    
      <div id="content">
        <div ui-view=''></div>
      </div>
    
      <script src="js/vendor/lodash.js"></script>
      <script src="js/vendor/angular.js"></script>
      <script src="js/vendor/angular-ui-router.js"></script>
      <script src="js/app.js"></script>
    </body>
    </html>
 
This page is a preview of ng-book 2.
Get the rest of this chapter plus hundreds of pages Angular 7 instruction, 5 sample projects, a screencast, and more.

 

Ready to master Angular 7?

  • What if you could master the entire framework – with solid foundations – in less time without beating your head against a wall? Imagine how quickly you could work if you knew the best practices and the best tools?
  • Stop wasting your time searching and have everything you need to be productive in one, well-organized place, with complete examples to get your project up without needing to resort to endless hours of research.
  • You will learn what you need to know to work professionally with ng-book: The Complete Book on Angular 7 or get your money back.
Download the First Chapter (for free)