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

The npm request was unsuccessful due to a self-signed certificate within the certificate chain causing the failure

I am attempting to launch a React Native project using Expo from this site npm install expo -g expo init AwesomeProject npm start However, when running npm start, I encounter the following error: npm ERR! code SELF_SIGNED_CERT_IN_CHAIN npm ERR! er ...

Encrypting and decrypting data using RSA in TypeScript

Currently, I am utilizing Angular 4 to develop the front end of my application. For authentication, I have integrated OAuth2 on the backend (which is created using Spring in Java), ensuring that only authorized individuals can access my app. However, ther ...

Unable to render pages with ng-view in Angular.js

I am facing an issue with my Angular.js application where the pages are not loading when using ng-view. When I type the URL http://localhost:8888/dashboard, the pages should be displayed. Here is an explanation of my code: view/dashboard.html: <!DO ...

Combining the elements within an array of integers

Can anyone provide insight on how to sum the contents of an integer array using a for loop? I seem to be stuck with my current logic. Below is the code I've been working on: <p id='para'></p> var someArray = [1,2,3,4,5]; funct ...

Utilizing an additional parameter in React to dynamically change the API URL

Hello everyone! I'm facing a slight issue with one of my React applications: I'm attempting to retrieve Weather alerts using an API. Here's how my App.js file is set up: import React, { Component } from 'react'; import './App ...

What is the best way to detect the presence of the special characters "<" or ">" in a user input using JavaScript?

Looking to identify the presence of < or > in user input using JavaScript. Anyone have a suggestion for the regular expression to use? The current regex is not functioning as expected. var spclChar=/^[<>]$/; if(searchCriteria.firstNa ...

Tips on managing and responding to external events in ngapp

Currently, I'm in the process of constructing an angular application within the SharePoint environment (although this query does not pertain to SharePoint). I've created a page that contains a div with an angular app directive (comprising a form ...

Using Javascript outside of the AngularJS environment

I am trying to utilize Javascript functions outside the controller in Angular JS instead of using a service within a module. Is this allowed? For instance: var UrlPath="http://www.w3schools.com//angular//customers.php" //this section will store all the f ...

Tips for assigning dynamic values to ng-model in AngularJS

When a user clicks, I am dynamically appending a div to the DOM. In order to capture the values entered by the user, I need to use ng-model for input fields. Since I cannot predict how many divs the user will append, I want to make the ng-model values dyna ...

What is the method for retrieving the index of an array from an HTML element?

Howdy! Within my Vue application, I have the ability to create multiple individuals: <div v-for="newContent in temp" :key="newContent.id" @click="showId(newContent.id)" v-show="true"> <!-- ...

Can we access local storage within the middleware of an SSR Nuxt application?

My Nuxt app includes this middleware function: middleware(context) { const token = context.route.query.token; if (!token) { const result = await context.$api.campaignNewShare.createNewShare(); context.redirect({'name': &a ...

Trying out a Controller with Jasmine in Karma

I'm trying to troubleshoot a controller issue and running into an error. Error: Object # has no method 'apply'. ReferenceError: inject is not defined The unit-test.js file looks like this: define(['angular', 'myAp ...

Extension for Chrome

My goal is to develop a Chrome extension that, when a specific button in the extension is clicked, will highlight the current tab. However, I'm encountering some challenges. Currently, I have document.getElementById("button").addEventListen ...

Reduce the amount of code in conditional statements

Is there a way to streamline the following code- <div className="App"> <Checkbox parameter={parameter1} setParameter={setParameter1}></Checkbox> { parameter1.country && parameter1.category ? < ...

Filtering data in AngularJS by parsing JSON records

I have a JSON file containing restaurant information and I need to display the data by grouping them based on their respective address fields. For example, all restaurants with the address 'Delhi' should be shown first, followed by those from &ap ...

Utilizing nested grouping in mongoose schemas

I am facing a challenge while attempting to execute a nested group query in MongoDB. Is there a way to group data by both date and campaign ID, ensuring that each campaign ID contains a nested array of creatives with their respective data (views and clicks ...

``Are you looking to create multiple canvases in a loop?

I've managed to get this command working exactly as I wanted: http://jsfiddle.net/m1erickson/64BHx/ However, I didn't anticipate how challenging it would be to turn the drawing into reality here: What I attempted to do is illustrated in this li ...

Hovering over the child element, instead of the parent

I'm working on implementing a highlight feature for my website. The structure of the HTML looks something like this: <div> <!-- this is the main container --> <div> content ... </div><!-- a child element --> < ...

What is the best way to implement an Angular application within the child routes of another Angular application?

Is it possible to load an Angular app using lazy-loading (when a specific route is hit by users) into another Angular app without compiling the first one for use in the second? This is the Routing-Module of the app to nest into an Angular app: const upgr ...

Attempting to utilize a for loop in JavaScript to condense code, however encountering a "not defined" error

I'm relatively new to working with javascript and currently attempting to enhance the following code snippet (which has been tested and is functioning correctly): // snail 1 // var s1 = document.createElement("div"); s1.id = snail1.id; s1.className = ...