Blog>
Snippets

Applying the MVC Pattern in JavaScript

Write a small MVC application example in JavaScript to demonstrate the value of architectural pattern knowledge for code scalability and maintenance.
// The Model represents the data and business logic

class TodoModel {
  constructor() {
    this.todos = [];
  }

  addTodo(todoText) {
    this.todos.push({ id: Date.now(), text: todoText, done: false });
  }

  removeTodo(id) {
    this.todos = this.todos.filter(todo => todo.id !== id);
  }
}
This piece of code defines the Model in MVC pattern. It represents the data - in this case, a list of to-dos - and includes the methods that handle the business logic, such as adding or removing to-dos.
// The View renders the model into a form that is suitable for the user interface

class TodoView {
  constructor(controller) {
    this.controller = controller;
    this.addButton = document.querySelector('#add-todo');
    this.inputField = document.querySelector('#todo-input');
    this.todoList = document.querySelector('#todo-list');

    this.addButton.onclick = () => this.addTodo();
  }

  addTodo() {
    const text = this.inputField.value;
    this.controller.addTodo(text);
  }

  render(todos) {
    this.todoList.innerHTML = todos.map(todo => `<li>${todo.text}</li>`).join('');
  }
}
This is the View part of the MVC pattern. It's in charge of rendering the to-dos and updating the user interface. It also listens to the user actions like clicking the Add button and informs the Controller about them.
// The Controller links the user input and the model. It listens to the events triggered by the View and updates the Model

class TodoController {
  constructor(model, view) {
    this.model = model;
    this.view = view;
    this.view.render(this.model.todos);
  }

  addTodo(text) {
    if (text) {
      this.model.addTodo(text);
      this.view.render(this.model.todos);
    }
  }

  removeTodo(id) {
    this.model.removeTodo(id);
    this.view.render(this.model.todos);
  }
}
The Controller part in the MVC pattern plays the middle-man. It processes input (in this case, from the View), updates the Model, and may also update the View to reflect changes in the Model.
// Initializing and linking all the MVC components

const appModel = new TodoModel();
const appView = new TodoView(new TodoController(appModel));
const appController = new TodoController(appModel, appView);
This code snippet initializes instances of Model, View, and Controller and wires them together. This step is crucial to make the MVC pattern functional.