Can you define the type of binding value in AngularJS 1.5(6) using TypeScript?

I am looking to define the type of binding items so that I am able to utilize components similar to functions.

For instance, consider a component:

angular.module('app').component('navBar', new NavBar());

 class NavBar{
    public bindings:{};
    constructor(){
        this.bindings={ 
            navInfo:'<'
        }
    }
}

The expected data structure is as follows:

export interface INavInfo {
    text: string;
    icon: string;
    OnClick: Function;
}

In order to avoid any errors, I need to pass in data like this:

{
  text: 'Maintenance',
  icon: 'assessment',
  OnClick: () => {....}
}

Is there a way to enforce that only objects with the structure defined in INavInfo can be passed into navInfo?

Answer №1

Your code isn't clear on where you want TypeScript compilation to fail. It seems related to how you pass the navInfo information.

Check out the example of using heroes in Angular components from the official documentation: https://docs.angularjs.org/guide/component

In the example, data is passed to components in the index.js file:

angular.module('heroApp', []).controller('MainCtrl', function MainCtrl() {
    this.hero = {
    name: 'Spawn'
  };
});

To ensure correct data passing in your component with TypeScript, mark the this.hero variable as type INavInfo in your TS controller:

private hero: INavInfo;

If someone forgets to use this specific type in another controller but uses the same component, TypeScript compilation won't show errors. On the flip side, if everyone correctly declares INavInfo wherever the component is used, any changes to properties will cause errors where needed.

Answer №2

Assuming the question is about navInfo being a part of component bindings declaration and you want to...

<nav-bar navInfo="vm.navInfo"></nav-bar>

in the view
and have "vm.navInfo" checked against INavInfo.

The answer is no.

Since you will be instantiating your component within an HTML view, and currently there is no tool that supports type-checking TypeScript in HTML markup. Angular also does not provide type binding characteristics, only the 'key' for binding and its behavior, as it is an Angular convention rather than a language feature.

Even if you create your component with inline HTML code all in one file within Webstorm, which is very Angular 1.x friendly,

You could consider adding run-time checking (although it may not be advisable).

import * as angular from "angular";

export interface INavInfo {
    text: string;
    icon: string;
    OnClick: Function;
}

function isNavInfo(x: any): x is INavInfo {
    return x && typeof x.text === "string"
        && typeof x.icon === "string"
        && typeof x.OnClick === "function";
}

class NavBar implements angular.IController {

    navInfo?: INavInfo;

    $onInit = () => {

    };

    $onChanges? = (onChangesObj: angular.IOnChangesObject) => {
        if (this.navInfo && !isNavInfo(this.navInfo)) {
            throw "Nav Info is Not NavInfo";
        }
    };

    clicked = ()=> {
        if(this.navInfo && this.navInfo.OnClick){
            this.navInfo.OnClick();
        }
    }
}

class OtherController {
    navInfo: INavInfo ;
    constructor(){
        this.navInfo = {
            text: "Hello",
            icon: "home",
            OnClick: ()=>{
                console.log("link clicked!")
            }
        };
    }
} 

angular.module('NavBarTest', [])
    .component(
        'navBar', {
            template: `<!-- there's No Type Checking here -->
                        <ul>
                            <li>
                                <a class="navText" href="" ng-click="$ctrl.clicked">
                                {{$ctrl.navInfo.text}}
                                <i class="naIvIcon">{{$ctrl.navInfo.icon}}</i>
                                </a>                        
                            </li>
                       </ul>>`,
            bindings: {
                navInfo: '<'
            },
            controller: NavBar,
            // controllerAs: '$ctrl'
        }
    )
    .component("navBarUser", {
        template: ` <!-- there's No Type Checking here -->
            <nav-bar nav-info="$ctrl.navInfo" ></nav-bar>
        `,
        controller: OtherController,
        // controllerAs: '$ctrl'
    });

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

Using TypeScript's `extend` keyword triggers an ESLint error when attempting to extend a generic type

I am dealing with numerous models that include additional meta data, which led me to create a generic type for appending them to the models when necessary: type WithMeta<T> = T extends Meta; However, I encountered an error stating: Parsing error: &a ...

Forwarding refs in React FC allows you to easily pass down

I have encountered an issue with references - I am trying to reference a function component and pass props to it. Currently, I have my Parent component and Child Component set up. In the parent component, I need to use a ref to access my child component. S ...

Endpoint path for reverse matching in Mongodb API

