Observing the state of a variable within a directive using a service from a different module

I currently have two modules named "core" and "ui".

The "ui" module has a dependency on the "core" module. Below is the code for my core.js file:

var core = angular.module('core', [ 'ngRoute' ]);

// Services
core.service('httpInformationService', function() {
    this.requestCount = 0;
    this.responseCount = 0;

    this.incrementRequest = function() {
        this.requestCount++;
        console.log('incrementRequest:' + this.requestCount);
    };

    this.incrementResponse = function() {
        this.responseCount++;
    }

    this.decrementRequest = function() {
        this.requestCount--;
        console.log('decrementRequest:' + this.requestCount);
    };

    this.decrementResponse = function() {
        responseCount--;
    }

    this.getRequestCount = function() {
        return requestCount;
    }

    this.getResponseCount = function() {
        return responseCount;
    }
});

// Service provider
core.provider("httpServiceInformationProvider", function() {
    var provider = {};

    provider.$get = ['httpInformationService', function( service ) {
        return service;
    }];

    return provider;
});

// HTTP Interceptor
core.factory('coreHttpInterceptor' ,function( httpInformationService ){
    var coreHttpInterceptor = {
        request: function(config) {
            httpInformationService.incrementRequest();
            return config;
        },
        response: function(response) {
            httpInformationService.decrementRequest();
            return response;
        }
    }

    return coreHttpInterceptor;
});


var config = {
    base_url: enviromnent_url,
}

core.value('config', config);

core.config(function( $interpolateProvider ) {
    $interpolateProvider.startSymbol( "[[" ).endSymbol( "]]" );
});

core.config(function( $httpProvider ) {
   $httpProvider.interceptors.push('coreHttpInterceptor');
});

Here's the code from my ui.js file:

 var ui = angular.module('ui',[ 'core' , 'ui.bootstrap' ]);

ui.directive( "shLoadify" , function( httpServiceInformationProvider ){
    return {
        restrict: "AE",
        link: function(scope, element, attrs) {
            element.bind( "click", function() {
                element.text("Loading...");
                element.prop( "disabled", true );
            });
        },
        controller: function($scope) {
            $scope.$watch('httpServiceInformationProvider', function(oldValue, newValue){
                console.log(oldValue + ' ' + newValue);
            }, true);
        }
    }
});

