User Tools

Site Tools


Browser Client AngularJS to Angular Migration


The browser client is built using AngularJS. The AngularJS project is getting overhauled and replaced by a fully refactored framework simply called Angular. The two projects are similar in concept, but the underlying code and how we as developers build code for each is quite different. Transitioning to Angular will require significantly more code changes than a typical AngularJS update.

AngularJS Project Status

The final release of AngularJS will be version 1.7. It will be an LTS release with 3 years of support.

Key Code Changes

  • Angular services, components, etc. have different structures
  • Lazy-loading, nested routing.
  • Native i18n support
  • Move to TypeScript
    • Note that TypeScript is universal in Angular, ng-bootstrap, rxjs libraries, documentation, stackoverflow, etc. Using Angular means using TypeScript.
  • Using ES6-style imports
  • Migrating from Bootstrap v3 to v4.
  • Use of Angular CLI for building

Migration Strategy Proposal

  • Create a parallel Angular app following style guide
  • Use plain HTML templates – No Template Toolkit!
    • Mixing TT2 with angular-cli for compiling, building, and i18n is a no-go, because it has to parse the HTML at compile time (not run time). It won't understand Template Toolkit.
    • Short of an alternate approach, this means no org-unit template overrides (like the TPAC and AngularJS has).
  • Use Angular i18n (again, no TT2)
  • Copy key services and components to Angular app
  • App look and feel should match AngularJS UI
    • Make it as seamless as possible to staff, documentation, etc.
  • App shares data with AngularJS app via local/sessionStorage, cookies, etc.
  • App navbar, etc. links point back to the AngularJS version of each interface.
  • As interfaces are moved from AngularJS to Angular, links in the AngularJS app are updated to refer to the Angular version.
  • Dojo and iframe-based interfaces are migrated to Angular first.

Migration Timeline Proposal

  • 3.2 Core services ported to Angular and navbar synchronized.
    • Unit tests for all core services included.
    • First batch of Dojo/iframe UIs migrated.
    • Code merged to EG for 3.2 release
  • 3.3
  • 3.4 More Dojo UI's migrated.
  • 3.5 Dojo UI's fully migrated. First batch of AngularJS UI's ported.
    • Remaining Dojo UIs:
      • Acquisitions (remaining work)
      • Booking
        • Capture Resources
      • Circulation
        • Patron record: triggered events
      • Cataloging
        • MARC Batch Edit
        • Link Checker
        • Manage Authorities
      • Admin
  • 3.6 More AngularJS UI's ported.
  • 3.7 AngularJS migration completed.
  • 3.8 (4.0?) Remove AngularJS

Evergreen Angular Proof-of-Concept (and more) code


  • Significant progress toward porting core services
  • Significant progress toward porting core services unit tests
  • Grid mostly ported
  • Fieldmapper Editor ported
  • UI's ported
    • Login
    • Workstation Admin
    • Server admin splash page
    • Billing Type Admin (under Server Admin)
    • Hard Due Date Admin (under Server Admin)
    • Nascent staff Angular catalog




  • Ported support for server-stored settings values. (bug 1750894)


A pile of new stuff since the last update. The biggest is locale-switching support. I opted for path-based locale handling (/eg2/fr-CA/, /eg2/en-US/, etc.) since it's very convenient. I've also added support for the eg_locale cookie used by the angularjs client and the tpac. If the cookie is present, it overrides the path. Similarly, if no locale is present in the path and no cookie is provided, it will default to /en-US/. The locale need not be included in the URL if you want the server to figure it out. Most importantly, links from the angularjs app to the ang6 app will just work.

Other additions:

  • Typeahead / combobox supporting static and on-demand (server) data.
  • Grid row/cell CSS callbacks
  • Minimal tree widget (initially created for managing vandelay match sets)
  • Use of display fields in the staff catalog (and other improvements/features).


After much experimentation, it's clear there's no way to implement dynamic rendering (from run-time generated html strings) in production mode in an Angular-compatible way. This is intentional by the angular team. Here's a comment that summarizes the situation:

Basically, JIT is "developer mode", shipping the extra compiler bits to the browser is bulky, and above all, it's a huge security risk to render dynamically generated html (more so html modified in the field by staff). And of course they're not wrong.

