Angular TypeScript state management system

I am facing a challenge in connecting a controller to a state (using angular ui.router) where one way of writing it works, while the other does not.

Successful example (with the controller registered under the module):

this.$stateProvider
  .state('items', {
    url: '/{cluster}/items',
    templateUrl: App.mapPath('Items/Items.html'),
    controller: 'ItemsController as controller'
   });

However, this approach fails (when using an 'anonymous' controller):

this.$stateProvider
  .state('items', {
    url: '/{cluster}/items',
    templateUrl: App.mapPath('Items/Items.html'),
    controller: ItemsController,
    controllerAs: 'controller'
  });

It is important to note that my controller has dependencies:

export class ItemsController {
  static $inject = ['$scope', 'itemsResource', '$stateParams'];
  constructor(
    scope: IItemsScope,
    itemsFactory: IItemsResource,
    stateParams: IClustersStateParams) {
     scope.items = itemsFactory.query({ cluster: stateParams.cluster });
   }

  public newItem(): void {
    console.log('test');
  }
}

The template for my Items.html looks like:

<div class="items">
  <ul class="add">
    <li>
      <action icon-style="glyphicon-plus" text="Add new item" activated="controller.newItem()"></action>
    </li>
  </ul>
  <ul>
    <li ng-repeat="item in items">
      <item item="item"></item>
    </li>
  </ul>
  </div>

Also, there is an action directive involved:

export class ActionDirective implements ng.IDirective {
  restrict = 'E';
  replace = true;
  template = '<a class="action"><span class="glyphicon {{iconStyle}}" aria-hidden="true"></span><span>{{text}}</span></a>';
  scope = {
    iconStyle: '@iconStyle',
    text: '@text',
    activated: '&'
  };

