The problem arises when Angular's $interval function is not recognized

Despite the possibility of this being considered a duplicate, none of the related topics have provided a solution to my simple date count down directive:

class Clock {
    constructor() {
        this.restrict = 'AC';
        this.replace = true;
        this.template = require('./templates/clock.tpl.html');
        this.scope = {};
    }
    link(scope, elem, attrs, $interval) {
        let end = new Date('05/05/2017 9:00 AM');

        let _second = 1000;
        let _minute = _second * 60;
        let _hour = _minute * 60;
        let _day = _hour * 24;

        scope.showRemaining = () => {
            let now = new Date();
            let distance = end - now;
            let days = Math.floor(distance / _day);
            let hours = Math.floor((distance % _day) / _hour);
            let minutes = Math.floor((distance % _hour) / _minute);
            let seconds = Math.floor((distance % _minute) / _second);

            scope.days = days;
            scope.hours = hours;
            scope.minutes = minutes;
            scope.seconds = seconds;
        }

        $interval(showRemaining, 1000;)
    }
}

// create factory function to handle DI
function factory() {
    "ngInject";

    return new Clock();
}

export default factory;

I've been searching for a solution to this issue and everywhere I find information stating that the interval function must be passed as a normal one without parameters or any additional features. However, I continue to encounter the same error message:

TypeError: $interval is not a function

Can someone provide assistance?

Answer №1

Injecting dependencies should be done in the constructor, not in the link function:

constructor($interval) {
    // ..
    this.$interval = $interval;
}
link(scope, elem, attrs) {
    // ..
    this.$interval(showRemaining, 1000;)
}

Answer №2

One issue with using classes to create directive objects is that directive functions have a non-lexical this, as explained in this particular answer. While it's possible to inject $interval into the constructor, utilizing it within the link function requires binding:

constructor($interval) {
  ...
  this.$interval = $interval;
  this.link = this.link.bind(this);
}

This reveals a flaw in the design. Directives and classes aren't an ideal match. The use of classes for constructing directive objects lacks advantages and reusability. It doesn't offer any architectural benefits.

Angular 1.5+ has borrowed concepts from Angular 2 to facilitate easier migration, steering development towards being controller-centric. As a result, pre-link and post-link functions have been replaced by hooks like $onInit and $postLink.

An effective approach to class-based AngularJS development could involve:

class ClockController {
  constructor($interval) {
    this.$interval = $interval;
  }

  $onInit() {
    this.$interval(() => this.showRemaining(), 1000);
  }

  showRemaining() { ... }
}

app.directive('clock', () => ({
  ...
  controller: ClockController
}));

At this stage, converting this directive into a component would be logical, considering that components essentially function as wrappers for directives, promoting a controller-centric approach.

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 compiler option 'esnext.array' does not provide support for utilizing the Array.prototype.flat() method

I'm facing an issue with getting my Angular 2 app to compile while using experimental JavaScript array features like the flat() method. To enable these features, I added the esnext.array option in the tsconfig.json file, so the lib section now includ ...

What are some alternative solutions when functional component props, state, or store are not being updated within a function?

Initially, I need to outline the goal. In React frontend, I display data that aligns with database rows and allow users to perform CRUD operations on them. However, in addition to actual database rows, I include dummy rows in the JSON sent to the frontend ...

What steps can I take to incorporate additional arguments into my function?

I am currently working with NodeJS, express, and passport. However, I believe this question is specifically related to JavaScript. Within my routes file, I have the following code: app.get( '/users', login_req, user.index); So, when a get requ ...

Using the v-for directive to loop through a list of items and adding a v-autocomplete with

I am facing a challenge with using a dropdown menu within a loop to select the region for each office in my list of offices. The problem lies in passing the index value to the updateRegion method so that I can correctly associate the selected region with t ...

Trying to update React and Electron, encountering the error message "global is not defined"

I have an Electron + React app that has not been updated in a couple of years, initially utilizing the following packages: "@rescripts/cli": "^0.0.13", "@rescripts/rescript-env": "^0.0.11", "electron": &quo ...

