AngularJS Service Implementing the Pub/Sub Design Pattern

I've been browsing for solutions to a problem and stumbled upon an answer provided by Mark Rajcok

angular JS - communicate between non-dependend services

However, I am struggling to fully grasp his explanation, particularly this part:

angular.forEach(event1ServiceHandlers, function(handler) {
            handler(some_data);
});

I'm uncertain if the event1ServiceHandlers array is filled with functions (referred to as handler) that are executed within this forEach loop.

It would be immensely helpful if someone could provide a clear example of setting up a publish/subscribe system.

I have two services that need to communicate with each other, but I want to steer away from using $rootScope.$broadcast. After researching, it seems like implementing a pub/sub service is the optimal approach. One of my services must call a function within the other service. However, due to one service being a dependency of the other, I cannot establish a mutual connection because of circular dependencies.

Therefore, my question is: If you have two AngularJS services (factories), how can service 1 trigger a function in service 2 when service 2 already depends on service 1? This should be done without utilizing $broadcast and $on.

Answer №1

Are the handlers in the event1ServiceHandlers array functions that are triggered within this forEach loop?

Affirmative

How can service 1 execute a function on service 2 if service 2 already depends on service 1?

To achieve this, introduce a new service called NotificationService:

.factory('NotificationService', [function() {
    var event1ServiceHandlers = [];
    return {
        // publish
        event1Happened: function(some_data) {
            angular.forEach(event1ServiceHandlers, function(handler) {
                handler(some_data);
            });
        },
        // subscribe
        onEvent1: function(handler) {
            event1ServiceHandlers.push(handler);
        }
    };
}])

Then, have service 2 register a callback function with the NotificationService:

.factory('Service2', ['NotificationService',
function(NotificationService) {
    // Event handler for event1
    var doSomething = function(someData) {
        console.log('S2', someData);
        // Actions to be performed here
    }
    // Subscribe to event1
    NotificationService.onEvent1(doSomething);
    return {
      // Define public API for Service2 here
    }
}])

Whenever service 1 needs to execute the doSomething() function on service 2, it can trigger the event1Happened event:

.factory('Service1', ['NotificationService',
function(NotificationService) {
    var someData = ...;
    return {
       // Define public API for Service1 here
       callService2Method: function() {
         // Trigger event
         NotificationService.event1Happened(someData);
       }
    }
}])

Answer №2

Within his illustration, the NotificationService emerges as a novel service that any preexisting services would rely upon. Although he presented an implementation of Service1, the functionality for Service2 remains essentially unchanged...both are dependent on NotificationService without either being aware of the other.

Service1 and Service2 individually subscribe to events by invoking

NotificationService.onEvent1(event1Happened);
and trigger events through
NotificationService.event1Happened(my_data);
.

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

Tips for saving an image that has been dragged onto the browser locally

I recently started working with Angular and decided to use the angular-file-upload project from GitHub here. I'm currently in the process of setting up the backend for my application, but I'd like to be able to display dropped files locally in th ...

Tips for implementing validation in JavaScript

I'm brand new to learning Javascript. Recently, I created a template for a login page and it's working perfectly fine. However, I am struggling with setting up validation and navigation. My goal is to redirect the user to another page if their us ...

AngularJS: Recommendations for structuring code to dynamically update the DOM in response to AJAX requests

Within Angular's documentation, there is a straightforward example provided on their website: function PhoneListCtrl($scope, $http) { $http.get('phones/phones.json').success(function(data) { $scope.phones = data; }); $scope.order ...

JavaScript - utilize regular expressions to check if the argument starts with a forward slash

