How does the AngularJS Dependency Injection system determine the names of the arguments it needs to inject?

Here is an example directly from the official website:

function PhoneListCtrl ($scope, $http) {
    $http.get('phones/phones.json').success(function(data) {
        $scope.phones = data;
    });

    $scope.orderProp = 'age';
}

The $scope and $http parameters are specific identifiers used to access corresponding AngularJS services within the DI (Dependency Injection) system. How does the DI system precisely locate the variable name for these arguments?

Answer №1

This is a condensed version of a method

var FN_ARGS = /^function\s*[^\(]*\(\s*([^\)]*)\)/m;
var FN_ARG_SPLIT = /,/;
var FN_ARG = /^\s*(_?)(\S+?)\1\s*$/;
var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;

function annotate(fn){
    var $inject
    if (!($inject = fn.$inject)) {
        $inject = [];
        fnText = fn.toString().replace(STRIP_COMMENTS, '');
        argDecl = fnText.match(FN_ARGS);
        angular.forEach(argDecl[1].split(FN_ARG_SPLIT), function(arg){
            arg.replace(FN_ARG, function(all, underscore, name){
                $inject.push(name);
            });
        });
        fn.$inject = $inject;
    }

    return fn.$inject;
}

Demo: Fiddle(View the console for output);

Steps:
1. Use `toString` to fetch the source of the function
2. Eliminate comments with regex
3. Parse and retrieve arguments from the function's source

Answer №2

Directly from the official @GitHub page:

The most basic method is to retrieve the dependencies from the arguments of the function. This involves converting the function into a string using the toString() method and then extracting the argument names.

// Example
function MyController($scope, $route) {
    // ...
}
// Outcome
expect(injector.annotate(MyController)).toEqual(['$scope', '$route']);

Concerning the annotate function

function annotate(fn) {
  var $inject,
  fnText,
  argDecl,
  last;

  if (typeof fn == 'function') {
    if (!($inject = fn.$inject)) {
      $inject = [];
      fnText = fn.toString().replace(STRIP_COMMENTS, '');
      argDecl = fnText.match(FN_ARGS);
      forEach(argDecl[1].split(FN_ARG_SPLIT), function(arg){
        arg.replace(FN_ARG, function(all, underscore, name){
        $inject.push(name);
      });
    });
    fn.$inject = $inject;
    }
  } else if (isArray(fn)) {
    last = fn.length - 1;
    assertArgFn(fn[last], 'fn')
    $inject = fn.slice(0, last);
  } else {
    assertArgFn(fn, 'fn', true);
  }
  return $inject;
}

found on line 45 onwards

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

Creating an object that tracks the frequency of each element from another object using JavaScript