Trouble getting search filter to function properly on an array of objects in a Vue JavaScript application

Can someone help me with integrating this code into my project? Here is the code I am referencing: http://jsfiddle.net/dkmmhf5y/701/ This snippet shows my JavaScript file, please disregard the 'test' data var app = new Vue ( { el: &apos ...

Display a text box upon clicking an item

I've been curious about how to create the effect of a text box or div that appears when clicked on, similar to what you see in this. Scroll down and click on "show patchnotes"; I've been puzzled by this for a while but haven't come across a ...

Is there a way to update a JSON file using React?

I'm looking for a solution to update a JSON file in React. Is it possible? Below is the code snippet that executes when an HTML element is clicked. Ultimately, it invokes VoteTracking, the function responsible for updating the JSON file. handleC ...

In what situations is it essential to utilize the `rerender` function in the React Testing Library?

In the past, my team and I usually focused on writing React Testing Library (RTL) tests for the main parent components that contained numerous nested child components. This approach made sense and proved to be effective. The child components in question we ...

File upload failed with the Easy Upload Adapter in ckeditor

I am experiencing an issue when trying to upload an image. Despite researching the error, I have not been able to find a solution that works. My code is written in Express.js with ejs and specifically relates to the addPost.ejs file. <!DOCTYPE html& ...

Using Node.js Express to pass data from both the URL and session into a JavaScript file being served

I've been working on a web-socket application where the client connects to a game instance and the server then links the client to the corresponding Socket.io room for transmitting information. For example, connecting to '/game/abc' would lo ...

What is the process for retrieving DOM elements and JavaScript variables using PHP?

I am currently developing a PHP script that will dynamically generate tables in MySQL based on the user's input for the number of columns and column names. However, I have encountered some challenges when trying to access DOM elements and JavaScript v ...

JavaScript code is failing to render data properly within HTML documents

I am facing an issue while trying to display data extracted from JSON in HTML. Despite my efforts, the data is not showing up on the webpage. I am unsure about what might be causing this error. Any assistance in resolving this matter would be greatly appre ...

Using Struts2 to fetch data through AJAX and dynamically update a div element

Looking for advice on how to trigger an action class using JavaScript when a value is selected from a drop-down menu. The goal is to fetch data from a database and then update a table within a specific div without refreshing the entire page. The drop-down ...

Angular- Product Details

I'm currently expanding my knowledge of angular (utilizing the ionic framework with phone gap included) and I'm working on developing a single application that displays a list of data. When a user clicks on an item in the list, I want to show the ...

Creating markers from Mysql database is a simple and efficient process

On my website, I have an array of markers that I use to display locations on a Google map. The array format I currently use is: generateMarkers([['Location', lat, long], ['Location2', lat2, long2],['Location3', lat3, long]3]) ...

Save the status of checkboxes in a JSON file using boolean values of true or false

When a user submits a form, I am retrieving the values of checkboxes and storing them as an array. The simplified form structure is as follows: <!-- gym_create.html - other input fields are omitted for brevity --> <form class="create-gym" role=" ...

Possible issue with accurate indexing causing caption error with API images in React

Continuing from: Implementing a lightbox feature in react-multi-carousel for my ReactJS app My application utilizes react-images for the lightbox functionality and react-carousel-images for the carousel. The API provides a title and image data. The issue ...

How can you resize a circle in Three.js without resizing its outline?

I'm currently using a THREE.Path to generate a Circular path and then utilizing a TubeGeometry to form a circle with transparent fill and an adjustable stroke thickness. My main query revolves around the process of scaling up the Circular path dynamic ...

Transforming Form Input Fields into a Nested JSON Format with the Power of JQuery

I'm facing a challenge in converting the input fields below into a nested JSON file structure in my HTML page. Despite trying various methods, I haven't been successful yet. These inputs are retrieved through AngularJS ng-repeat. Any assistance o ...