Issue with defining controllers in AngularJS 1.3.0 using TypeScript

Our application utilizes the "controller as" syntax for AngularJS:

<div class="workspace-header" ng-controller="LoginController as loginCtl">

The LoginController is defined as a TypeScript class like so:

class LoginController {
    // variables here

    constructor($rootScope, $http, $location, $cookieStore, AuthService, AUTH_EVENTS, localStorageService) {
        // set variables
        
        this.$rootScope.$on(AUTH_EVENTS.logoutSuccess, () => {
            this.logout();
        });
    }

    public login(credentials: any): void {
        this.AuthService.login(credentials).then(() => {
            // login success
        }, () => {
            // login failed
        });
    }

    public logout() {

    }
}

To instantiate it, we use the following approach:

.controller('LoginController', ['$rootScope', '$http', '$location', '$cookieStore', 'AuthService', 'AUTH_EVENTS', 'localStorageService',
    ($rootScope, $http, $location, $cookieStore, AuthService, AUTH_EVENTS, localStorageService) =>
        new LoginController($rootScope, $http, $location, $cookieStore, AuthService, AUTH_EVENTS, localStorageService);
])

However, after upgrading to AngularJS 1.3.0, there are issues with the "controller as" syntax not functioning properly. When attempting to call loginCtl.login(), nothing happens and no errors are shown in the console.

Upon investigation, it seems that a breaking change in AngularJS might be causing this issue:

https://github.com/angular/angular.js/issues/8876 https://github.com/angular/angular.js/pull/8882 (added note to documentation)

A possible solution involves modifying the controller definition as follows:

.controller('LoginController', ['$rootScope', '$http', '$location', '$cookieStore', 'AuthService', 'AUTH_EVENTS', 'localStorageService',
    function ($rootScope, $http, $location, $cookieStore, AuthService, AUTH_EVENTS, localStorageService) {
        var loginCtrl = new LoginController($rootScope, $http, $location, $cookieStore, AuthService, AUTH_EVENTS, localStorageService);

        // extend 'this' with the properties of the controller
        _.extend(this, loginCtrl);
        _.extend(this, loginCtrl["__proto__"]);
    }
])

If anyone else has encountered this issue or has a cleaner approach for defining classes in TypeScript, we would appreciate your insights.

Answer №1

According to PSL, the issue lies in the following code:

.controller('LoginController', ['$rootScope', '$http', '$location', '$cookieStore', 'AuthService', 'AUTH_EVENTS', 'localStorageService',
    ($rootScope, $http, $location, $cookieStore, AuthService, AUTH_EVENTS, localStorageService) =>
        new LoginController($rootScope, $http, $location, $cookieStore, AuthService, AUTH_EVENTS, localStorageService);
])

Rather than using the lengthy arrow function, you can simply replace it with LoginController.

Refer to this comment in the linked issue for clarification on why returning an object is incorrect and how the function should be compatible with the use of the new operator.

Answer №2

PSL mentioned using $inject... I had a similar question that I asked on Stack Overflow about Angular 1.3 breaking changes

You can find my answer here: My Plunker code

//additional dependencies removed for simplicity
.controller('LoginController', ['$scope', LoginController]);
LoginController.$inject = ['$scope'];

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

How can I showcase array elements using checkboxes in an Ionic framework?

Having a simple issue where I am fetching data from firebase into an array list and need to display it with checkboxes. Can you assist me in this? The 'tasks' array fetched from firebase is available, just looking to show it within checkboxes. Th ...

Summernote information embedded with HTML elements

I just started using the summernote text editor and I'm trying to figure out how to extract the content from the textarea without all the HTML tags. This is what I have in my code: <textarea class="summernote" id="summernote" ng-model="blog.c ...

Having trouble getting a constructor to function properly when passing a parameter in

Here's the code snippet I'm working with: import {Component, OnInit} from '@angular/core'; import {FirebaseListObservable, FirebaseObjectObservable, AngularFireDatabase} from 'angularfire2/database-deprecated'; import {Item} ...

Mock a single method within an Angular service

