Challenge: Solution Review

This lesson will explain the solution to the problem from the last coding challenge.

We'll cover the following

Solution #

Console

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 the color. It is set to red 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.