What causes a service called from external of angular to not act as a singleton?

Currently, I am in the process of working on a project that requires me to access a service from outside the Angular service. Unfortunately, it seems that the service retrieved from outside of Angular is not the same instance as the one inside the application. In fact, it creates a new instance every time I invoke it. Below, I have created an example to illustrate this issue.

<div ng-controller="controller">
    <div>
        <span ng-bind="count"></span>
        <input type="button" value="Inside" ng-click="inc()"></input>
    </div>
    <div>
        <span id="outside-count">0</span>
        <input type="button" value="Outside" onclick="outside()"></input>
    </div>
</div>

Here is the corresponding JavaScript code:

angular.module('Services', [])
.service('svc', function() {
    var svc = {
        count: 0,
        increment: function(){svc.count++;}
    };
    return svc;
});

angular.module('MyApp', ['Services'])
.controller('controller', ['$scope', 'svc', function($scope, svc) {
    $scope.count = svc.count;
    $scope.inc = function() {
        svc.increment();
        $scope.count = svc.count;
    };
}]);

var outside = function() {
    var svc = angular.injector(['ng', 'Services']).get('svc');
    svc.increment();
    angular.scope().$apply();
    document.getElementById('outside-count').innerHTML = svc.count;
};

My expectation was that the outside count button would increment the same service object as the one I get in the ng-controller. However, it creates a new instance every time, with consecutive clicks on the button always displaying 1. The "Inside" button, on the other hand, continues to increment the single service as expected.

Is there an alternative way for me to access the service from outside Angular in order to get the singleton instance of the service?

Here is a fiddle of the provided code.

Answer №1

In Angular, services act as singletons because they are only created once per injector.

On the other hand, angular.injector generates a new injector function.

To access the current app injector, use

angular.element(domElement).injector()

See a demonstration here: http://jsfiddle.net/BsLK8/

Check out another demo where the content stays synchronized: http://jsfiddle.net/kW2BC/

Answer №2

When you are creating a new injector using those modules, you are actually creating a new instance of the requested service. In order to access the existing injector associated with the element containing the necessary data/instance, you should use the following code snippet:

//assuming ng-app='MyApp' is placed on the html tag
//if not, provide the correct element
var service = angular.element(document).injector().get('service');

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 is the best method for determining the cookie expiration time in AngularJS 1.3?

Currently in my application, I am utilizing AngularJS 1.3. I encountered a challenge while using $cookies to store data where I needed to implement a 1-minute expiration time for the cookie. However, the $cookies service in AngularJS 1.3 does not provide ...

Guide to incorporating jQuery into an ASP.NET webpage and styling GridView column layouts

After reading numerous articles and questions on formatting gridview rows using jQuery, I decided to give it a try for the first time in an ASP.NET page. Although I managed to write the following code, it seems to have no effect on the gridview. Can anyon ...

Step-by-Step Guide to Editing a Firebase Document

Attempting to update a Firebase document results in an error message displayed in the console. Unhandled promise rejection FirebaseError: "Function DocumentReference.update() called with invalid data. Unsupported field value: undefined (found in fie ...

Having trouble deploying my Express/Next app on Netlify

I am facing issues deploying my Next/Express app on Netlify. While the app functions perfectly locally, I encounter problems when attempting to deploy it using Netlify lambda function. Here are the links to my test git repositories: https://github.com/La ...

Using TypeScript to define values with the placeholder "%s" while inputting an object as a parameter

One common way to decorate strings is by using placeholders: let name = "Bob"; console.log("Hello, %s.", name) // => Outputs: "Hello, Bob." I'm curious if there's a way to access specific values within an object being passed in without specif ...

The value attribute in the HTML input tag being dynamically increased by JavaScript

Hi there, can someone help me figure out how to save changes to the value attribute of an HTML input tag that is being incremented by JavaScript? Currently, every time I click on a specific element, the input field should increase by one. The problem is th ...

