The art of tidying up Angular UI controllers

I am a beginner with Angular and have integrated angular-ui to use bootstrap modals for adding data. It seems inefficient to have to include all these functions in EVERY controller where I want to use a modal. Is there a way to make this more reusable?

lassoControllers.controller('PostsController', ['$scope', '$timeout', '$http', 'Post', '$modal',
function($scope, $timeout, $http, Post, $modal) {
    $scope.posts = Post.query();

    $scope.askDelete = function(item) {
        var message = "Are you sure ?";

        var modalHtml = '<div class="modal-body">' + message + '</div>';
        modalHtml += '<div class="modal-footer"><button class="btn btn-primary" ng-click="save()">OK</button><button class="btn btn-warning" ng-click="cancel()">Cancel</button></div>';

        var modalInstance = $modal.open({
            template: modalHtml,
            controller: 'ModalInstanceCtrl'
        });

        modalInstance.result.then(function() {
            reallyDelete(item);
        });
    };

    var reallyDelete = function(item) {
        $scope.items = window._.remove($scope.items, function(elem) {
            return elem != item;
        });


    };

}]);

Answer №1

While I am still exploring Angular, I have been delving into it for a few months now, especially in working with modals. As far as I know, your code looks good. Unless you feel that the logic inside the modal is repetitive, it seems to be as modular as it can be.

You could enhance it by moving the modal's HTML to a separate template file and then using templateUrl: to include it.

Additionally, I came across a helpful Angular style guide here that could assist in understanding the framework better. It provides insights into the reasoning behind various patterns.

Answer №2

Your understanding is correct that Angular.js requires you to inject multiple services into the controller when using dependency injection. This is a fundamental aspect of a framework that utilizes constructor dependency injection. However, in the example you provided, you have the opportunity to refactor some of the services being injected. While you may still need to inject certain alternatives, you can streamline your code and reduce the amount of boilerplate code needed.

Optimizing Services

$scope

By utilizing the controllerAs syntax, you can simplify your code by assigning properties directly to the controller and referencing it in your templates. Todd Motto and John Papa both advocate for this approach in their respective discussions on Angular.js best practices.

$http

It is advisable to avoid directly using $http in your controllers. Instead, create a service that abstracts the $http calls, similar to what the Post service appears to be doing. John Papa's style guide highlights the benefits of this approach in terms of data services.

$modal

Abstracting the $modal functionality into separate services, such as a ConfirmModalService, can help streamline your codebase. By centralizing logic related to modals, you can enhance code reusability. Additionally, storing modal HTML content in a separate file or property within the service can improve maintainability.

Additional Style Recommendations

To further simplify your controller, consider moving certain services into a separate abstraction layer responsible for handling user interactions. This modular approach offers flexibility in code organization.

Furthermore, relying on the global window object can pose challenges during testing. In line with Angular.js best practices, consider injecting the angular $window service for improved testability and adherence to recommended coding styles.

Sample Implementation:

lassoControllers.controller('PostsController', ['$timeout', 'Post', 'ConfirmModalService',
function($timeout, Post, ConfirmModalService) {
    var vm = this;
    vm.posts = Post.query();

    vm.askDelete = function(item) {
        var message = "Are you sure ?";
        var modalResult = ConfirmModalService.open(message).then(function() {
            vm.reallyDelete(item);
        });
    };

    vm.reallyDelete = function(item) {
        // Assuming this is an array
        vm.items = vm.items.filter(function(elem) {
            return elem != item;
        });
    };

}]);

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

What could be causing the malfunction of this JavaScript dropdown select feature in Internet Explorer?

I created a website that requires users to input their location, including the city and state. The process involves two dropdown menus: - The first dropdown menu, labeled "state," loads all USA states as selectable options when the website is loaded. This ...

Issue persists: Ajax functionality remains nonfunctional, prompting the need for

My goal is to use the post input, and upon hitting enter, I want to dynamically replace <div id="mainPagePosts"></div> with new data without causing a page refresh. However, even after submitting the post, the page still refreshes, although I d ...

What is the best way to set up an on-change listener for material-ui's <CustomInput...>?

I'm currently utilizing the React dashboard created by Creative Tim. I have a question regarding how to set up an onChange listener for a Here is the code snippet for the custom input class: import React from "react"; import classNames from "classna ...

Pinia store encountering a Typescript Vue component issue: error message "The property 'testStore' does not exist on the 'CreateComponentPublicInstance' type."

