What am I missing that is causing this to be undefined?

Hey everyone,

I am working on my first real JS app and am having a hard time finding what I am missing that keeps causing this to be undefined. This is a budget app where I am trying to take 3 user inputs (budget, expense name, and expense amount) and write them on the page. I am having problems with the expense part only coming up as undefined and having both my expense name and amount writing in my expense name section of the page.

Any help would be greatly appreciated!

//Selectors and Vars
let totalExpense;
let incomingCalcButton = document.getElementById('incomingCalcButton');
let outgoingCalcButton = document.getElementById('expenseButton');
let newExpenseName =  document.querySelector("[name=expense_Name]").value;
let newExpenseAmount =  document.querySelector("[name=expense_Value]").value;
let expensesNameSection = document.querySelector('#title_Expenses');
let expensesAmountSection = document.querySelector('#value_Expenses');

//Functions 
function addExpense(event) {
    //Prevent submission
    event.preventDefault();
    //Expense Name Div
    const expenseNameDiv = document.createElement('div');
    expenseNameDiv.classList.add('expName');
    //Expense amonut div
    const expenseAmountDiv = document.createElement('div');
    expenseAmountDiv.classList.add('expAmount');
    //Create LI Expense Names
    const newExpName = document.createElement('li');
    newExpName.innerText = newExpenseName.value;
    newExpName.classList.add('expense-name');
    expenseNameDiv.appendChild(newExpName);
    //Create LI Expense Amounts
    const newExpAmt = document.createElement('li');
    newExpAmt.innerText = newExpenseAmount.value;
    newExpAmt.classList.add('expense-amount');
    expenseNameDiv.appendChild(newExpAmt);
    //append to LI
    expensesNameSection.appendChild(expenseNameDiv);
    expensesAmountSection.appendChild(expenseAmountDiv);
    //Clear input
    newExpenseName.value = "";
    newExpenseAmount.value = "";
}

// Event Handlers
incomingCalcButton.addEventListener("click", incomingCash);
expenseButton.addEventListener("click", addExpense);
<body>
    <h1>Budget Application</h1>
    <div id="inputSections" class="inputSections">
        <form id="incomingMoney">
            <h3>Please Enter Your Budget</h3>
            <input type="number" id="incomingCashInput" class="inputs" name="incoming_Cash_Input"><br>
            <button id="incomingCalcButton">Calculate</button>
        </form>

        <form id="enterExpenses">
            <h3>Please Enter Your Expense</h3>
            <input type="text" id="expenseName" class="inputs" name="expense_Name">
            <h3>Please Enter Expense Amount</h3>
            <input type="number" id="expenseAmount" class="inputs" name="expense_Value"><br>
            <button id="expenseButton">Add Expense</button>
        </form>
    </div>
    <section id="calculations" class="calcs">
        <div class="budget calcs">
            <h3>Budget</h3><br>
            <img src="money_icon.png" class="moneyIcon calcIcon"><br>
            <section id="budgetIncoming">

            </section>
        </div>
        <div class="expenses calcs">
            <h3>Expenses</h3><br>
            <img src="expense_icon.png" class="expenseIcon calcIcon"><br>
            <section id="expenseIncoming">

            </section>
        </div>
        <div class="balance calcs">
            <h3>Balance</h3><br><br>
            <img src="budget_icon.png" class="budgetIcon calcIcon"><br>
            <section id="balanceIncoming">

            </section>
        </div>
    </section>

    <section id="expenses expContainer" >
        <div class="expContainer">
            <h4>Expense Title</h4>
            <section class="titleExpenses expContainer" id="title_Expenses">

            </section>
        </div>
        <div class="expContainer">
            <h4>Expense Value</h4><br><br>
            <section class="valueExpenses" id="value_Expenses">
                
            </section>
        </div>
        <div class="expContainer">
            <h4>Edit</h4>
            <section class="deleteExpenses" >

            </section>
        </div>

    </section>


</body>

You probably don’t want to access the value attribute just yet here:

let newExpenseName =  document.querySelector("[name=expense_Name]").value;
let newExpenseAmount =  document.querySelector("[name=expense_Value]").value;

Why would I not want to access that there? Would it be better to just declare the var there and then access the value attribute in the addExpense function? Thanks for the feedback!

Adam

What exactly is returning undefined? For example, your function would be undefined because there is no return statement.

It just doesn’t make any sense to assign newExpenseName to the value of the input field before anything was entered into the input field. newExpenseName won’t just magically be updated with the new value when a button is clicked. That’s not how JavaScript works. Instead, you’d have to put the assignment into your event handler.

So I see what you are saying. I have removed it from the original declaration of the newExpenseName and newExpenseAmount and just have it in addExpense(). That with a couple small changes have started to return the correct output. Thanks for pointing that out to me. I will have to look into .value to make sure I understand when and when not to do it going forward.

I do have a strange question about what I am getting though. Are you able to tell why I have gotten output that is formatted differently in different sections when I am using basically the same code? Thanks for all the help!

//Selectors and Vars
let totalExpense;
let incomingCalcButton = document.getElementById('incomingCalcButton');
let outgoingCalcButton = document.getElementById('expenseButton');
let newExpenseName =  document.querySelector("[name=expense_Name]");
let newExpenseAmount =  document.querySelector("[name=expense_Value]");
let expensesNameSection = document.querySelector('#title_Expenses');
let expensesAmountSection = document.querySelector('#value_Expenses');


