Search code examples
javascriptprototypejavascript-objects

Undefined function with javascripts


I'm writing a small 'quote calculator'. I want to print the summary to the browser with innerHTML, but I'm still getting "undefined" instead of the price. But in my console.log everything works fine, I can console.log the variable price and get the expected result.

//Variables 

const form = document.getElementById('request-quote');
const html = new HTMLUI();

//Event Listeners 

eventListeners();

function eventListeners() {
  document.addEventListener('DOMContentLoaded', function() {
    //Create the <option> for the years
    html.displayYears();
  });
  //when the form is submitted

  form.addEventListener('submit', function(e) {
    e.preventDefault();

    //get values from the form
    const make = document.getElementById('make').value;
    const year = document.getElementById('year').value;

    //Read the radio buttons

    const level =
      document.querySelector('input[name="level"]:checked').value;

    // Validation
    if (make === '' || year === '' || level === '') {
      html.displayErrors('All fields are mendatory')
    } else {
      //Make the quotation
      const insurance = new Insurance(make, year, level);
      const price = insurance.calculateQuotation(insurance);
      //print
      html.showResults(price);
    }

  });
}
// Create another prototype with for the object HTMLUI. to print Errors

//Object 
// Everything related to the calculation and quotation

function Insurance(make, year, level) {
  this.make = make;
  this.year = year;
  this.level = level;
}

//calculation 

Insurance.prototype.calculateQuotation = function(insurance) {
  let price;
  const base = 2000;

  //get make
  const make = insurance.make;

  /**
   1. america: 15
   2. Asia : 5
   3. europia: 35
  */

  switch (make) {
    case '1':
      price = base * 1.15;
      break

    case '2':
      price = base * 1.05;
      break

    case '3':
      price = base * 1.35;
      break
  }

  //get level

  const level = insurance.level;

  price = this.calculateLevel(price, level);

  //get year

  const year = insurance.year;
  const difference = this.getYearDifference(year);
  price = price - ((difference * 3) * price) / 100;
  console.log(price);

}
//return difference between years

Insurance.prototype.getYearDifference = function(year) {
  return new Date().getFullYear() - year;
  // each year the cost must be 3% cheaper

}

//add value based on level

Insurance.prototype.calculateLevel = function(price, level) {
  //basic increase 30%

  //complete increases 50%
  if (level === 'basic') {
    price = price * 1.30;
  } else {
    price = price * 1.50;
  }
  return price;
}


function HTMLUI() {}
//display the latest 20 years in the select
HTMLUI.prototype.displayYears = function() {
  //Max & minimum years
  const max = new Date().getFullYear();
  min = max - 20;
  //Generate the list
  const selectYears = document.getElementById('year');

  //print the values

  for (let i = max; i >= min; i--) {
    const option = document.createElement('option')
    option.value = i;
    option.textContent = i;
    selectYears.appendChild(option);
  }
}

//Print Error, by creating a prototype

HTMLUI.prototype.displayErrors = function(message) {
  //create div
  const div = document.createElement('div');
  div.classList = 'error';

  //insert message
  div.innerText = `
    <p>${message}</p>
    `;

  form.insertBefore(div, document.querySelector('.form-group'));

  //Remove the error

  setTimeout(function() {
    document.querySelector('.error').remove();
  }, 3000);
}

HTMLUI.prototype.showResults = function(price) {
  //print result
  const result = document.getElementById('result');

  //create a div with the result

  const div = document.createElement('div');
  //insert the result
  div.innerHTML = `
    <p class="total">Total: $ ${price}</p>
    `;
  //insert into html

  result.appendChild(div)
}

I am expecting to print the value of the variable price( which will actually be the price) but I'm getting "undefined" while trying to print the price


Solution

  • You need to add in a return statement to the calculateQuotation function. Here's why, in case it helps.

    The reason you're getting undefined is because the price variable is never being given a value.

    On this line:

    const price = insurance.calculateQuotation(insurance);

    price is getting whatever the calculateQuotation function sends back with a return statement. However, in that function you're just filling a price variable which exists only in the context of that function. To make this work, I believe you need to add in a return statement at the end of the calculateQuotation function like so:

    Insurance.prototype.calculateQuotation = function(insurance) {
      let price;
      const base = 2000;
    
      //get make
      const make = insurance.make;
    
      /**
       1. america: 15
       2. Asia : 5
       3. europia: 35
      */
    
      switch (make) {
        case '1':
          price = base * 1.15;
          break
    
        case '2':
          price = base * 1.05;
          break
    
        case '3':
          price = base * 1.35;
          break
      }
    
      //get level
    
      const level = insurance.level;
    
      price = this.calculateLevel(price, level);
    
      //get year
    
      const year = insurance.year;
      const difference = this.getYearDifference(year);
      price = price - ((difference * 3) * price) / 100;
      console.log(price);
      return price; // Added this in
    }