Within my <script setup> block, I have imported my testStore. However, whenever I attempt to use this.testStore.name in my Vue file, Vetur displays the following error: Property 'testStore' does not exist on type 'CreateComponentPublic ...

Adjust the button's background hue upon clicking (on a Wix platform)

I need some help with customizing the button "#button5" on my Wix website. Here are the conditions I'd like to apply: Button color should be white by default; When the user is on the "contact" page, the button color should change to red; Once the use ...

Upon opening index.html in the browser, the jQuery code fails to execute, as no errors are displayed in the console

I am struggling to make a simple toggleClass() function work in jQuery and I can't seem to figure out why. This is just a beginner exercise for me with jQuery. The code works perfectly when I test it as a snippet or manually in the console, but when I ...

What is the process of creating a sequence using IONIC and an angularjs controller?

I'm facing a problem with the sequence of alerts in my code. Here is how I have implemented it: .controller('ulpCtrl', function($rootScope, $ionicPopup, tanyaService, $state) { $rootScope.getKat = 'UL'; // The meth ...

Is there a way to establish the position of a mesh in three.js before integrating it into the scene?

How can I add a mesh to a specific position in the scene using three.js? I attempted the following code without success: // mesh refers to an instance of THREE.Mesh // scene is an instance of THREE.Scene scene.add(mesh) scene.updateMatrixWorld(true) mesh. ...

Transferring binary fragments to Node.js for assembly into a complete file. Creating a file

Hey there, I'm in a bit of a bind. I'm trying to send file chunks using multiple XMLHttpRequest requests and then receive these parts in Node.js to reconstruct the original file from the binary data. The issue I'm facing is that the final f ...

obtainServerSideProps query parameter

Hey there, I'm trying to use NextJS and its getServerSideProps function to send an API Request, but I'm having trouble passing my ID Query Parameter along. The URL for my API is: http://localhost:3001/product/${id} Below is my code: const rout ...

The menu on the webpage in smartphone mode is infiltrating other divs on the page

Encountering an issue with the TwitterBootstrap CSS menu on this page when viewed on a smartphone: The div containing the menu does not resize its height, causing it to invade the content below when the "Menu" is clicked. I've been unable to find a ...

What could be causing the bootstrap 4 col-md-3 block to shrink when using position fixed?

When working with Bootstrap 4, I encountered an issue where changing the block position from relative to fixed using a script caused the block to decrease in size. The script I used includes a .sticky class: .sticky { position: fixed !important; top: ...

The dataTable plugin is malfunctioning, displaying all records on a single page when it should only show 10 per page

I utilized the dataTable plugin to format my HTML table, but unfortunately it is not displaying the results as expected. Instead of showing 10 records per page, it is displaying all records at once. I even tried setting "iDisplayLength: 10" but it didn&apo ...

I am facing a recurring issue where I am unable to add new libraries to my node_modules directory due to encountering the same error every time I attempt to

An error occurred after running npm audit --force, causing a dependency issue in my Node_modules 0 verbose cli C:\Program Files\nodejs\node.exe C:\Users\Jenis\AppData\Roaming\npm\node_modules\npm\bin& ...

Scrolling with React Event

I am attempting to create a scrollbar that only appears when I scroll within a particular area using React. I am utilizing debounce and useState in my implementation. The issue: When I reach the end of the scroll, the event continues to repeat indefinitel ...

Encountering an issue where the Angular build is unable to locate the installed Font-Awesome node module

Every time I attempt to compile my project using ng build --prod, I encounter the following error: ERROR in ./src/styles.scss Module build failed: ModuleBuildError: Module build failed: Error: Can't resolve '~font-awesome/css/font-awesom ...

Link a function to a button in a 3rd party library

Whenever I click a button, there is a possibility of an alertify alert window appearing randomly. The alertify alert popup serves as a more aesthetically pleasing alternative to the traditional javascript Alert. Alertify library Below is a snapshot depic ...

`Month filter functionality optimized`

I have a flirty plugin installed on my website and it's working great except for one thing: I'd like the month category to be filtered in chronological order instead of alphabetically. Is there a way to achieve this? In simpler terms, how can I ...

Codeigniter - Ajax request successful in remote server but fails in local server

I am encountering an issue with my web application that makes Ajax requests to a server using Codeigniter-php code. While the Ajax requests work fine on the local server, they do not function properly when the application is hosted on a remote server. The ...

Changes made to the data are not reflected in the user interface, but they are visible in the console

When working on a React project with input fields, I encountered an issue where the date data can be changed but doesn't get reflected in the UI. Instead, the updated data is visible in the console. The code snippet below showcases how I'm using ...