Brainstorming for alternate ways to allow sites to easily modify print templates under way…

One option of course are well documented stock templates with lots of knobs and switches for controlling how receipts, etc. are generated. Other options are server-generated receipts (speed concerns, offline printing?).


Continuation from yesterday's notes about dynamic rendering.

I've set up a PoC where the main app is built with –prod and –aot for optimization, and a second tiny app is built without –aot (or –prod which requires –aot). The second app contains a single DynamicComponent class exported as an Angular Element, so the main app can import it and use it for dynamic rendering.

It works well, but comes at a cost.

  • Main app alone compiled with –aot –prod is 336KB download size.
  • Main app with –aot plus secondary dynamic app is 949KB download size.
  • Main app without –aot (and no secondary app) is 938 KB

So we can have targeted dynamic rendering, with a quick pre-compiled main application, but it almost triples the download size. In affect, we are including 2 copies of Angular and its dependencies to accomplish this. It also adds a little bit of build-time complexity.;a=shortlog;h=refs/heads/collab/berick/lp1775466-ang6-base-app-plus-dynamic-mod


  • Added support for rendering dynamic HTML content from a string or URL. This will be useful for loading print templates dynamically and it opens the door for server-hosted template fall through for local customization.

Here's an example of how server-hosted overrides could work:

<div *ngIf="renderLocal">                                                      
  <b>fall through local template: hello {{world}}</b>                          

If eg-dynamic-content fails to fetch and render the requested URL, it reports the results via onComplete. When it fails, it sets renderLocal to true, allowing the stock template to render.

UPDATE: The above code only works when the application is compiled with the JIT compiler. After much digging, it appears dynamic complilation is not possible when using the AOT compiler. (The AOT compiler is preferred for production because it creates code that renders faster in the browser / requires less cpu at render time).

In the context of a public catalog, we could potentially build it as a separate app (we'll likely do that anyway) that can optionally use the JIT compiler for dynamic content.

Considering other options for dynamic print templates…

UPDATE2: A possible option would be to create a separate angular app with one component that knows how to render dynamic content. This app will be complied via JIT and packaged as a standalone Angular Element. It could then be imported into the main app by loading its js bundle. In theory, that would allow the main app to be compiled with AOT. Angular Elements are new, though, and it sounds like they will be much improved in Angular7.


  • Acquisitions admin splash page added.
  • All links point to Angular admin pages, except for the Funds page which will require additional development to add the year filter and rollover stuff.


  • Removed Eg prefix from most shared classes/service since it's unnecessary with imports and it's clunky.
  • We now have 42 auto-generated server admin UI's. That's all the admin UI's that only require a grid an maybe an org filter. Other UIs (e.g. org tree) will require custom code.


  • More admin UI automation
  • We now have 42 server admin UI's loading in the Angular6 app. These are all basic admin pages that don't require any special handling – e.g. building trees of data – stuff that can just be managed with a grid, add/delete actions, and optionally an org unit filter.


  • Created an EgAdminPageComponent for generic IDL object CRUD management. We now have admin pages for billing types, hard due dates, and sms carriers.
  • Using the new admin page component, the sms carrier page admin page is a whopping 10 lines of code.
  • All existing code is now ng-lint compliant.


Unit Tests

  • Added first unit tests for core services (idl, org, event).
  • Unit test syntax is practically identical, some minor variation in setting up the tests and using TS.
  • Unit tests live in *.spec.ts files (e.g. org.spec.ts) right beside the tested code (e.g. org.service.ts)

ng lint

  • Discovered 'ng lint'. Running it on the code base shows a bunch of warnings. Slowly cleaning those up. One useful warning in particular is how various 'rxjs' libs are imported. Generic imports (import {blah} from 'rxjs') imports way too much code. So I'm making those more specific (e.g. import {map} from 'rxjs/operators/map').
dev/browser_staff/angjs_to_ang_migration.txt · Last modified: 2022/02/10 13:34 by

Except where otherwise noted, content on this wiki is licensed under the following license: CC Attribution-Share Alike 4.0 International
CC Attribution-Share Alike 4.0 International Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki

© 2008-2022 GPLS and others. Evergreen is open source software, freely licensed under GNU GPLv2 or later.
The Evergreen Project is a U.S. 501(c)3 non-profit organization.