Within my Angular service, I have a method that listens for state changes and returns an observable. However, other methods within the same service handle transformation logic: ngOnInit() { this.isLoading = true; this.myService.stateListener().sub ...

Showing Arrays in Angular on HTML Page

I have created an array that stores multiple arrays with 3 indexes each. An example of the structure looks like this: (3) [Array(3), Array(3), Array(3)] 0: (3) [199.4, 10.5, 19] 1: (3) [47.2, 2.1, 23] 2: (3) [133.6, 5.3, 25] In my HTML, I want to display ...

The challenge of optimizing Angular websites for SEO while also addressing page reload issues

I am struggling to create SEO-friendly URLs in my Node server backend. I want URLs like the following: http://localhost:3003/my-new-mobile //product http://localhost:3003/my-new-category //category http://localhost:3003/my-first-blog-post // blog post I ...

Utilize the index of a for loop to manipulate an Angular string

When working with different objects and creating forms simultaneously, I've come across a challenge. My initial idea for handling the submission was to use the following code: <form (ngSubmit)="submitForm{{u}}()"> However, incorporating the in ...

Displaying a Div element containing dynamically calculated values based on selected options in Angular

As a newcomer to Angular, I decided to challenge myself by building a simple app. Currently, my select options only display the keys of a data object. What I really want to achieve is to show a value beneath the second select box for each team, which displ ...

When you find that the plugins on pub.dev do not offer web support, consider utilizing npm packages for Flutter web development

I am currently working on developing a cross-platform app using Flutter for iOS, Android, and web. However, some plugins do not support web. Fortunately, I came across npm packages that provide the same functionality and I am considering integrating them. ...

Data is successfully being stored in an array in AngularJS, however, it is not appearing in the user interface

Having an issue with displaying updated data on my UI. I am successfully pushing data into the database and an array using Angular 2-way binding. The data is being pushed as confirmed by the console, but it's not showing up on the user interface. Con ...

Unable to pass a parameter through an Angular http.get request

I've encountered an issue where I am attempting to pass the page number and page size values to a web API, but for some reason, no parameters are being passed. I have thoroughly debugged the application in VS Code, and verified that the pagingModel ob ...

Guide on transforming observable<User> to Observable<boolean> in Angular 4

As a newcomer in Angular and Mean Stack, I need help implementing the canActivate() method to restrict admin routes. In my service file, the checkAdmin method returns an observable of type "User", but the canActivate method's return type is an observa ...

Modifying the value of a date picker input using an Angular button

I have an input field with an attached Angular UI datepicker, and I have also added two buttons below to change the date "day by day". Here is the input section on my page: <p class="input-group"> <span class="input-group-addon hidden-xs"> ...

Transitioning from pop-up modals to AngularJS JSON

I have a table with fields such as: product, lot, input1, input2. It is possible to clone a line or add a new line. The selection of the Product is based on a value from JSON data. The Lot selection initially stays empty and gets filled with sub-arrays rel ...

Adding data to a pre-made JavaScript file template to create a fresh document

In my web application, I have a form with multiple inputs: <form action=""> Title1:<br> <input type="text" name="title1"> <input type="text" name="title1Description"> <br> Title2:<br> <input t ...

Guide to configuring the active Tab in Angular 6 using Angular Material Design

I've searched high and low for a solution to this issue, but I haven't been able to find one. In a particular component, I have a material tab control. However, the active tab doesn't display until I click on one of the tabs on the page. a ...

"Communication + AngularJS + Social Networking - The Perfect Trio

I'm currently in the process of developing an Angular app that will eventually be compiled using PhoneGap for both Android and iOS platforms. While testing various plugins to incorporate Facebook integration (specifically for login and sharing), I enc ...

Modify the selected toggle buttons' color by utilizing the MUI ThemeProvider

I am currently working on customizing the color of selected toggle buttons within my React app using TypeScript and ThemeProvider from @mui/material 5.11.13. Despite my efforts, when a toggle button is selected, it still retains the default color #1976d2, ...

Sorting by Date in JavaScript

My goal is to filter out the elements in an array that have a date (converted from string) greater than a specific date. _this.downloadData.forEach(_d => _d.LogTime = _d.LogTime.toString()); console.log(_this.downloadData.filter(x=>new Date(x.LogTi ...

Having two ng-click events and two distinct classes in an ng-repeat based on the selected option

There are two buttons in my code that should remove a div within an ng-repeat loop. Depending on which button is clicked, a custom CSS class should be added to the effect. The CSS changes based on the option selected. When I click on a button, either &apo ...