Transitioning to a mixed Angular and AngularJS application: encountering TypeScript and AngularJS module import issues

Our team is currently working on migrating an AngularJS application to Angular, using a gradual approach. Our goal is to create new components in Angular and upgrade existing AngularJS components one by one while ensuring that the application remains functional throughout the process.

We are following the guidance provided in the official documentation and various articles discussing hybrid Angular/AngularJS applications in real-world scenarios.

Below are our initial attempts along with the challenges faced:

Context

  • AngularJS 1.7.3
  • Angular 6.1.7
  • Typescript 2.7.2
  • angular-cli

First steps

  • Upgraded to AngularJS 1.7
  • Transitioned from Grunt to angular-cli
  • Utilized ngUpgrade (app.module.ts and app.module.ajs.ts)

Migrating to Typescript: Addressing Errors

The recommended process involved renaming .js files to .ts and shifting from Node require() to TypeScript module loading (var ... = require --> import ... = require). While correcting typing errors due to TypeScript compiler was advised, we explored the possibility of incremental migration as suggested in the TypeScript documentation.

To facilitate this, we opted for the awesome-typescript-loader instead of tsc with options like transpileOnly and errorsAsWarnings. Although these options helped pass compilation, we encountered an issue where the compilation ran twice, causing build failure. Any insights on running only the first compilation?


Alternative Approach: Retaining .js Files, Importing, and Bootstrapping Errors

In an unconventional attempt at incremental migration, we kept the original .js files alongside new .ts files. This led to complications during compilation and application loading related to importing AngularJS and module management.

Understanding the intricacies of Typescript modules, specifically UMD modules, became critical as we navigated through issues arising from global variables and script-mode vs. module-mode usage across .js and .ts files.

Despite managing to compile and load the application without errors, we encountered a hurdle during AngularJS bootstrapping, resulting in an "Angular 1.x not loaded!" error. Could this be resolved by importing AngularJS in the TypeScript module format? Suggestions regarding angular.IAngularStatic and setAngularJSGlobal functions would be appreciated.

Additionally, clarifications on calling bootstrap() with [App] or ["App"] were sought, considering our limited experience in the migration process.


Configuration Files

angular.json

{ 
    // Configuration details here
}

tsconfig.json

{
    // Compiler options and configurations mentioned here
}

Answer №1

If you're encountering the angular 1.x not loaded error, have you made sure to properly install AngularJS in your new application?

$ npm install --save <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="27464940524b4655671609100914">[email protected]</a> \
      @types/angular

Within your angular.json file, be sure to include the necessary script:

"scripts": [
    "../node_modules/angular/angular.js",
    //etc...
],

For guidance on how to upgrade an application that appears to be similar to yours, check out this example.

Alternatively, you can add Angular to the import chain by importing it in main.ts:

import * as angular from 'angular';

This approach may be preferable as it ensures that Angular CLI / webpack is aware of AngularJS, potentially avoiding errors like "

WARNING: Tried to Load Angular More Than Once
" that could occur if another component (such as the hybrid router) also imports Angular.

Answer №2

Our team successfully verified that the solution works as intended, allowing us to operate our application in a hybrid mode. Utilizing AngularJs, we incorporated grunt and browserify for bundling, leveraging the package.json browser field to package certain libraries. To replicate this setup, we needed to specify the libraries that should be loaded in the browser within the

angular.js / build.options.scripts
section:

"scripts": [
    "./node_modules/jquery/dist/jquery.js",
    "./node_modules/jquery-ui-dist/jquery-ui.js",
    "./node_modules/moment/moment.js",
    "./node_modules/bootstrap/dist/js/bootstrap.js",
    "./node_modules/eonasdan-bootstrap-datetimepicker/src/js/bootstrap-datetimepicker.js",
    "./node_modules/bootstrap-tour/build/js/bootstrap-tour.js",
    "./node_modules/angular/angular.js",
    "./node_modules/ng-table/bundles/ng-table.js"
]

We greatly appreciate your assistance.

This information could potentially enrich the Angular documentation. It's worth noting that the examples provided in https://angular.io/guide/upgrade#bootstrapping-hybrid-applications are centered around SystemJS, while our approach relies on Webpack (which is already integrated with Angular).

As highlighted in this issue regarding Angular documentation, the migration guide has yet to be updated for angular-cli, hence emphasizing SystemJS compatibility.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The latest version of React (v2.20.2) with TypeScript is encountering issues when trying to display a component containing `<Navigate to="/login"/>`

import { createBrowserRouter, createRoutesFromElements, Route } from 'react-router-dom'; import ErrorBoundary from './ErrorBoundary'; // Bringing in the ErrorBoundary component import Login from './Login'; // Getting the Login ...

Secure access with Express/Node.js in the mobile app powered by Appgyver Supersonic

I find myself facing a bright shine of ignorance on this particular issue. The Web App I am working on utilizes the MEAN stack - Mongo, Express, Angularjs, Nodejs. However, I have noticed that some functionalities are not as optimal on mobile devices. As a ...