function addExpense(event) {
    //Prevent submission
    event.preventDefault();
    //Expense Name Div
    const expenseNameDiv = document.createElement('div');
    expenseNameDiv.classList.add('expName');
    //Expense amonut div
    const expenseAmountDiv = document.createElement('div');
    expenseAmountDiv.classList.add('expAmount');
    //Create LI Expense Names
    const newExpName = document.createElement('li');
    newExpName.innerText = newExpenseName.value;
    newExpName.classList.add('expense-name');
    expenseNameDiv.appendChild(newExpName);
    //Create LI Expense Amounts
    const newExpAmt = document.createElement('li');
    newExpAmt.innerText = newExpenseAmount.value;
    newExpAmt.classList.add('expense-amount');
    expenseAmountDiv.appendChild(newExpAmt);
    //append to LIs
    expensesNameSection.appendChild(expenseNameDiv);
    expensesAmountSection.appendChild(expenseAmountDiv);
    
    //Clear input
    newExpenseName.value = "";
    newExpenseAmount.value = "";
}

// Event Handlers
incomingCalcButton.addEventListener("click", incomingCash);
expenseButton.addEventListener("click", addExpense);
<body>
    <h1>Budget Application</h1>
    <div id="inputSections" class="inputSections">
        <form id="incomingMoney">
            <h3>Please Enter Your Budget</h3>
            <input type="number" id="incomingCashInput" class="inputs" name="incoming_Cash_Input"><br>
            <button id="incomingCalcButton">Calculate</button>
        </form>

        <form id="enterExpenses">
            <h3>Please Enter Your Expense</h3>
            <input type="text" id="expenseName" class="inputs" name="expense_Name">
            <h3>Please Enter Expense Amount</h3>
            <input type="number" id="expenseAmount" class="inputs" name="expense_Value"><br>
            <button id="expenseButton">Add Expense</button>
        </form>
    </div>
    <section id="calculations" class="calcs">
        <div class="budget calcs">
            <h3>Budget</h3><br>
            <img src="money_icon.png" class="moneyIcon calcIcon"><br>
            <section id="budgetIncoming">

            </section>
        </div>
        <div class="expenses calcs">
            <h3>Expenses</h3><br>
            <img src="expense_icon.png" class="expenseIcon calcIcon"><br>
            <section id="expenseIncoming">

            </section>
        </div>
        <div class="balance calcs">
            <h3>Balance</h3><br><br>
            <img src="budget_icon.png" class="budgetIcon calcIcon"><br>
            <section id="balanceIncoming">

            </section>
        </div>
    </section>

    <section id="expenses expContainer" >
        <div class="expContainer">
            <h4>Expense Title</h4>
            <section class="titleExpenses expContainer" id="title_Expenses">

            </section>
        </div>
        <div class="expContainer">
            <h4>Expense Value</h4><br><br>
            <section class="valueExpenses" id="value_Expenses">
                
            </section>
        </div>
        <div class="expContainer">
            <h4>Edit</h4>
            <section class="deleteExpenses" >

            </section>
        </div>

    </section>

The value in the HTML changes whenever you input a number, but JavaScript doesn’t notice that. You can only tell it to listen for events (like a button click or an input). Then you can read the updated value into your script.

I don’t understand, can you post a screenshot?

I am speaking about the Expense title and Value sections at the bottom. I am trying to get both of them to write out as vertical lists instead of the title writing out horizontally. I have checked my CSS to confirm that I have not accidentally added a class name that would coincide with something else on the page. I will put that below here just in case. Thanks again for the help so far!

html{
    padding: 5% 20%;
   text-align: center;
}

#incomingMoney {
    border: green 1px solid;
    padding: 10% 5%;
    margin-bottom: 20px;
}

#incomingCalcButton {
    margin-top: 10px;
}

#enterExpenses {
    border: red 1px solid;
    padding: 10% 5%;
}

#expenseButton{
    margin-top: 10px;
}
.calcIcon {
    width: 100%;
    height: 100%;
    max-width: 50px;
    max-height: 50px;
}

.inputs {
    width: 90%;
}

.expense-name{
    display: list-item;
    flex: 1;
    flex-wrap: wrap;
    
    
}

/* When the browser is at least 600px and above */
@media screen and (min-width: 700px) {
    html{
        margin: 1%;
       text-align: center;
    }

    .inputSections {
        display: inline;
        height: 1000px;
    }

    #incomingMoney {
        width: 35%;
        float: left;
    }

    #enterExpenses {
        width: 35%;
        float: right;
    }

    .calcs {
        border: red 1px solid;
        padding-top: 50px;
        margin: auto;
        display: flex;
        justify-content: space-around;
        align-items: stretch;
        flex-basis: auto;
        flex-flow: row;
        width: 100%;
    }

    .expContainer {
        border: blue 1px solid;
        display: inline-flex;
        margin: auto;
        padding-top: 10px;
        flex-wrap: nowrap;
        width: 32%;
        justify-content: space-around;
        flex-flow: row;
        
    }
  }
~~~

I think this shouldn’t have the .expContainer class, it has display:flex:

<section class="titleExpenses expContainer" id="title_Expenses">

Ahh ok that fixes it. Thank you for all the help!