I have a scenario where I need to create a new object based on the number of occurrences of specific minutes extracted from a timestamp stored in another object. Existing Object: { "data": { "dataArr": [ { ...

Building a like/dislike feature in Angular

Here is a snippet of code I have that includes like and dislike buttons with font-awesome icons: <ng-container *ngFor="let answer of question.answers"> <p class="answers">{{answer.text}} <i class="fa fa-hand-o-le ...

retrieving the values listed on the current v-data-table page

In my vuejs2 project, I am utilizing a v-data-table to display information in columns about a large number of users. Each page shows 25 users, with a total exceeding 60,000 individuals. I am wondering if there is a way to retrieve the list of users curre ...

Utilize Google Tag Manager to search and substitute characters within a variable

Within my GTM setup, I have a CSS selector variable in the DOM. This variable pertains to real estate and specifically represents the price of a listing. My goal is to eliminate the characters ($) and (,) from this variable as part of meeting the requireme ...

Simplify nested JSON data

I'm struggling with a JSON object that looks like this: const people = { name: 'My Name', cities: [{city: 'London', country: 'UK'},{city: 'Mumbai', country: 'IN'},{city: 'New York', country: ...

Instructions for manipulating and displaying a source array from a child component using Vue

I have a parent component with an array that I display in the template. My goal is to click on a link that uses vue-router with a dynamic id attribute, and then open a new component displaying only the element of the array that corresponds to that id. Howe ...

State in Vuex is not kept intact after redirection to another page

Inside my Vue.js application, I have created a method for logging in users. This method sends a POST request to the server with the username and password, stores the returned data in Vuex store, and then redirects the user to the home page: login: func ...

Generating an instance of an enum using a string in Typescript

Having trouble accessing the enum members of a numeric enum in TypeScript using window[name]. The result is an undefined object. export enum MyEnum { MemberOne = 0, MemberTwo = 1 } export class ObjectUtils { public static GetEnumMembers(name ...

Querying MongoDB in Loopback is posing a challenge

My attempt to query MongoDB from a LoopBack model is not yielding any results. This is an example of how my document appears in MongoDB: {"_id":"5b9f8bc51fbd7f248cabe742", "agentType":"Online-Shopping", "projectId":"modroid-server", "labels":["category", ...

AngularJS NG-Repeat not iterating multiple times like it should

Can anyone help me with my ng-repeat issue regarding Json data? It seems to only display the second set of dates and not the first. Any insights into why this might be happening? I have tried using a promise, but it is only fetching the information relate ...

What is the best way to generate dynamic components on the fly in ReactJS?

Could you please guide me on: Techniques to dynamically create react components, such as from simple objects? Is it possible to implement dynamic creation in JSX as well? Does react provide a method to retrieve a component after its creation, maybe b ...

Receiving updates on the status of a spawned child process in Node.js

Currently, I'm running the npm install -g create-react-app command from a JavaScript script and I am looking to extract the real-time progress information during the package installation process. Here is an example of what I aim to capture: https://i ...

Utilizing jQuery to send AJAX requests and display the results on separate lines within a textarea

My form includes a text area where users can enter keywords, one per line. I would like to implement the following functionality: upon clicking a button, an ajax request will be sent to the server to retrieve the result for each keyword entered. The resul ...

"Looking to disable the browser shortcut for ctrl-N and instead trigger a function when this key combination is pressed? Check out the JS Fiddle example provided below

I recently incorporated the library shortcut.js from In my project, I attempted to execute a function when CTRL + N is pressed. The function executed as expected; however, since CTRL + N is a browser shortcut for opening a new window in Mozilla 8, it also ...

What is the best method for updating the state of a dynamically created Switch component using React's setState()?

I have a dynamic creation of Switches based on a map like shown in the image: https://i.stack.imgur.com/jDLbS.png For example, using this code: const [enabled, setEnabled] = useState(false) return( ... {people.map((person) => ( ... ...

How to Insert PHP/MySql Data into JavaScript

As I delve deeper into PHP OOP, I feel like I'm making progress in transitioning my website. Currently, each user has their own page with a javascript grid tailored to their specific needs. For easier maintenance, I'm considering the idea of havi ...

Transform a string into a boolean value for a checkbox

When using v-model to show checked or unchecked checkboxes, the following code is being utilized: <template v-for="(item, index) in myFields"> <v-checkbox v-model="myArray[item.code]" :label="item.name" ...

Tips on dividing a div into two separate pages when converting to PDF

I am working on an asp.net MVC project and I need to convert a HTML div into a PDF with two separate pages. Here is an example of my code: HTML Code <div class="row" id="mycanvas"> <p>This is the first part of my content.</p> <p ...

Swapping data between two HTML files and PHP

As I work on setting up a signup form for a MikroTik hotspot, I've encountered limitations with the device not supporting PHP. In order to pass the necessary variables from the device to an external PHP page where customer data will be saved and trial ...

What is the best way to show a loading symbol within a ui-grid before the data is rendered?

This is the code snippet I have been working on: var app = angular.module('app', ['ngAnimate', 'ui.grid']); app.controller('MainCtrl', ['$scope', '$http', '$timeout', function ($scop ...