Using TypeScript with Angular-UI Modals

Currently, my goal is to create a modal using angular-ui-bootstrap combined with typescript. To begin, I referenced an example from this link (which originally utilizes jQuery) and proceeded to convert the jQuery code into typescript classes.

After successfully implementing the modal's opening functionality, I encountered issues where the items within the modal were not displaying properly, and the buttons were unresponsive for unknown reasons.

You can review the code snippet below or access the live example on this plunker.

index.html:

<!doctype html>
<html>
<head>
  <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.js"></script>
  <script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.12.1.js"></script>
  <script src="example.js"></script>
    <link href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div ng-app="ui.bootstrap.demo" ng-controller="ModalDemoCtrl as c">
    <script type="text/ng-template" id="myModalContent.html">
        <div>
            <div class="modal-header">
                <h3 class="modal-title">I'm a modal!</h3>
            </div>
            <div class="modal-body">
                <ul>
                    <li ng-repeat="item in i.items">
                        <a ng-click="setSelected(item)">{{item}}</a>
                    </li>
                </ul>
                Selected: <b>{{selected}}</b>
            </div>
            <div class="modal-footer">
                <button class="btn btn-primary" ng-click="ok()">OK</button>
                <button class="btn btn-warning" ng-click="cancel()">Cancel</button>
            </div>
        </div>
    </script>
    <button class="btn btn-default" ng-click="c.open()">Open me!</button>
    <div ng-show="c.getSelected()">Selection from a modal: {{c.getSelected()}}</div>
</div>
</body>
</html>

example.ts

angular
    .module('ui.bootstrap.demo', ['ui.bootstrap']);

class ModalDemoCtrl {

    private selected: string;

    static $inject = ['$modal'];
    constructor(private $modal: ng.ui.bootstrap.IModalService) {
    }

    getSelected(): string {
        return this.selected;
    }

    open(): void {
        var modalInstance: ng.ui.bootstrap.IModalServiceInstance = this.$modal.open({
            templateUrl: 'myModalContent.html',
            controller: 'ModalInstanceCtrl'
        });

        modalInstance.result.then(function (selectedItem) {
            this.selected = selectedItem;
        });
    };
}

angular
    .module('ui.bootstrap.demo')
    .controller('ModalDemoCtrl', ModalDemoCtrl);

class ModalInstanceCtrl {

    public items: string[] = ['item1', 'item2', 'item3'];
    public selected: string = this.items[0];

    static $inject = ['$modalInstance'];
    constructor(private $modalInstance: ng.ui.bootstrap.IModalServiceInstance) {
    }

    setSelected(item): void {
        this.selected = item;
    }

    ok(): void {
        this.$modalInstance.close(this.selected);
    };

    cancel(): void {
        this.$modalInstance.dismiss('cancel');
    };
}

angular
    .module('ui.bootstrap.demo')
    .controller('ModalInstanceCtrl', ModalInstanceCtrl);

Once I have resolved the issues and ensured that the code functions correctly, I plan to share it with others interested in similar implementations.

Thank you for your time and assistance!

Sincerely, Gonzalo

Answer №1

In case you are not using $scope, it is important to utilize the "bindToController" option. Check out this example with updated html and ts files.

 modalInstance.result.then(function (selectedItem) {
        this.selected = selectedItem;
    })

The correct syntax should be:

 modalInstance.result.then((selectedItem) => {
        this.selected = selectedItem;
    })

This ensures proper resolution of "this"

Answer №2

Thank you, Aleksey! Your modifications are spot on! I will be sharing the finalized and functioning code later today so that others can benefit from it as well.

UPDATE: Check out the final working code below :)

example.js

angular
.module("ui.bootstrap.demo", ["ui.bootstrap"]);

class ModalDemoCtrl {
    private selected: string;

    static $inject = ["$modal"];
    constructor(private $modal: ng.ui.bootstrap.IModalService) {
    }

    getSelected(): string {
        return this.selected;
    }