  public link(scope: IActionDirectiveScope, instanceElement: ng.IAugmentedJQuery, instanceAttributes: ng.IAttributes, controller: any): void
  {
    instanceElement.on('click', (): void => {
    scope.activated();
    });
  }

public static factory(): ng.IDirectiveFactory {
  const directive = () => new ActionDirective();

  return directive;
}

The main issue lies in the controller.newItem() call. It functions correctly in the working example but fails to display anything in the console otherwise. Furthermore, the items array (initialized in the controller's constructor) always gets populated regardless of the method used, indicating that the problem solely rests on calling controller.newItem()...

Answer №1

Make sure to pass the controller as a STRING name:

this.$stateProvider
  .state('items', {
    url: '/{cluster}/items',
    templateUrl: App.mapPath('Items/Items.html'),
    //controller: ItemsController,
    controller: "ItemsController",
    controllerAs: 'controller'
  })

You can find more information in the documentation here.

controller: Controller fn that should be associated with newly related scope or the name of a registered controller if passed as a string. Optionally, the ControllerAs may be declared here.

Alternatively, you can just pass the constructor function (class name) as well.

For a functional example, visit this link.

I have placed the controller into the namespace:

namespace MyModule{
 export class ItemsController {
  static $inject = ['$scope', 'itemsResource', '$stateParams'];
  constructor(
    scope: IItemsScope,
    itemsFactory: IItemsResource,
    stateParams: IClustersStateParams) {
     scope.items = itemsFactory.query({ cluster: stateParams.cluster });
   }

  public newItem(): void {
    console.log('test');
  }
 }
}

View the code here

And use this state definition:

.state('items', {
    url: '/{cluster}/items',
    //templateUrl: App.mapPath('Items/Items.html'),
    templateUrl: 'Items/Items.html',
    controller: MyModule.ItemsController, 
    controllerAs: 'controller'
})

Here is the view for Items/Items.html

<div class="items">
 ...
      <button icon-style="glyphicon-plus" text="Add new item" >xxx
 ..
</div>

A live demo can be viewed here

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

Error: passport-local-mongoose does not have a createStrategy or authenticate function

Currently, I am working on enhancing features of a starter project available at this repository. The specific task at hand involves integrating user login functionality using passport-local-mongoose. In my attempts to utilize different strategies for impl ...

Comparing dates in Angular 6 can be done by using a simple

Just starting with angular 6, I have a task of comparing two date inputs and finding the greatest one. input 1 : 2018-12-29T00:00:00 input 2 : Mon Dec 31 2018 00:00:00 GMT+0530 (India Standard Time) The input 1 is retrieved from MSSQL database and the in ...

How can I utilize generic types in Typescript/React when crafting a component with prop types?

I am facing an issue with a component that has a generic definition as shown below: export type CheckboxItem = { label: string, code: string, }; export type CheckboxesProps = { items: CheckboxItem[], handleStateChange: (selected: (CheckboxItem[&ap ...

Error: Module not found - Unable to locate 'dropzone'

Since migrating from Angular 4.4 to Angular 8.0, I encountered the following issue: ERROR in ./src/attributes/import/import.component.ts Module not found: Error: Can't resolve 'dropzone' in 'C:....\src\attributes\imp ...

Creating cohesive stories in Storybook with multiple components

I need assistance with my storybook setup. I have four different icon components and I want to create a single story for all of them instead of individual stories. In my AllIcons.stories.tsx file, I currently have the following: The issue I am facing is ...

"Enhancing Real-Time Communication in Angular with Websockets and $rootScope's Apply

Currently, I am experimenting with an Angular application that utilizes a websocket to interact with the backend. I've encountered some challenges in getting Angular's data binding to function correctly. In this scenario, I have developed a serv ...

I'm trying to figure out how to incorporate types for utilizing Intl.ListFormat in node v12. Can

I am currently working with nodeJS version 12.10.0, which now includes support for Intl.ListFormat. I am also using Typescript version 3.6.3. However, when compiling my code with Typescript, I encounter the following error: Property 'ListFormat' ...

Retrieving a property of an object within an array using JavaScript in AngularJS

Seeking advice on how to calculate the total price of products in an array when working within a callback function. Is there a method similar to myArray.(intheobject).price? Or is there a way to handle callbacks effectively to achieve accurate results? th ...

Observing changes to attributes in AngularJS is a useful feature that allows for

I am looking to update the attribute of an element by using its id and have the element respond to this change. After trying to showcase my situation in a plunkr, I encountered issues with even getting ng-click to function properly. My goal is to invoke ...

"Utilizing ReactJS and Typescript: A guide on initiating a Redux dispatch event through an axios

Looking for help with ReactJS typescript and redux dispatch events when calling APIs using axios interceptors? Check out my code snippet below. Codesandbax Repo App.tsx import "./App.css"; import "bootstrap/dist/css/bootstrap.min.css" ...

Unlocking the potential of a local mongoDB database in an Angular application without the need for a server - a truly client-side experience with the MAN stack

I have organized a mongoDB database with extensive data stored in multiple collections, all residing in a 'data' folder within the directory of my node app. I am now looking to develop a front-end interface for the database, including CRUD funct ...

Functionality similar to ngChange, but applied to the entire form

Is there a way to create an equivalent of the ng-change directive for the entire form, triggering when any input field changes? I am aware of the debounce option in AngularJS 1.3, but it only works for individual inputs. I need a "debounce" or "on change ...

Error TS2339: The 'selectpicker' property is not found on the 'JQuery<HTMLElement>' type

Recently, I integrated the amazing bootstrap-select Successfully imported bootstrap-select into my project with the following: <!-- Latest compiled and minified CSS --> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstra ...

What is the process for utilizing a Typescript Unit Test to test Typescript code within Visual Studio?

Currently, I am facing an issue while writing a unit test in Typescript to check a Typescript class. The problem arises when the test is executed as it is unable to recognize the class. To provide some context, my setup includes Typescript (1.4) with Node ...

Issue: Firebase.update was unsuccessful due to NaN being present in a property within the first argument

A project I'm working on involves creating a web app where users can nurture a virtual tree. One of the key interactions is when the user fertilizes the tree, the "fertilizer" attribute should increase. However, an error keeps popping up stating that ...

Linking a model using AngularJS' ng-click functionality

I am currently creating a compact RSS reader application using Express with Jade and Angular. The interface includes a dropdown menu populated by items from a model, each of which has an associated RSS feed URL that should trigger a specific factory functi ...

TS2688 Error: Type definition file for 'keyv' is missing

The automated code build process failed last night, even though I did not make any changes related to NPM libraries. The error message I received was: ERROR TS2688: Cannot find type definition file for 'keyv'. The file is in the program because: ...

What is the reason behind tsc (Typescript Compiler) disregarding RxJS imports?

I have successfully set up my Angular2 project using JSPM and SystemJS. I am attempting to import RxJS and a few operators in my boot.ts file, but for some reason, my import is not being transpiled into the final boot.js output. // boot.ts import {Observa ...

The issue of file uploading not functioning properly with AngularJS on a lighttpd server is causing frustration

Currently in my project, we are utilizing the lighttpd server. I am attempting to upload a file and encountering two Response Headers. The first has a 301 status code (Moved Permanently) and the second has a 200 status code (OK). However, upon checking th ...

The GIPHY API object returns no results

Utilizing Angular 2 to fetch data from the GIPHY API. export class ListaGifsComponent { gifs : Object[] = []; urlBase = "http://api.giphy.com/v1/gifs/search?q="; termoPesquisado = "ryan+gosling"; key = "O8RhkTXfiSPmSCHosPAnhO70pdnHUiWn"; ...