SoftTimur
SoftTimur

Reputation: 5540

Messaging between two angularjs services

I want to realise a communication (by sending and receiving messages) between two services in an angularjs web site. Actually, messaging would be unnecessary if we could merge two services into one service. But the reality is I don't want to merge them for some reason. As mutual dependency of two services is not possible (please correct me if i am wrong), it seems that I have to let them communicate via messaging.

Let me explain... Assume we have two services serA and serB. In serA, we have

this.startTask1 = function () {
    console.log("B, please do task 1")
    sendMsgFromAtoB("B, please do task 1")
}

this.receiveMsgFromBtoA = function (msg) {
    if (msg === "A, B has done task 1") {
        console.log("A, B has done task 1"); 
        console.log("task 1 is finally over!!!")
    }
}

in serB, we have

this.receiveMsgFromAtoB = function (msg) {
    if (msg === "B, please do task 1") {
        console.log("B is doing task 1... Done!");
        sendMsgFromBtoA("A, B has done task 1")
    }
}

As a result, if a controller runs serA.startTask1(), I expect to see in the console:

B, please do task 1
B is doing task 1... Done!
A, B has done task 1
task 1 is finally over!!!

To this end, I need to make sendMsgFromAtoB and sendMsgFromBtoA, and complete receiveMsgFromAtoB and receiveMsgFromBtoA. However, I don't know by which mean I could implement them.

I have used $window.addEventListener("message", ...) (ie, postMessage) and $window.addEventListener("storage", ...) (ie, StorageEvent). But StorageEvent is not fully cross-platform, I am not sure postMessage is good for messaging inside 1 page.

So does anyone have a good idea?

Upvotes: 0

Views: 160

Answers (2)

georgeawg
georgeawg

Reputation: 48968

A circular dependency is always the sign of mixing of concerns, which is a really bad thing. Miško Hevery, one of the authors of AngularJS, explains a nice solution on his awesome blog. In short, you probably have a third service hidden somewhere, which is the only part of your code really needed by the two others.

Change:

+---------+      +---------+
|    A    |<-----|  B      |
|         |      |  |  +-+ |
|         |      |  +->|C| |
|         |------+---->| | |
|         |      |     +-+ |
+---------+      +---------+

To this:

                         +---------+
+---------+              |    B    |
|    A    |<-------------|         |
|         |              |         |
|         |    +---+     |         |
|         |--->| C |<----|         |
|         |    +---+     +---------+
+---------+

See also,

Upvotes: 1

Estus Flask
Estus Flask

Reputation: 223114

You've already got event bus in Angular 1.x app, $rootScope. Unless you're willing to introduce third-party libraries to the project (RxJS, EventEmitter3 or other pub/sub implementations), there's no reason to look any further.

$rootScope.$on('foo', (e, arg1, arg2) => { ... });
...
$rootScope.$emit('foo', arg1, arg2);

Upvotes: 1

Related Questions