    open(): void {
        var modalInstance: ng.ui.bootstrap.IModalServiceInstance = this.$modal.open({
        templateUrl: "myModalContent.html",
        controller: "ModalInstanceCtrl",
        bindToController: true,
        controllerAs: "i",
    });

    modalInstance.result.then((selectedItem) => {
        this.selected = selectedItem;
    });
};
}

angular
.module("ui.bootstrap.demo")
.controller("ModalDemoCtrl", ModalDemoCtrl);

class ModalInstanceCtrl {
    public items: string[] = ["item1", "item2", "item3"];
    public selected: string = this.items[0];

    static $inject = ["$modalInstance"];
    constructor(private $modalInstance: ng.ui.bootstrap.IModalServiceInstance) {
    }

    setSelected(item): void {
        this.selected = item;
    }

    ok(): void {
        this.$modalInstance.close(this.selected);
    };

    cancel(): void {
        this.$modalInstance.dismiss("cancel");
    };
}

angular
    .module("ui.bootstrap.demo")
    .controller("ModalInstanceCtrl", ModalInstanceCtrl);

index.html

<!doctype html>
<html>
<head>
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.js"></script>
    <script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.12.1.js"></script>
    <script src="example.js"></script>
    <link href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div ng-app="ui.bootstrap.demo" ng-controller="ModalDemoCtrl as c">
    <script type="text/ng-template" id="myModalContent.html">
        <div>
            <div class="modal-header">
                <h3 class="modal-title">I'm a modal!</h3>
            </div>
            <div class="modal-body">
                <ul>
                    <li ng-repeat="item in i.items">
                        <a ng-click="i.setSelected(item)">{{item}}</a>
                    </li>
                </ul>
                Selected: <b>{{i.selected}}</b>
            </div>
            <div class="modal-footer">
                <button class="btn btn-primary" ng-click="i.ok()">OK</button>
                <button class="btn btn-warning" ng-click="i.cancel()">Cancel</button>
            </div>
        </div>
    </script>
    <button class="btn btn-default" ng-click="c.open()">Open me!</button>
    <div ng-show="c.getSelected()">Selection from a modal: {{c.getSelected()}}</div>
</div>
</body>
</html>

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

Retrieve JSON Data Using Angular in a Wordpress Environment

I need assistance with displaying a JSON Array in <li>'s within a Wordpress Template. Here is the specific JSON file: I am completely unfamiliar with how to achieve this. This is the HTML code I have: <div ng-app="appExtern" ng- ...

Customize the appearance of the Material UI expansion panel when it is in its expanded

Is there a way to customize the height of an expanded expansion panel summary? Specifically, I am looking to remove the min-height property and set the summary panel's height to 40px instead of the default 64px. I have attempted to make this change in ...

Converting milliseconds into a formatted DateTime using AngularJS: A step-by-step guide

Upon receiving JSON data from the server, I obtained a date-time in milliseconds: $scope.JDT = "1492499995056";. While I am able to display the scope variable 'JDT' on my view using a filter: {{JDT | date:"dd/MM/yyyy h:mm:ss a"}} ... I do not a ...

"Using TypeScript: How to effectively wait for the completion of the array.sort

Need to implement a loading screen in Angular until an array is sorted. Solution provided below: this.isSorting = true; this.array = this.array.sort((a,b) => a.totlaTime - b.totalTime); this.isSorting = false; The issue faced is when isSorting is set t ...

How can I create an efficient AngularJS application with minimal NPM dependencies?

Currently, as I develop my AngularJS app, I am utilizing npm to download all necessary JS dependencies. These dependencies are stored within the node_modules folder of my application, and everything is running smoothly. However, when it comes time to deli ...

Utilize puppeteer and web-vitals in NextJS to retrieve the web performance metrics of a website

I'm currently working on a basic tool in NextJS that uses puppeteer to fetch web vitals data from a given URL. However, I'm facing an issue where the results are not being printed out. What could be causing this problem? const browser = await pup ...

