What is the best way to link this interval service with a view component?

Exploring the AngularJS documentation for $interval, I came across an interesting example demonstrating how to utilize $interval in a controller to create a user-friendly timer in a view. The official example code can be found on the angularJS documentation page linked here.

In an attempt to enhance modularity, I endeavored to shift the code from the example controller into a service. However, I encountered difficulties as the service wasn't being connected to the view properly. To provide a clear demonstration of this issue, I have replicated it on this plnkr link where you can experiment with the code.

The main question at hand is what specific modifications are required in the provided plnkr code so that the mytimer service is accessible in the view as a property of the controller importing the service?

To summarize, 'index.html` consists of:

<!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8>
  <title>Example - example-example109-production</title>
    <script src="myTimer.js" type="text/javascript"></script>
    <script src="exampleController.js" type="text/javascript"></script>
    <script src="app.js" type="text/javascript"></script>

    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.min.js"></script>

</head>
<body ng-app="intervalExample">

<div>
  <div ng-controller="ExampleController">
    <label>Date format: <input ng-model="mytimer.format"></label> <hr/>
    Current time is: <span my-current-time="mytimer.format"></span>
    <hr/>
    Blood 1 : <font color='red'>{{mytimer.blood_1}}</font>
    Blood 2 : <font color='red'>{{mytimer.blood_2}}</font>
    <button type="button" data-ng-click="mytimer.fight()">Fight</button>
    <button type="button" data-ng-click="mytimer.stopFight()">StopFight</button>
    <button type="button" data-ng-click="mytimer.resetFight()">resetFight</button>
  </div>
</div>
</body>
</html>

The content of app.js:

angular.module('intervalExample',['ExampleController'])

Code inside exampleController.js:

angular
.module('intervalExample', ['mytimer'])
.controller('ExampleController', function($scope, mytimer) {

    $scope.mytimer = mytimer;

});

And finally, within myTimer.js:

angular
.module('mytimer', [])
.service('mytimer', ['$rootScope', function($rootScope, $interval) {

    var $this = this;
    this.testvariable = "some value. ";

        this.format = 'M/d/yy h:mm:ss a';
        this.blood_1 = 100;
        this.blood_2 = 120;

        var stop;
        this.fight = function() {
          // Don't start a new fight if we are already fighting
          if ( angular.isDefined(stop) ) return;

          stop = $interval(function() {
            if (this.blood_1 > 0 && this.blood_2 > 0) {
              this.blood_1 = this.blood_1 - 3;
              this.blood_2 = this.blood_2 - 4;
            } else {
              this.stopFight();
            }
          }, 100);
        };

        this.stopFight = function() {
          if (angular.isDefined(stop)) {
            $interval.cancel(stop);
            stop = undefined;
          }
        };

        this.resetFight = function() {
          this.blood_1 = 100;
          this.blood_2 = 120;
        };

        this.$on('$destroy', function() {
          // Make sure that the interval is destroyed too
          this.stopFight();
        });

}])

    // Register the 'myCurrentTime' directive factory method.
    // We inject $interval and dateFilter service since the factory method is DI.
    .directive('myCurrentTime', ['$interval', 'dateFilter',
      function($interval, dateFilter) {
        // return the directive link function. (compile function not needed)
        return function(scope, element, attrs) {
          var format,  // date format
              stopTime; // so that we can cancel the time updates

          // used to update the UI
          function updateTime() {
            element.text(dateFilter(new Date(), format));
          }

          // watch the expression, and update the UI on change.
          scope.$watch(attrs.myCurrentTime, function(value) {
            format = value;
            updateTime();
          });

          stopTime = $interval(updateTime, 1000);

          // listen on DOM destroy (removal) event, and cancel the next UI update
          // to prevent updating time after the DOM element was removed.
          element.on('$destroy', function() {
            $interval.cancel(stopTime);
          });
        }
      }]);;

You can investigate all of the code mentioned above in "working" form by accessing this plnkr link where you can troubleshoot and pinpoint the solution to the problem. What precise adjustments should be made to the aforementioned code to allow users to interact with the service through the view effectively?

Answer №1

Initially, there was an issue with injecting the $interval into the mytimer service and attempting to use it.

Additionally, scope problems were present within the mytimer service:

stop = $interval(function() {
    if (this.blood_1 > 0 && this.blood_2 > 0) {
        this.blood_1 = $this.blood_1 - 3;
        this.blood_2 = $this.blood_2 - 4;
    } else {
        this.stopFight();
    }
}, 100);

When defining a function, a new scope is created, leading to the reference of this to point to a new scope. To address this, you can utilize bind or make use of the $this variable defined in line 5. (Alternatively, in ES2015, you could employ arrow functions).

Furthermore, the module exampleController was declared twice in both app.js and mytimer.js.

Refer to this functional Plunker for clarification:
http://plnkr.co/edit/34rlsjzH5KWaobiungYI?p=preview

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

Guide for sending token through Authorization in Laravel 8 API

