Challenge: Solution Review

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

We'll cover the following

Solution #

Press + to interact
class Model{
constructor(){
this.senderName = "";
this.recieverName = "";
this.emailTitle = "";
}
setSenderName(senderName){
this.senderName = senderName;
}
getSenderName(){
return this.senderName;
}
setRecieverName(recieverName){
this.recieverName = recieverName;
}
getRecieverName(){
return this.recieverName;
}
setEmailTitle(emailTitle){
this.emailTitle = emailTitle;
}
getEmailTitle(){
return this.emailTitle;
}
}
class View{
constructor(){
this.presenter = null;
}
registerWith(presenter){
this.presenter = presenter;
}
sendEmail(to,fromWhom, emailTitle){
this.presenter.sendEmail(to,fromWhom, emailTitle)
}
displayEmailInfo(senderName,recieverName, emailTitle){
console.log("Email From: " + senderName + " To: " + recieverName + " Title: " + emailTitle);
}
}
class Presenter{
constructor(view){
this.view = view;
this.model = null;
}
setModel(model){
this.model= model;
}
getView(){
return this.view;
}
sendEmail(to,fromWhom, emailTitle){
this.model.setEmailTitle(emailTitle)
this.model.setSenderName(fromWhom)
this.model.setRecieverName(to)
this.view.displayEmailInfo(this.model.getSenderName(), this.model.getRecieverName(),this.model.getEmailTitle())
}
}
var model = new Model()
var view = new View()
var presenter = new Presenter(view)
presenter.setModel(model)
view.registerWith(presenter)
presenter.getView().sendEmail("Rachel", "Joey", "Rent Discussion")
presenter.getView().sendEmail("Monica", "Phoebe", "Smelly Cat Draft")

Explanation

The challenge requires you to use the MVP pattern to implement an email sending system. Hence, it has three components, the Model, the View, and the Presenter. Let’s discuss them one-by-one.

Model

class Model{

    constructor(){
        this.senderName = "";
        this.recieverName = "";
        this.emailTitle = "";
    }

    setSenderName(senderName){
        this.senderName = senderName;
    }

    getSenderName(){
        return this.senderName;
    }

    setRecieverName(recieverName){
        this.recieverName = recieverName;
    }

    getRecieverName(){
        return this.recieverName;
    }

    setEmailTitle(emailTitle){
        this.emailTitle = emailTitle;
    }

    getEmailTitle(){
        return this.emailTitle;
    }

}

As mentioned in the question, the Model contains the following properties:

  • senderName: The name of the person sending the email.

  • recieverName: The name of the recipient.

  • emailTitle: The email title.

It also has the set and get functions for each property to set and retrieve their values. We will need to access these values when displaying them in the view.

View

class View{
    constructor(){
        this.presenter = null;
    }

    registerWith(presenter){
        this.presenter = presenter;
    }

    sendEmail(to,fromWhom, emailTitle){
        this.presenter.sendEmail(to,fromWhom, emailTitle)
    }

    displayEmailInfo(senderName,recieverName, emailTitle){
        console.log("Email From: "  + senderName + " To: " + recieverName + " Title: " + emailTitle);
    }

}

You were already provided with the registerWith and the displayEmailInfo functions. As you know, the presenter reacts to the user actions on the view side; hence, registerWith initializes the presenter so the view can inform it of the user actions.

The displayEmailInfo displays the name of the sender, recipient, and the email title.

You had to write the definition of sendEmail. As you can see, it takes three parameters: to, fromWhom, and emailTitle. So when a user wants to send an email, they will need to enter all three pieces of information. When the user performs this action, the view informs the presenter about it by calling the presenter.sendEmail function and passing it all the information. We will discuss what the presenter's sendEmail function does later.

Presenter

class Presenter{
    constructor(view){
        this.view = view;
        this.model = null;
    }

    setModel(model){
        this.model= model;
    }

    getView(){
        return this.view;
    }
   //code...
}

The presenter acts as the middle man between the model and the view. Hence, it initializes the view in its constructor and sets the model using setModel function. The presenter also defines the getView function, which returns the current view. This function is used by the presenter outside the class to access the view’s properties/functions.

Lastly, you had to define the sendEmail function for the presenter.

sendEmail(to,fromWhom, emailTitle){
     this.model.setEmailTitle(emailTitle)
     this.model.setSenderName(fromWhom)
     this.model.setRecieverName(to)
     this.view.displayEmailInfo(this.model.getSenderName(), this.model.getRecieverName(),this.model.getEmailTitle())
}

As discussed above, this function is invoked when the user performs the action of sending an email on the view side. So when changes are made on the view side, that is, the information such as sender name, recipient name, and the title is filled, it is the presenter’s task to update the model. Hence it calls model's set functions to update the value of each property. Now that the model has been updated, the presenter again must update the view to display the new information. Hence, it calls the view.displayEmailInfo function passing to it the new values that it retrieves from the model using the get functions for each property.


Let’s discuss the MVVM pattern in the next lesson.