Angular often uses the JavaScript pattern for development

After completing an AngularJS tutorial on http://www.tutorialspoint.com/angularjs/angularjs_services.htm, I found myself puzzled by the method used in the CalcService service. It seemed unclear whether Angular was using revealing prototype or a different approach. The inner function declared within this.square should technically be private and inaccessible outside of the object's context, so I was curious how Angular managed to access it.

mainApp.service('CalcService', function(MathService){
    this.square = function(a) { 
        return MathService.multiply(a,a); 
    }
});

Answer №1

An AngularJS service is quite unique in its behavior.

During initialization, it goes through the process of being instantiated with the use of the new keyword. For example:

function CalcService() {
  this.square = function() {
    // perform some square calculation
  };
}

// then in the controller, directive, or any other component,
// it is initialized implicitly as shown above
new CalcService();

However, what sets it apart is that it is instantiated as a singleton, indicating that there's always just one instance of the object, even if attempts are made to reinitialize it within the registering component (refer to my response on singletons in AngularJS for more information).

I'm not entirely sure about your reference to a "revealing prototype pattern," but in the context of an AngularJS service, the this simply signifies the implementation of a non-prototypal method on a standard JavaScript object.

Expanding on the previous example, in typical JavaScript, you could execute new CalcService().square(). It's worth noting that JavaScript doesn't inherently support private methods (although there are techniques for simulating "class" methods that seem confidential.)

var service = new CalcService();

service.square();

There isn't anything technically "private" about that method, much like the methods associated with AngularJS service objects. The closest thing to privacy is that it specifically belongs solely to that particular object by way of utilizing the this keyword.

Answer №2

When using the angular service DI method, you pass a constructor function in your example.

In this constructor function, a method is assigned to this.square.

If you try this same approach without Angular, you will notice that it behaves similarly.


function Calculator() {
    this.square = function() {
        console.log('we get here');    
    } 
} 

var calculator = new Calculator();
calculator.square();

This demonstrates Javascript's prototype object-oriented model and showcases plain old OO javascript.

Answer №3

The previous responses have provided a good explanation of how services work, but they have not addressed how the newly created object, referred to as this, is exposed.

When you create a service in Angular, the framework generates a new object of that function for you. This object is returned when the service is injected into a controller, directive, or another service. Internally, Angular uses the prototype of the function to create the this context of the function. Let's take a closer look at the code snippet below to understand how this mechanism works:

function CalcService(){
    //The line below this creates an obj object.
    //obj = Object.create(CalcService.prototype)
    //this = obj;
    //`this` is essentially an instance of the function/CalcService.prototype which grants access to its properties attached to it
    var privateVariableExample = 'test'; //This is a private variable of the service.
    this.square = function(a) {
        //Return multiplication result from here 
    }

    //return this;
}

var objectOfCalcService = new CalcService();
objectOfCalcService.square(1);

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

Determining the file size of an HTML and JavaScript webpage using JavaScript

Is there a way to determine the amount of bytes downloaded by the browser on an HTML+JS+CSS page with a set size during page load? I am looking for this information in order to display a meaningful progress bar to the user, where the progress advances bas ...

Enhance your Sails.js model by incorporating a custom instance method as a new property