I am currently utilizing Laravel 8 as an API REST and encountering an issue where my token is null when sent in the AJAX request. I have successfully handled logins and requests without tokens, but this specific scenario has me puzzled. Within my JavaScri ...

React - Error occurred when parsing module: Unexpected Token. It is recommended to use a suitable loader to manage this file format

As a beginner in using React, I might be making obvious mistakes and I apologize for that. After researching similar bugs on various platforms like StackOverflow and GitHub, I couldn't find a solution that works for my specific issue. Here is the erro ...

Why does my jQuery map code work in version 2.0 but not in version 3.0?

I've encountered an error with a jQuery map snippet that I'm trying to troubleshoot. It was working fine under jQuery 2, but after upgrading to version 3, it doesn't work anymore and I can't figure out why. Feeling stuck! var menuIte ...

What could be the reason for my mongoose model failing to save in mongodb?

I am experiencing an issue with my simple Post model and route for creating posts. After submitting a new post using Postman, the request hangs for a moment before returning an error in JSON format. The model data is never saved successfully. Below is the ...

Posting several pictures with Protractor

In my test suite, I have a specific scenario that requires the following steps: Click on a button. Upload an image from a specified directory. Wait for 15 seconds Repeat Steps 1-3 for all images in the specified directory. I need to figure out how to up ...

What is the reason for not using ng-attr-width to set the width of this SVG?

I am facing a challenge in understanding ng binding on a simple web page I created to experiment with: <html ng-app="AngularSVGTestApp"> <head> <title>Angular SVG Test</title> <style> svg { backgro ...

Leverage information extracted from the Node.js function

As I dive into the world of NodeJS, a particular issue arose while working with the getCurrentWeather() function. It's asynchronous nature means that it loads instantly upon app start and writes data to variables. However, when attempting to use these ...

What could be causing my fetch() function to send a JSON body that is empty?

I've been struggling with sending JSON data using fetch as the backend keeps receiving an empty object. In my Client JS code, I have the following: const user = "company1"; const username = "muneeb"; const data = {user, username}; fetch("http://127. ...

Executing a task within a Grunt operation

I have integrated Grunt (a task-based command line build tool for JavaScript projects) into my project. One of the tasks I've created is a custom tag, and I am curious if it is feasible to execute a command within this tag. Specifically, I am working ...

Is there any benefit to making the SVG elements width and height 100%?

The Angular Material documentation app features an SVG Viewer that is able to scale the SVG content to fit the container using the following function: inlineSvgContent(template) { this.elementRef.nativeElement.innerHTML = template; if (this.sca ...

Vue: nesting components within components

Looking for a clever solution to create a nested component system with efficient rendering? Check out the code snippet below: custom-tab.vue (child component) <template> <slot></slot> </template> <script> export def ...

applying a timeout for the .on(load) event

My goal is to dynamically load images using .on('load') in the script below: .on('load', function() { if (!this.complete || typeof this.naturalWidth == "undefined" || this.naturalWidth == 0) { alert('broken i ...

Tips for incorporating user access control logic into a lazy-loaded Angular Monorepo application without embedding the logic in the main application

In our current project, we are developing an Angular application utilizing the Angular monorepo structure. This setup includes a parent application and several children applications, with the parent application located in the `app` folder and the children ...

Change the div attribute when clicking on a corresponding link

For the full code, please visit: https://plnkr.co/edit/6TTLVcsXLV7C1qXSMQV0?p=preview Here is an angular ui bootstrap accordion with nested panels: <uib-accordion close-others="oneAtATime"> <div ng-repeat="sub in subdivisions"> < ...

Seeking particular section of online content in an asynchronous manner

Is there a method for asynchronously requesting a specific portion of a web resource (like the initial 100 bytes) using JavaScript? I believed this could be accomplished through XmlHttpRequest by adjusting its Range header. However, if the server utilizes ...

Having trouble with installing node-steam on your node.js server?

I recently attempted to install node-steam and encountered a significant error. Can anyone provide guidance on how to resolve this issue? Is the mistake on my end? ... gyp ERR! configure error gyp ERR! stack Error: Can't find Python ex ...

Problems with the navigation bar scrolling in Bootstrap

The project I'm currently working on is located at zarwanhashem.com If you'd like to see my previous question along with the code, you can check it out here: Bootstrap one page website theme formatting problems Although the selected answer help ...

Display the jQuery validation message in the final td cell of the table

JavaScript Animation Library rules:{ gender: { required: true }, }, messages:{ gender: { required: "Please indicate your gender" }, }, errorPlacement: function (error, element) { if (element.attr("type") == "radio") { ...

Tick the checkboxes that are not disabled, and leave the disabled ones unchecked

Currently, I am employing Jquery for the purpose of checking and unchecking checkboxes. However, some of these boxes are disabled, thus there is no need for them to be checked. Is there a method by which I can instruct the script to disregard disabled che ...

Encountering mixed content error on webpack development server

My React based website is currently running on Cloud9 using webpack-dev-server, which serves content over https. However, I have encountered an issue when attempting to make ajax (network) requests to external http links. The error message I receive is: ...