Bypassing angular's dependency injection by utilizing a universal object

Recently, I came across some code that utilizes a global object to store angular services. These services are attached to the global object within the run function of the angular module. It made me wonder, could this approach potentially lead to issues in the future? How does it impact testing? On one hand, passing around services like this seems more convenient than injecting them into each controller individually, which may explain why it was implemented this way. However, what are the downsides to using this method? The following code snippet demonstrates the concept:

// Global variables
var globalObject =
{
    ng: {},
};

// Module setup
var myModule = angular.module("myModule", []);
myModule.config(doStuff);
myModule.run(setUpGlobals);

// Setting up global app variables
function setUpGlobals(ngRootScope, ngHttp, ngTimeout)
{
    globalObject.rootScope = ngRootScope;

    // Angular services
    globalObject.ng.http = ngHttp;
    globalObject.ng.Timeout = ngTimeout;
}
setUpGlobals.$inject = ['$rootScope', '$http', '$timeout'];

Answer №1

Angular introduced Modules and DI to eliminate the reliance on global variables and enhance modularity.

However, this approach falls short when multiple modules are involved, leading to potential issues with separate usability (such as in testing environments) and multiple application instances on a single page.

The use of a monolith module can hinder testability and limit certain options, like injecting spied or stubbed services into controllers that depend on globals.

The function setUpGlobals causes eager service instantiation, which may not be necessary for all services at once.

In terms of code size in minified applications, there is limited improvement when minifying ng.$rootScope. Annotated functions should reference the '$rootScope' string only once, allowing the variable name 'rootScope' to be further minified for optimization.

Various reasons exist outlining why global variables are detrimental, some of which are relevant in this context while others may not apply.

Answer №2

Testing becomes a nightmare with this setup. However, Dependency Injection offers a solution by allowing for atomic tests through mocking out unnecessary services. For instance, consider a service that makes http API calls - by using DI, you can mock the http requests in your test and simulate a response. This way, you can focus on testing specific parts of your code without relying on external APIs or depleting your allotted number of API calls. Achieving the same level of isolation would be much more challenging with the provider in the global scope.

This is just one advantage among many others.

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

The angular view is lacking a CSS class

index.html: <div ng-view="myview.html"></div> myview.html: <table class="table table-striped table-hover"> <tr> <td>Name</td> <td>Product</td> </tr> <tr ng-repeat="deal in deals" class="clickableR ...

Utilizing Raycaster for modifying the Box's face color upon clicking

I've been experimenting with the raycaster in order to select faces of cubes that are created, and then change the color of the clicked face. So far, I've managed to make it work for selecting entire objects, but not individual faces of those obj ...

I have to ensure that a plugin is only loaded once its dependency has been loaded with RequireJS

Currently, I am utilizing the jquery.validationEngine.js plugin and facing an issue. It seems that jqueryValidateEnglish is unable to function properly unless jqueryValidateEngine is loaded beforehand. In my code for jquery.wrapped.validationEnglish2.js, ...

What is the best way to implement validation for individual elements within an array that are being displayed on a webpage using a for loop?

Currently, I am utilizing Vue JS within the Vuetify framework to build a dynamic form: <v-text-field v-for="items in itemsArray" :key="items.id" v-model="items.data" :label="items.name" ></v-text-field> ...

How can I deploy my Angular application on Wildfly along with the REST API it utilizes?

I have developed an AngularJs application that interacts with my REST api backend, which is built in Java and deployed on Wildfly. My servers are currently accessible from the Internet by using my public IP address through port-forwarding. Now I am wonde ...

What is a way to receive a reply in JavaScript without using an endpoint?

Take a look at this code snippet I wrote: ... await fetch('https://example.com', { method: "GET", mode: "no-cors" }) .then((response) => { console.log(response.body); console.log(response ...

Can I maintain the separation of two arrays in Angular and still utilize them in an ng-repeat?

Before we proceed, let's reference this question: Angularjs map array to another array Presently, I am managing two distinct scopes: $scope.products = [ {id: 001, name: "prod 1", ...}, {id: 002, name: "prod 2", ...}, {id: 003, name: "prod 3", ...

What is the best way to add DOM elements to an Angular 2 component while maintaining encapsulated styles?

I am currently in the process of upgrading a pre-existing Angular 2 application that heavily relies on JQuery Plugins, D3, and even some React Components (all utilizing sizzle). Instead of rewriting everything at once, I have decided to wrap certain compon ...

Instructions for activating and deactivating a numerical input field with a checkbox

Is there a way to create a pair of a checkbox and number field that are linked together? When the checkbox is clicked, it should disable the associated number field. Javascript File: $(document).ready(function(){ $("input[name=check]").click(function(){ ...

The website that had been functioning suddenly ceased operations without any modifications

It seems like this might be related to a JavaScript issue, although I'm not completely certain. The website was working fine and then suddenly stopped. You can find the URL here - Below is the HTML code snippet: <!DOCTYPE html> <html> ...

Find the position of an HTML5 canvas element within a webpage

I am currently facing an issue with a canvas within another canvas. <canvas id ='canvas2' height="718" width="1316"></canvas> The CSS for this canvas is as follows: #canvas2{ position:absolute; width :95%; height:90%; top:5%; lef ...

Looking to detect and notify the presence of duplicate values within an array

I am encountering an issue where I can view an array in the console, but cannot check if it contains duplicate values. $('.tab2field').each(function () { PackageName.push($('.span2', this).val() ); PackageCount.push($(&apo ...

Dynamic Array Rendering with Vue.js Computed Properties

As a newcomer to Vue, I've dedicated the last few hours to learning how to implement conditional logic in methods and computed properties for a practice birthday component project. While exploring different approaches, I noticed some developers utiliz ...

Maintain the structure of ajax POST requests and display a real-time feed of

I've been developing an openvz script to run virtual machines at home. I've been exploring JavaScript and AJAX functions to send post requests, which are then displayed in the innerHTML section of my webpage. However, I've encountered an iss ...

Tips for dynamically hiding/showing a button depending on the focus of two different HTML inputs

I'm working on a login section and looking to add a unique feature: When a user selects the email or password input field, I want the button text to change to 'LOGIN'. If neither input field is selected, the text should display 'NOT A ...

An approach to concealing a search bar while scrolling down and revealing it while scrolling up in react-native

Looking for help with implementing a disappearing search bar functionality when scrolling? Check out the following code snippets and examples that demonstrate how to achieve this feature: showSearchBarIOS = () => { return ( <View style={st ...

A guide on selecting the best UI container based on API data in React using TypeScript

I have been developing a control panel that showcases various videos and posts sourced from an API. One div displays video posts with thumbnails and text, while another shows text-based posts. Below is the code for both: <div className=""> &l ...

The submission of the form is not functioning correctly when triggered by JavaScript using a button

My website was designed using a CSS/HTML framework that has been seamlessly integrated into an ASP.NET site. Within a ContentPlaceHolder, I have implemented a basic login form. The unique aspect is that I am utilizing the onclick event of an image to subm ...

Is JavaScript generating a random sequence by dynamically adding fields?

I'm encountering an issue with my button that adds a set of text fields every time I click on the Add More button. The problem is that when I add new text fields, they are appended above the Add More button. Then, pressing the button again adds more t ...

passing parameters between functions using event listeners

Within these functions, the first one is activated by a button with the goal of triggering another function that will change the content within the same area as the button. The challenge lies in how to pass arguments from the first function to the second, ...