As a JavaScript programmer still learning the ropes, I encountered a challenge while working with Sails.js and creating a model. Here is what I have so far: module.exports = { tableName: 'FOO_TABLE', attributes: { FOO: 'st ...

Bootstrap revamps dropdown menu code into a convoluted mess

I recently started working on a project with the Material Design theme from for a CodeIgniter application. However, I've encountered an issue with the dropdown functionality. It seems that Bootstrap is altering the original code, transforming it from ...

Running a Blitz.js api handler triggers a Google Cloud Storage call failure with the message "error:0909006C:PEM routines:get_name:no start line"

When attempting to utilize @google-cloud/storage within a Blitz.js /api handler, I encounter the following error: error:0909006C:PEM routines:get_name:no start line at Sign.sign (internal/crypto/sig.js:110:29) at NodeCrypto.sign (C:\Users&bsol ...

A guide on installing a npm dependency module from a local registry domain

I have successfully published a module on my own custom registry domain, located at , and I am able to publish updates to the module there. Unfortunately, I am encountering an issue with dependencies within my published module. For example: "dependencies" ...

What is the purpose of using async/await in Node.js when it is inherently asynchronous, and in JavaScript as well, vice versa?

Apologies for my lack of experience in Javascript and NodeJS. I'm a total beginner, so please excuse my silly questions. I've been trying to wrap my head around the concept but haven't found a clear explanation. Here's what's conf ...

The function $(this).addClass() seems to be malfunctioning

While trying to follow a tutorial, I noticed that the style sheet isn't being applied to the clicked element in the list. What could be causing this issue? In the example provided, when a string is added to the text box and the button is clicked, a n ...

Easy steps to dynamically add buttons to a div

I need help with a JavaScript problem. I have an array of text that generates buttons and I want to add these generated buttons to a specific div element instead of the body. <script> //let list = ["A","B","C"]; let list = JSON.p ...

Issue with JQuery Event Listener on Canvas Subelement not functioning

I encountered an issue while trying to implement a custom crop rectangle on a canvas using JavaScript. I created a function that, when called, should add a child node to the existing canvas and use JQuery listeners to draw the rectangle. However, although ...

Adding an HTML element to the DOM in an AngularJS directive without using jQuery

Looking to enhance my AngularJS directive by including an svg tag within the current element, currently using jQuery for this purpose. link: function (scope, iElement, iAttrs) { var svgTag = $('<svg width="600" height="100" class="svg">< ...

Bootstrap relies on jQuery for its JavaScript functionality, so jQuery must be loaded before using Bootstrap's JavaScript

I encountered an issue while trying to load the Bootstrap library, consistently receiving this error message: Uncaught Error: Bootstrap's JavaScript requires jQuery Even though I have ensured that jQuery is loaded before attaching the Bootstrap li ...

Creating blank entities with app.post using AngularJS and mongoose in a node.js environment

My issue seems to be with my REST API as it is posting empty objects. The value I am retrieving from req.body.name appears correctly when I log it using console.log(req.body.name);. POST: { name: 'typing any name', status: null } typing any na ...

Exploring the integration of video playback within an Angular-Bootstrap modal upon opening

When it comes to loading videos dynamically based on a scope array of resources, I currently have the following setup: this.open = function (size, resource) { var modalInstance = $uibModal.open({ templateUrl: 'playModal.html', ...

Issue with setting state in useEffect causing an infinite loop due to either linter warning or user error

In its current state, my component appears as follows: const { listOfStuff = [{name:"john"},{name:"smith"}] } = props const [peopleNames, setPeopleNames] = useState([]) useEffect(() => { listOfStuff.forEach(userName => { setPeopleNames(people ...

What is the best way to extract words from a string within a textarea using javascript?

Currently, I am focused on improving my skills in JavaScript and HTML. In one of my projects, there is a text area where the user inputs a CSV format like this: 17845 hello bye 789 After input, I get 17845,hello,bye,789. Now, the challenge is t ...

A guide on customizing the appearance of individual items in a vue v-for loop based on specific conditions

I am currently developing a multiple choice quiz game and I want the selected answer by the user to change color, either red or green, depending on its correctness. To achieve this, I have created a variable called selected that correctly updates when the ...

Automatically log out users in AngularJS after a specified period with session timeouts

I recently developed a website using AngularJS and now I'm faced with the task of implementing an automatic logout feature if the user has been inactive for more than 10 minutes after logging in. Additionally, I need to ensure that the local storage r ...

I am encountering problems with images that are imported as module imports in a Vue.js project

Currently, I have stored all the default images for my Vue project in a designated folder. The path to this folder is web/images/defaults/<imageNames>.png. Instead of importing each image individually in my components, I wish to create a file that co ...

Stopping a velocity.js animation once it has completed: is it possible?

For the pulsating effect I'm creating using velocity.js as a fallback for IE9, refer to box2 for CSS animation. If the mouse leaves the box before the animation is complete (wait until pulse expands and then move out), the pulsating element remains vi ...

Error: The method specified in $validator.methods[method] does not exist

Having trouble solving a problem, despite looking at examples and reading posts about the method. The error I'm encountering is: TypeError: $.validator.methods[method] is undefined Below that, it shows: result = $.validator.methods[method].call( t ...