In my controller, I am attempting to access the `requestCount` property of `httpInfomationService` using `$scope.watch. However, the problem I'm facing is that both `newValue` and `oldValue` are always null. Why could this be happening?

Answer №1

Method 1

To trigger an action whenever the requestCount variable in a service changes, you can utilize broadcasting/emitting and listening through the on method. However, passing the scope in your service is not recommended.

var app = angular.module('app',['app1']);

app.service('myService',function($rootScope){
  this.requestCount=1
  this.incrementRequestCount=function(){ 
    this.requestCount++
    $rootScope.$broadcast('requestCountChanged', { message: this.requestCount });
  }.bind(this)

})


app.controller('myController',['$scope','myService',function($scope,myService){

  $scope.$on('requestCountChanged', function(event, args) {
      // Updated requestCount available in args
    }); 

   $scope.click= myService.incrementRequestCount;

}])

var app1 = angular.module('app1',[]);
    app1.controller('mySecondController',['$scope','myService',function($scope,myService){

      $scope.$on('requestCountChanged', function(event, args) {
            // Updated requestCount available in args
        }); 

    }])

Method 2

An alternative approach without passing scope into the service:

var app = angular.module('app',['app1']);

app.service('myService',function(){
  this.requestCount=1
  this.incrementRequestCount=function(){ 
    debugger;
    this.requestCount++
  }.bind(this)

})


app.controller('myController',['$scope','myService','$rootScope',function($scope,myService,$rootScope){

   $scope.click=function(){
     myService.incrementRequestCount();
     $rootScope.$broadcast('requestCountChanged', { message: myService.requestCount });

   }  

}])

var app1 = angular.module('app1',[]);
    app1.controller('mySecondController',['$scope','myService',function($scope,myService){

      $scope.$on('requestCountChanged', function(event, args) {

            // Updated requestCount available in args
        }); 

    }])

Method 3

You can only watch properties that are present in the scope. Add requestCount to your scope to detect changes using watch and then apply the broadcast/emit approach.

var app = angular.module('app',['app1']);

app.service('myService',function(){
  this.requestCount=1
  this.incrementRequestCount=function(){ 
    debugger;
    this.requestCount++
  }.bind(this)

})


app.controller('myController',['$scope','myService','$rootScope',function($scope,myService,$rootScope){

    $scope.requestCount=myService.requestCount
    $scope.$watch('requestCount',function(n,o){
      debugger;
      if(n!=o)
      {
          $rootScope.$broadcast('requestCountChanged', { message: n });
      }
    })
   $scope.click=function(){
     myService.incrementRequestCount();
     $scope.requestCount=myService.requestCount


   }  

}])

var app1 = angular.module('app1',[]);
    app1.controller('mySecondController',['$scope','myService',function($scope,myService){

      $scope.$on('requestCountChanged', function(event, args) {

            // Updated requestCount available in args
        }); 

    }])

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

Is there a way to have text appear in a popup when I reach it while scrolling?

Is there a way to make the textblocks on my website increase in size or pop up when I scroll down to them? I've attempted to search for a solution online but have been unsuccessful in finding one. ...

Calculating the function using data in a Vue component

Here is a Vue component along with some data: Vue.component('receipt', { template: '#receipt-template', data: function() { return { tip: 8.50 }; }, computed: { subtotal: function( ...

Using cascading style sheets to switch a page into editing mode

Is it possible to change the view of a page after clicking a button without using javascript, and instead relying solely on CSS? I want to display a page with information where users can click an edit button and make changes within the same view rather th ...

how to protect your javascript and php code

I have a question about "injection", specifically javascript injection which I find confusing. Suppose I have a javascript function that sends an AJAX request to get a user's permission level, and then uses an if statement to assign power based on th ...

MariaDB won't generate JSON output for a column that has a JSON data type

Currently, I am utilizing MariaDB and phpMyAdmin to effectively manage my database. Within one of my tables, I have a specific field that is defined as type json, or alternatively longtext. However, whenever I execute a SELECT query using JSON_EXTRACT(fiel ...

Extracting Query Parameters from a Successful Ajax Call in Javascript

How can I extract data from the success response? Take a look at my code snippet: $.ajax({ async: 'true', url: 'https://exampleapi.com/product', type: 'GET', data: {page: idQuery}, success:(response => { v ...

Guide to aligning the center of a div with the mouse cursor using JavaScript during mouse movement

I've been trying to center a div element with the mouse cursor, following its movement. However, the current code I have offsets the positioned div from the cursor instead of aligning it perfectly. PROCESS The concept behind my code is to display an ...

Make the div disappear upon clicking the back button in the browser

When a user selects a thumbnail, it triggers the opening of a div that expands to cover the entire screen. Simultaneously, both the title and URL of the document are modified. $('.view-overlay').show(); $('html,body').css("overflow","h ...

How can I display the updated save button text in an Angular form?

Using an Angular 1 form to display a changed save button text can be achieved with the following settings: (disabled) save - displayed when the form is initial (enable) save - displayed when the form is edited or re-edited after being saved (enable) save ...

The slash character is escaped by the RegExp constructor, but the dot character is

Consider the following code: console.log(new RegExp('.git')); console.log(new RegExp('scripts/npm')); which produces the following output: /.git/ /scripts\/npm/ The puzzling question here is - why does it escape the slash in &a ...

Checking for collisions among numerous elements in JS: An insightful guide

I have created 40 images with random positions, however, some of them collide in certain cases. My question is how to prevent collisions and assign new positions if they do occur? Below is my code along with comments for clarity. $( document ).ready(fun ...

I'm trying to display hidden forms on a webpage when a button is clicked using the DojoToolkit, but I'm having trouble figuring out what's going wrong with my code

Currently, I am trying to grasp the concepts of Dojotoolkit and my objective is to display a form when a button is clicked. Upon reviewing other examples, my code seems correct to me; however, there appears to be something crucial that I am overlooking but ...

Troubleshooting Angular MIME problems with Microsoft Edge

I'm encountering a problem with Angular where after running ng serve and deploying on localhost, the page loads without any issues. However, when I use ng build and deploy remotely, I encounter a MIME error. Failed to load module script: Expected a ...

What strategies can be implemented to maximize the effectiveness of Office ribbon commands within an AngularJS application?

Currently, I have developed an Office add-in using AngularJS (version 1.4) and ASP.NET MVC 4.5. The Angular controller and service JS files contain a significant amount of functionality that has already been implemented. Lately, I have been exploring the ...

Tips for enhancing the appearance of a React component

I have a redux form that doesn't look great, and I would like to style it. However, my project uses modular CSS loaders. The styling currently looks like this: import styled from 'styled-components'; const Input = styled.input` color: #4 ...

A Step-by-Step Guide on Importing Components in Vue.js

I have defined the following component as shown below: import Vue from 'vue'; import Datepicker from 'vuejs-datepicker'; Vue.component('DatePicker', { template: ` <datepicker name="date"></datepicker> ` ...

Run the jQuery script once it has been successfully loaded using jQuery's .load method

On the Index.html page, there is a select box labeled #choose_content_to_load and a div named #get_loaded_content <select id="choose_content_to_load"> <option>Some content from the page content.html and div #content</option> </select ...

Executing a js.erb template while submitting a form with AJAX in a Rails application

My form setup looks like this: <div class= "parent-container"> <%= form_with scope: @company, url: companies_path, html: { class: "form-inline", remote: true, "data-type" => :js, id: "new-company-create" }, local: true do |f| %> <d ...

Issue with reflect metadata in Next.js edge runtime causing functional problems

Currently, I am utilizing a package in my upcoming 13 app that incorporates reflect metadata. Unfortunately, during the next build process, an error occurs for which I haven't been able to find a solution. ../../eshop-sdk-js/node_modules/reflect-metad ...

Tool for controlling the layout of the viewport with Javascript

I have experience using ExtJS in the past to create dashboards, and one of my favorite features is the full-screen viewport with a border layout. This allows for easy splitting of a dashboard into panels on different sides without creating excessive scroll ...