One of the widely used pattern in JavaScript is the Observer pattern. Every events you use on your browser (click, keypress, hover, custom events etc.) are the example of observer pattern.
This pattern is also called Publish-Subscribe pattern.
This pattern is well defined by GOF in their book “Design Patterns: Elements of Reusable Object-Oriented Software” as
“One or more observers are interested in the state of a subject and register their interest with the subject by attaching themselves. When something changes in our subject that the observer may be interested in, a notify message is sent which calls the update method in each observer. When the observer is no longer interested in the subject’s state, they can simply detach themselves.”
In a simple term consider that you are a Netflix USER and you subscribe to the Netflix streaming service by paying monthly rental. When you subscribe, Netflix puts you in the list of users who has subscribed for its services. Whenever a new series or movies are released it notify all the subscribers from the list via email or SMS. If you stop paying monthly rental it automatically removes you from the list i.e. unsubscribes you and do not notify you anymore.
Here Netflix is a Subject and the users are Observers. Whenever the Subject has new things, it notify the Observers.
If you know Angular, you must have used two way binding using syntax [( )] also called Banana Box. This is indeed the implementation of observer pattern.
Other frameworks/libraries which has observable are Knockout, dojo, JQuery , RxJs, React.
Lets create a working example using vanilla JavaScript.
Use case: there is a form on your web app which collects user details. When user fill the form, his/her details are displayed below form.
//A simple HTML doc for modeling observer pattern.
//we have two input fields here which ask user to enter
//first name and last name.
//when user enter the data, the corresponding observer section
//gets updated(notified)
//file name - main.html<!doctype html><html> <head> <title>Observable</title> </head> <body> <div class="firstName"> <label for ="fName">FirstName</label> <input type="text"
name = "firstName"
id="fName"
placeholder ="Enter first name"> </div> <div class="lastName"> <label for="lName">Last Name</label> <input type="text"
name="lastName"
id="lName"
placeholder="Enter last name"> </div> <div> <button type="submit">Submit</button> </div> <hr><!-- the observer section --> <div class="observer-section"> <h4> you entered below data</h4> <p class="data1"> </p> <p class="data2"> </p> </div> </body></html>
now lets create a simple observable class having three methods on its prototype, subscribe(), unsubscribe(), and notify().
//the observable function.
//observer.jsfunction Observable(){ this.observers = []}Observable.prototype.subscribe = function(f){ this.observers.push(f);}Observable.prototype.unsubscribe = function(f){ this.observers = this.observers.filter(
subscriber => subscriber !== f
);
}Observable.prototype.notify = function(data){ this.observers.forEach(observer => observer(data));}
now we have our HTML form and the Observable constructor function. lets integrate them to see the magic of observer pattern.
//file name - main.jsconst fName = $(".firstName input"), lName = $(".lastName input"), fNameData = $(".data1"), lNameData = $(".data2"), updateFname = inputVal => fNameData.text(inputVal), updateLname = inputVal => lNameData.text(inputVal), fNameObserver = new Observable(), lNameObserver = new Observable();fNameObserver.subscribe(updateFname);lNameObserver.subscribe(updateLname);fName.on('keyup', e=>fNameObserver.notify(e.target.value));lName.on('keyup', e=>lNameObserver.notify(e.target.value));// *note - I have used JQuery for DOM manupulation.
you can try this code here on codepen or on jsfiddle to see the working example.
Reference