Displaying the standard index.html page when implementing Angular HTML5mode with Servicestack on the server side

I am brand new to ServiceStack and Angular, so I apologize if this explanation is a bit lengthy. After reading up on the topic at this Stack Overflow post, I'm hoping to configure my api service to be accessible from the root of my domain - in other ...

Revisiting Angular: The Curious Case of an Object Attribute Altering Attributes on Two Separate Objects

Creating a website with Angularjs involves working with an array of objects: $scope.fieldsToShow = [ { "fields": {}, "type": "LOGGED_IN" }, { "fields": {}, "type": "PERSONAL", "user": 2, "name": ...

Verify the dates in various formats

I need to create a function that compares two different models. One model is from the initial state of a form, retrieved from a backend service as a date object. The other model is after conversion in the front end. function findDateDifferences(obj1, ...

Is there a way to automatically populate an AngularJS input field?

Attempting to automate filling out a website using JavaScript. The script below: document.getElementsByClassName('form-control')[1].value = "MYNAME"; The input text changes, but upon clicking the submit button it displays as empty. Any as ...

Trigger the rowContextMenu in Tabulator Table by clicking a Button

Is there a way to add a button at the end of a table that, when clicked, opens a rowContextMenu below the button? Additionally, can the rowContextMenu pop up when right-clicking anywhere on the row? I have attempted some solutions without success. Here is ...

Angular 2 integration for Oauth 2 popup authorization

I am in the process of updating an existing Angular application to utilize Angular 2. One challenge I am facing is opening an OAuth flow in a new pop-up window and then using window.postMessage to send a signal back to the Angular 2 app once the OAuth proc ...

How can I generate pure JavaScript, without using Typescript modules?

Take this scenario as an example ... index.ts import { x } from "./other-funcs"; function y() { alert("test"); } x(y); other-funcs.ts import { z } from "some-module"; export function x(callback: () => void): void { z(); callback(); } ...

Dispensing guarantees with Protractor

q library offers a unique feature that allows resolving and spreading multiple promises into separate arguments: If you have a promise for an array, you can utilize spread instead of then. The spread function distributes the values as arguments in the f ...

What are the best practices for organizing data in a view using AngularJS?

I have an <input type="text" ng-model="user.User.DateOfBirth"> in my view. The user.User.DateOfBirth is currently in YYYYMMDD format, but I would like it to display as mm/dd/yyyy format on the view. Is there a way to convert this format just for th ...

Having trouble with tooltips in an Angular 11 project after updating to Bootstrap 5

Encountering an issue with displaying HTML content using Bootstrap popover and tooltip. <button type="button" data-bs-toggle="popover" data-bs-html="true" data-bs-content= {{item.HtmlDescription}} title={{item.HtmlDescrip ...

What is the process of determining if two tuples are equal in Typescript?

When comparing two tuples with equal values, it may be surprising to find that the result is false. Here's an example: ➜ algo-ts git:(master) ✗ ts-node > const expected: [number, number] = [4, 4]; undefined > const actual: [number, number] ...

Can anyone provide guidance on incorporating jQuery typing into an angular2 seed project?

I'm struggling to incorporate jQuery typings into my Angular2-seed project. Within my component, I am utilizing jQuery in the following manner: declare let $: any; export class LeafletComponent implements OnInit { ngOnInit(): void { th ...

Sending data between a Grandchild component and its Parent component

In my Angular 8 project, I have multiple components structured in the following way: Parent 1 > Child 1 > ... > N Grandchild 1 Parent 2 > Child 2 > ... > N Grandchild 2 There might be other components between Child X and N Grandchild ...

Load a React component in the same spot when clicked

Is there a way to implement a functionality where clicking on different buttons in a panel will display different components in the same location? <AddNotification /> <EditNotification /> <DeleteNotification /> const AdminPanel = () =& ...

Unique: "Unique One-Step Deviation in Date Comparison"

A Little Background Information: I am working with data points that span from the current day to 5 days ahead, in 3-hour intervals (such as 10pm, 1am, 4am, 7am...). My goal is to organize these data points into arrays sorted by date, with each array repre ...

The specified type '{ data: any; }' is incompatible with the type 'IntrinsicAttributes'. The property 'data' is not found in the type 'IntrinsicAttributes'

I'm encountering issues with the data property. interface Props { params: { slug: string }; } const Page = async ({ params }: Props) => { const data: any = await getPage(params.slug); // This section dynamically renders the appropriate orga ...

Unable to configure Angular 2 tour of champions tutorial

When I accessed the Hero Editor page (https://angular.io/docs/ts/latest/tutorial/toh-pt1.html), I followed the given instructions: “Follow the setup instructions for creating a new project named angular-tour-of-heroes, after which the file structure sho ...

The Issue with NG-Zorro Datepicker Manual Input Mask Functionality未分类

Is there a way to mask the datepicker so that users can enter dates in the format MM/dd/yyyy without typing the "/" character manually? I've tried using ngx-mask but it doesn't seem to work for the datepicker component. I have provided a link to ...