Encountered a problem initializing Rangy.js on Internet Explorer

Currently, I am developing an angular application that utilizes textAngular along with rangy-core and rangy-selectionsaverestore. However, I am encountering some errors specifically on the latest version of Internet Explorer: Module 'WrappedSelection ...

The user model cannot be assigned to the parameter of type Document or null in a mongoose with Typescript environment

While working with Typescript, I encountered an error related to mongoose. The issue arises from the fact that mongoose expects a promise of a mongoose document (in this case, the user's document) or "null" to be resolved during a search operation. Ho ...

Socket.io encounters emitting issue within express app.post function

I am working on integrating an express application with a frontend React application using socket connections. My goal is to trigger an event on the connected socket whenever a post request containing JSON data is sent to my server. However, I am facing a ...

Issue reported: "Usage of variable 'someVar' before assignment" ; however, it is being properly assigned before usage

This piece of code showcases the issue: let someVar: number; const someFunc = async () => { someVar = 1; } await someFunc(); if (someVar == 1) { console.log('It is 1'); } As a result, you will encounter ...

How can I prevent anchors from performing any action when clicked in React?

My dilemma involves this HTML element: <a href onClick={() => fields.push()}>Add Email</a> The purpose of the href attribute is to apply Bootstrap styles for link styling (color, cursor). The issue arises when clicking on the element caus ...

Is there a way to seamlessly transition between images in a slider every 3 seconds using javascript?

<!DOCTYPE html> <html> <head> <title>Hello</title> <meta http-equiv="Content-Type" type="text/html" charset="UTF-8"/> <style> *{margin:0; padding:0;} .mySlides{ position:relative; width:1000px; ...

The JavaScript function getSelection is malfunctioning, whereas getElementById is functioning perfectly

I am encountering a peculiar situation while trying to input text into a textbox using a JavaScript command. The CSS locator does not seem to update the text, whereas the ID locator is able to do so. URL: Below are screenshots of the browser console disp ...

Having trouble with debugging Angular JavaScript code? The Model option in the Batarang debugger doesn't seem to be displaying the scope

I've been struggling to pinpoint the scope of AngularJS in Batarang. Despite spending a considerable amount of time debugging, I still can't seem to access the scope. Below is the HTML code snippet: <div data-ng-controller="RegisterCtrl" ...

An error occurs with Three JS when trying to access a S3 Bucket used as a CDN due to Cross Origin

function displayItem() { startScene(); THREE.ImageUtils.crossOrigin = "anonymous"; var mtlLoader = new THREE.MTLLoader(); mtlLoader.setTexturePath('https://cdn.rubyrealms.com/textures/'); mtlLoader.setPath('https://cdn.ru ...

The $scope variable is missing from the DOM

I've been trying to implement ng-repeat with AngularJS, but I'm having trouble getting the scope result in my DOM. Is there something wrong that anyone can spot? I've spent hours troubleshooting this and no matter what I do, "players" always ...

Vue.js provides an interesting object that contains observed data

My axios request looks like this: retrieveData() { Axios.get( '/vue/get-data/', { ...

Toggle switch with active state

I'm currently using Ionic 2 alongside Angular 2 beta 11. Is there a way to turn off the toggle switch? The Ionic documentation suggests using the checked attribute, but I've tried that and also attempted ng-checked with no luck. Any advice on t ...

The feature to hide columns in Vue-tables-2 seems to be malfunctioning

The issue I'm facing is with the hiddenColumns option not working as expected. Even when I set it to hiddenColumns:['name'], the name column remains visible. I've updated to the latest version, but the problem persists. UPDATE I am tr ...

What is the process for adding information to datatables using jQuery?

I have been struggling to make a data table in jQuery function correctly. I am able to append data to the table, but the sorting, pagination, and search features are not working. Even though the data is visible in the table, it shows as 0 records. I am wor ...