I've created a project that implements Singleton pattern so that I have a single entry point to my functionality. My project also implements MVC framework and is also where I think I'm having most of my trouble. I have Controller, View, and Model classes separate from my Singleton class. The Controller is instantiated through the constructor of my Singleton class and I've added dependencies for the Model and View classes in the constructor of my Controller. The problem lies when I attempt to have a function in my Controller class call another function that is within the Controller as well.
Here is my Javascript:
window.addEventListener('load', function() {
console.log("Page Loaded!");
Ross_DPW.getInstance();
});
class Ross_DPW {
constructor() {
console.log("Singleton Created");
console.log("Start Code Here!!!!");
this.controller = new Controller();
}
static getInstance() {
let ross_DPW = null; // Keeps track of current instance.
//Check if there is an instance variable attached to the class.
//If there is one, don't create another one. If not, then create one.
if(!ross_DPW){
//Create instance
ross_DPW = new Ross_DPW();
}
document.querySelector('#name').addEventListener('blur', function() {
if(document.querySelector('#name').value){
document.querySelector('#nameError').innerHTML = "";
document.querySelector('#nameError').style.display = "none";
}
});
document.querySelector('#type').addEventListener('blur', function() {
if(document.querySelector('#type').value){
document.querySelector('#typeError').innerHTML = "";
document.querySelector('#typeError').style.display = "none";
}
});
document.querySelector('#glucose').addEventListener('blur', function() {
if(document.querySelector('#glucose').value){
document.querySelector('#glucoseError').innerHTML = "";
document.querySelector('#glucoseError').style.display = "none";
}
});
}
}
class Controller {
constructor() {
console.log("Controller Created!");
this.model = new Model();
this.view = new View();
document.querySelector('#submit').addEventListener('click', this.IsValid);
}
IsValid(){
let name = document.querySelector('#name').value;
let type = document.querySelector('#type').value;
let glucose = document.querySelector('#glucose').value;
let nameError = document.querySelector('#nameError');
let typeError = document.querySelector('#typeError');
let glucoseError = document.querySelector('#glucoseError');
let isValid = Model.Validate(name, type, glucose, nameError, typeError, glucoseError);
if(isValid){
this.Process(name, type, glucose);
}
}
Process(name, type, glucose){
let data, feedback, a1c = this.model.ProcessData(name, type, glucose);
if(data && feedback && a1c){
this.AddData(data, feedback, a1c);
}
}
AddData(data, feedback, a1c){
if(data, feedback, a1c){
this.view.glucoseDataArray.push(data, feedback, a1c);
this.view.DisplayGlucoseData();
}
}
}
class Model {
constructor() {
console.log("Model Created!");
}
//Validate form fields before further processing is done.
static Validate(name, type, glucose, nameError, typeError, glucoseError) {
let isValid;
if(!name || name == ""){
nameError.style.display = "inline-block";
nameError.innerHTML = "<p class='errorText'>Name field can not be left blank!</p>"
isValid = false;
} else {
isValid = true;
}
if(!type || type == ""){
typeError.style.display = "inline-block";
typeError.innerHTML = "<p class='errorText'>Diabetes type can not be left blank!</p>";
isValid = false;
} else {
isValid = true;
}
if(!glucose || glucose == ""){
glucoseError.style.display = "inline-block";
glucoseError.innerHTML = "<p class='errorText'>Glucose field can not be left blank!</p>";
isValid = false;
} else {
isValid = true;
}
return isValid;
}
//Process the data from the form.
ProcessData(name, type, glucose){
let data = new GlucoseDataObject(name, type, glucose);
let goodFeedback = ["Keep up the good work!", "You're awesome at this!", "Looks like you have your health figured out!"];
let carefulFeedback = ["You're doing well, but there's room for improvement", "It could be worse, but I'll take it.", "With a little work, you'll be perfect."];
let poorFeedback = ["Looks like you could use some tips.", "I know you can do better.", "I've seen better."];
let rand = Math.floor(Math.random() * 3);
let feedback = "";
let avgGlucose = Utils.getAverage(data['glucose']);
let a1c = (46.7 + avgGlucose) / 28.7;
if(a1c < 7){
feedback = goodFeedback[rand];
} else if (a1c > 7 && a1c < 8){
feedback = carefulFeedback[rand];
} else { // If we get here, we can safely assume the A1C is greater than 8, which is bad...
feedback = poorFeedback[rand];
}
return data, feedback, a1c;
}
}
class View {
constructor() {
console.log("View Created!");
this.glucoseDataArray = [];
}
DisplayGlucoseData(){
let glucoseData = document.querySelector('#glucoseData');
glucoseData.innerHTML = "";
for(let data in this.glucoseDataArray){
console.log(data + " : " + this.glucoseDataArray[data]);
}
}
}
class GlucoseDataObject {
constructor(name, type, glucoseVals) {
console.log("Data Object Created!");
this._name = name;
this._type = type;
this._glucoseVals = glucoseVals;
}
}
//Utility Class
class Utils {
constructor() {
}
static getAverage(array) {
let total = 0;
array.forEach(function (e) {
total += Number.parseInt(e);
});
return total / array.length;
}
}
This line throws an error in the browser that says "main.js:70 Uncaught TypeError: this.Process is not a function"
this.Process(name, type, glucose);
I've set breakpoints in the browser to see if I could track down the issue but with no luck.