Is there a way for me to access the user's gender and birthday following their login using their Google account details?

I have successfully implemented a Google sign-in button in my Angular application following the example provided in Display the Sign In With Google button: <div id="g_id_onload" class="mt-3" data-client_id="XXXXXXXXXXXX-XX ...

Ensuring a boolean outcome from a promise function within AngularJS

When working with angularjs, I am attempting to determine whether the value isInternal is true or false based on a promise function. However, instead of getting the expected result, I am receiving another promise (Promise {$$state: Object} $$state : Object ...

What causes the Cassandra client driver to provide more detailed information compared to cqlsh?

I'm currently utilizing the datastax nodejs-driver to retrieve information about a keyspace from cassandra. const results = await client.execute( ` DESC KEYSPACE ${keyspace} ` ); The method client.execute provides a comprehensive object containin ...

Utilize AngularJS to bind keys to arrays

Hey there, I have an array that looks like this: $scope.Selectedgroups =[183,184,24] I want to convert it to the format shown below: [{groupId:183},{groupId:184},{groupId:24}]; I've been trying to convert it using a for loop: var groups=[] ...

Leveraging NgRx for Managing Arrays

export class Ingredient { public name: string; public amount: number; constructor(name: string, amount: number) { this.name = name; this.amount = amount; } } List of Ingredients: export const initialIngredients: Ingredient ...

Exploring the challenges of setting up Node in an attempt to unravel AngularJs 1.5

I recently started reading a book called "Unraveling AngularJS 1.5" in order to expand my knowledge on Angular development. Early on in the book, the author suggests installing Node.js, so I went ahead and did that. When I ran Node on the command prompt, i ...

There was an error encountered trying to access the options (URL) with a 405 method not allowed status. Additionally, the request to load the (URL) failed with a response indicating an

I attempted to retrieve data from an API using httpClient in Angular 5, but encountered errors. Below are the issues I faced: 1) ERROR: when trying to access http://localhost:8080/api/getdata, I received a 405 error (method not allowed). 2) ERROR: failed t ...

First example of combining Spring, Thymeleaf, and AngularJs: no issues, yet functionality is not operational

I am currently working on a project using Spring MVC 4.2.6 along with webjars libraries and the Thymeleaf framework. I have implemented a simple example in a template called 'test.html' mapped to '/test' in the controller: <!DOCTYPE ...

"Transferring Attributes to Nested Elements: A Step-by-Step

Currently, I am in the process of creating a straightforward AngularJS directive that will convert input elements as shown below: <input type="text" name="FirstName" mydirectivename /> Into a format like this: <span><input type="text" nam ...

Error TS2339: Cannot access attribute 'reactive_support' on interface 'LocalizedStringsMethods'

Encountering the error TS2339: Property 'reactive_support' does not exist on type 'LocalizedStringsMethods' I recently updated TypeScript from version 2.6 to 2.9, and attempted import LocalizedStrings from 'react-localization&apo ...

Creating a constructor that assigns values by using interfaces that are built upon the class

Looking at this interface/class example export interface MyErrorI { something: boolean; } export class MyError extends Error implements MyErrorI { public something = false; constructor(message: string, key: keyof MyErrorI ) { super(m ...

Could adjusting the 'lib' compiler option to incorporate 'dom' potentially resolve TS error code TS2584?

My preferred development environment is Visual Studio where I write Typescript code. I am facing an issue where I simply want to use the command "document.write" without encountering an error. Unlike my previous PC and VS setup, I am now getting an error ...

TypeScript Definitions for Material-UI version 15

Is there a Material-UI v15 TypeScript definition file in the works? I need it for a project I'm working on and as a TypeScript newbie, I want to make sure the custom file I've begun is accurate. ...

Cannot assign Angular 4 RequestOptions object to post method parameter

I'm having trouble with these codes. Initially, I created a header using the code block below: headers.append("Authorization", btoa(username + ":" + password)); var requestOptions = new RequestOptions({ headers: headers }); However, when I tried to ...