Currently, I am utilizing nodejs for API testing purposes. To properly test the logic within this if statement, I am in search of a string that aligns with this specific regular expression. if (arg.match(/^\/.*/)) { // ... } Would anyone be able ...

What method does jQuery Validation use to configure the validation message?

A custom method was developed for the jQuery validation plugin to validate whether a given value meets the length requirements set during validation. The method is structured as follows: jQuery.validator.addMethod("exactLength", function(value, ...

The Res.redirect function appears to be useless within my Angular-Express project

Here is my latest project in development. 1. Building a Node/Express Server 2. Implementing Angular Routes 3. Setting up Database functions 4. Creating Controllers In the first file, I have this specific function: function requireUser(req, res, next ...

Idea: Develop a bookmarklet that generates a header form and deletes it upon submission

After much contemplation and experimentation, I have been grappling with the idea of creating a bookmarklet that displays a header when clicked on any webpage. This header will contain a small form that submits its contents to a server before disappearing. ...

Transitioning my website to incorporate Angular JS

Recently, I have been exploring AngularJS and I am quite impressed with its features. I am currently developing a website using traditional methods (php, html, css, mysql, some jQuery) and I am considering transitioning to Angular. The reason for this chan ...

Using the value from the Vuex state to set the initial value for a different parameter

I am facing an issue with utilizing an array of objects in my Vuex state to set a default value for another parameter, specifically for mainAccount: For instance: const store = new Vuex.Store({ state: { AccountNums: [ { label: 'M ...

Troubleshooting the display of API-generated lists in Angular 8

I am encountering an issue in Angular 8 when trying to display my list on a page. Below is the code from my proposal-component.ts file: import { Component, OnInit, Input } from "@angular/core"; import { ActivatedRoute, Params } from "@angular/router"; imp ...

Registration of Laravel Vue.js components

I am currently working on a Vue.js application in conjunction with Laravel. To get started, I registered Vue.js like this: import Vue from 'vue'; import VueRouter from 'vue-router'; Vue.use(VueRouter); import App from './compone ...

Transitioning from one bootstrap modal to another in quick succession may lead to unexpected scrolling problems

I'm facing a challenge with two modals where scrolling behavior becomes problematic when transitioning from one to the other. Instead of scrolling within the modal itself, the content behind it is scrolled instead. In order to address this issue, I im ...

Ways to find the image source using JavaScript/Jquery upon page loading?

I've scoured countless forums, yet a viable solution still eludes me. My objective is simple - upon page load, I want to gather all elements with the ".home" class and store them in an array called arr. Subsequently, the script should iterate through ...

The EJS template on the Express app is encountering an issue: it is unable to find the view "/id" within the views directory located at "/home/USER/Desktop/scholarship-app/views"

When attempting to render the request URL for an ID in my Express app, I encountered the following error: Error: Failed to find view "/id" in views directory "/home/USER/Desktop/scholarship-app/views" Here is a portion of my Express app code: app.get(&a ...

What is the process of implementing FFT in node.js?

Struggling with implementing FFT in node.js is proving to be quite challenging for me at the moment. Despite experimenting with three different libraries, I find them all poorly documented, which only adds to the complexity of the task. My current setup i ...

The AJAX success callback function failed to execute in cases where the dataType was set to JSONP during Cross domain Access

type = 'math'; var ajurl = "sample.com&callback=myhandler"; var datas = "cateid=" + cateid + "&type=" + type + "&pno=" + pno + "&whos=" + whos; $.ajax({ type: "GET", url: ajurl, data: datas, contentType: "application/json; ...

Various instances of controllers in Angular.js and JavaScript

I'm facing a challenge with a view that has two identical parts but different content. I want to find a way to use one controller and one view for both the left and right parts. Here's what I currently have in my HTML: <div class="board_bod ...

Issues arise when attempting to alter the background image using jQuery without browserSync being activated

I am facing an issue with my slider that uses background-images and BrowserSync. The slider works fine when BrowserSync is running, but without it, the animations work properly but the .slide background image does not appear at all. Can someone help me ide ...

Decorators do not allow function calls, yet the call to 'CountdownTimerModule' was executed

While building production files, the aot process is failing with this error message: Function calls are not supported in decorators but 'CountdownTimerModule' was called. I run the build command using npm run build -- --prod --aot and encounter ...

jQuerry's on method fails to respond to newly added elements through the clone() function

I always thought that jquery's on() function would handle events for dynamically added elements in the DOM, such as those added via ajax or cloning. However, I'm finding that it only works for elements already attached to the dom at page load. Cl ...