I am currently in the process of setting up a webhook system that allows users to connect to any method on my express server by specifying a method and an endpoint to listen to (for example PUT /movies/*). This setup will then send the updated movie to the ...

Adjust the size of a map on an HTML page after it has

Currently, I am utilizing Angular 2 to create a simple webpage that includes a Google 'my map' displayed within a modal. <iframe id="map" class="center" src="https://www.google.com/maps/d/u/0/embed?mid=1uReFxtB4ZhFSwVtD8vQ7L3qKpetdMElh&ll ...

Prevent click events on disabled tabs in PrimeNG tabMenu

I am encountering an issue with PrimeNG's p-tabMenu when it comes to disabled menu items. For example, suppose I have a tabMenu with 4 sub tabs labeled AAA, BBB, CCC, and DDD. This is how the menuItems are set up in the TypeScript component: //.... ...

Filter out all elements in an array except for one from a JSON response using Angular 2

After receiving a JSON response from a server via HTTP GET, the data structure looks like this: { searchType: "search_1", overview: [ "Bed", "BedSheets", "BedLinen", .. ...

Console.log is displaying array as [object Object] when utilizing Typescript

When working with an object in typescript called "obj," I encountered a strange behavior. Initially, when I ran the console.log(obj); command, the output in the terminal console was displayed as [object Object]. However, after wrapping it in JSON.stringify ...

Angular's ng-select fails to select the value when generating the dynamic control

Currently, I am working on dynamically adding cities using ng-select in order to have search functionality while entering city names. For example, if I have two city names saved in a form and need to display them in separate ng-select controls when editing ...

Using AngularJS to update attributes in an HTML tag within a string

My string contains HTML tags : var str = "<div><p></p><p><i>blabla</i></p><p><i><b>blaaaaaablaaaaa</b></i></p><iframe src='urlAAA' height='400' width=&ap ...

The server in Angular 4 does not pause for the http call to finish before rendering. This can result in faster loading

After implementing angular universal, I was able to render the static part of HTML via server-side rendering. However, I encountered an issue where API calls were being made and the server rendered the HTML without waiting for the HTTP call to complete. As ...

Monitoring an Angular form for changes in its $dirty state can provide valuable insights into performance

I have a question about my Angular application. I am dynamically setting placeholders in my form based on the time of day using code inside the controller. Is there a way to clear all placeholders when a user starts typing into any field of the form? I h ...

What is the best way to call an Angular component function from a global function, ensuring compatibility with IE11?

Currently, I am facing a challenge while integrating the Mastercard payment gateway api into an Angular-based application. The api requires a callback for success and error handling, which is passed through the data-error and data-success attributes of the ...

ng-repeat dysregulating the binding of directive models

<input-directive model="config.shared.product.whatevers[0]"></input-directive> <!-- This code is functioning correctly, however the following does not bind properly --> <td ng-repeat="whatever in config.shared.product.whatevers trac ...

How to assign a specific class to the previous item in an ng-repeat loop within a

Below is a prime example of a reusable progress bar that utilizes ng-repeat and directives. Check out the Plunker In my current setup, I use the class .progressBar__isActive for the active page or index. What I now want to achieve is adding the progressB ...

The revalidation process in react-hook-form doesn't seem to initiate

Stumbled upon a code example here Decided to fork a sandbox version (original had bugs and errors) I am trying to implement custom validation callbacks for each form input element by providing options in the register function, but the validate is only tr ...

The legends on the Google chart are having trouble being displayed accurately

Take a look at the screenshot below to pinpoint the sample issue. While loading the graph UI with Google Charts, the legends data is showing up but not appearing correctly. This problem seems to occur more frequently on desktops than on laptops. Any advi ...

IE9 causing issues with Angularjs ng-route - views fail to display

I am new to AngularJS and currently working on developing an application using AngularJS along with Coldfusion for database data retrieval. However, I am facing compatibility issues specifically with IE9 (which is the default browser in my office). The ap ...

Can you explain the significance of setting scope:true in an AngularJS directive?

When scope:false is used, it indicates that the directive will not have its own scope. If scope:{something}, an isolated scope will be created for the directive. But what does scope:true mean? And more importantly, why is it useful? Thank you! ...

How can one pass a generic tuple as an argument and then return a generic that holds the specific types within the tuple?

With typescript 4 now released, I was hoping things would be easier but I still haven't figured out how to achieve this. My goal is to create a function that accepts a tuple containing a specific Generic and returns a Generic containing the values. i ...

Configuring IIS Rewrite can be easily achieved by following these simple

My project utilizes PHP and Angular, hosted on IIS. I have enabled the html5Mode in Angular, allowing me to use routes like localhost/home instead of locahost/#/home. The issue arises when I copy and paste the URL (for example: http://localhost/home) into ...