Challenge: Solution Review
This lesson will explain the solution to the problem from the last coding challenge.
We'll cover the following
Solution #
Explanation
This challenge required you to use the MVVM pattern to write a program that changes the color of the text “green”, “red”, or “blue” when written in the input field.
It is divided into three components: the Model, ViewModel, and View. Let’s take a look at them one-by-one.
Model
class Model{
constructor(){
this.model = {color: "red"};
this.observers = [];
}
//code...
The Model
constructor consists of the following properties:
-
model
: The object containing thecolor
. It is set tored
by default. -
observers
: This is the list containing all the observers of the model.
Since the Model
is a subject, it also contains the subscribe
function to register an observer
.
subscribe(observer){
this.observers.push(observer);
}
It also contains the notifyObservers
function, which informs the observer of the changes that occur in the model. If you look at the code below, you’ll see that it calls the observer function, passing it the updated value in the Model
.
notifyObservers(attrNm, newVal){
for(var i = 0; i < this.observers.length; i++){
this.observers[i](attrNm, newVal);
}
}
It has the getCurrentColor
function to retrieve the current color
value from model.
getCurrentColor(key){
return this.model[key];
}
It also has the setColor
function, which can be used to set the value of the color attribute in the model.
setColor(key, value){
this.model[key] = value;
this.notifyObservers(key, value);
}
}
As you can see, when the new value is set, the notifyObservers
function is called to inform the observer of this change. But what is the observer here? Our viewmodel is the observer that looks out for any changes in the model so it can update the view accordingly. So let’s discuss it next.
ViewModel
class ViewModel{
constructor(model){
this.bind = function(viewElement, modelElement){
viewElement.style.color = model.getCurrentColor(modelElement);
model.subscribe(function(attrNm, newValue){
var elem = document.getElementById(attrNm);
if(newValue == "red"){
elem.style.color = "blue"
}
else if(newValue == "green"){
elem.style.color = "red"
}
else if(newValue == "blue"){
elem.style.color = "green"
}
});
viewElement.addEventListener('input', function(){
model.setColor("color", viewElement.value);
});
}
}
}
The constructor
initializes the bind
function that binds the model element to the view element.
It sets the color
of the viewElement
equal to the color value retrieved from the model
(using getCurrentColor
function). This is the reason you see red
as the default text color in the input field.
viewElement.style.color = model.getCurrentColor(modelElement);
Next, it calls the subscribe
function to which it passes the callback function, which is invoked when a change occurs in the model. Meaning, whenever the value of color
in the model changes, it will notify the observer (the callback in our case). It gets invoked with the updated values so it can update the view as well.
As you know, the question required us to change the color of “green” text to red, “red” text to blue, and “blue” text to green. So we use a series of if conditions to update the color of the text in view according to this rule:
model.subscribe(function(attrNm, newValue){
var elem = document.getElementById(attrNm);
if(newValue == "red"){
elem.style.color = "blue"
}
else if(newValue == "green"){
elem.style.color = "red"
}
else if(newValue == "blue"){
elem.style.color = "green"
}
});
The above scenario deals with the case when the changes made in the model are to be reflected on the user interface. The code below is for when the model needs to reflect the changes made on the UI side.
viewElement.addEventListener('input', function(){
model.setColor("color", viewElement.value);
});
We attach an event listener to the viewElement
so that whenever a user enters a color in the input field, model.setColor
function gets called. It uses the view element’s value to update the model’s value accordingly.
View
Color: <input type="text" name = "color" id="color">
The view is a simple HTML code that creates an input field for the color. This allows the user to interact and enter the color in the field.
var nameInput = document.getElementById('color');
var model = new Model()
var viewModel = new ViewModel(model);
viewModel.bind(nameInput, 'color');
On the JavaScript side, we get the input element and store it in nameInput
. Next, we initialize the viewModel
and model
, and call the view model’s bind
function to bind the view element to the model element, color
.
This marks the end of this course! Now you know about all the major design patterns in JavaScript and how you can use them to solve a problem given to you in an interview.