Search code examples
javascripthtmlarraysbootstrap-modal

Error Uncaught TypeError: Cannot read properties of undefined (reading 'unshift') at HTMLFormElement.<anonymous>


I am doing a javascript course and I followed all the steps but it keeps giving this error.
I already researched a lot on the internet about it, I looked at several posts and it was saying that probably some variable would be null but I already used console.log and alert and I saw that all the variables are being filled.
I rewrote the page several times to see if I was missing something but without success :

Uncaught TypeError: Cannot read properties of undefined (reading 'unshift')

this is my code:

const myModal = new bootstrap.Modal("#transaction-modal");
let logged = sessionStorage.getItem("logged");
const session = localStorage.getItem("session");
let data = {
    transactions: []
};

checkLogged();

document.getElementById("logout-button").addEventListener("click", logout);

document.getElementById("transactions-button").addEventListener("click", function () {
    window.location.href = 'transactions.html';
});

document.getElementById("transaction-form").addEventListener('submit', function (e) {
    e.preventDefault();

    const value = parseFloat(document.getElementById('value-input').value);
    const description = document.getElementById('description-input').value;
    const date = document.getElementById('date-input').value;
    const type = document.querySelector('input[name="type-input"]:checked').value;

    data.transactions.unshift({
        value: value, type: type, description: description, date: date
    });

    saveData(data);
    e.target.reset();
    myModal.hide();

    getCashIn();
    getCashOut();
    getTotal();

    alert("Lançamento adicionado com sucesso!");

});

function checkLogged() {
    if (session) {
        sessionStorage.setItem("logged", session);
        logged = session;
    }

    if (!logged) {
        window.location.href = 'index.html';
        return;
    }

    const dataUser = localStorage.getItem(logged);
    if (dataUser) {
        data = JSON.parse(dataUser);
    }

}

function logout() {
    sessionStorage.removeItem("logged");
    localStorage.removeItem("session");

    window.location.href = 'index.html';
}

function getCashIn() {
    const transactions = data.transactions;

    const cashIn = transactions.filter((item) => item.type === "1");

    if (cashIn.length) {
        let cashInHtml = ``;
        let limit = 0;

        if (cashIn.length > 5) {
            limit = 5;
        } else {
            limit = cashIn.length;
        }

        for (let index = 0; index < limit; index++) {
            cashInHtml += `
            <div class="row mb-4">
                <div class="col-12">
                    <h3 class="fs-2">R$ ${cashIn[index].value.toFixed(2)}</h3>
                    <div class="container p-0">
                    <div class="row">
                        <div class="col-12 col-md-8">
                        <p>${cashIn[index].description}</p> 
                        </div>
                        <div class="col-12 col-md-3 d-flex justify-content-end">
                        <span>${cashIn[index].date}</span> 
                        </div>
                    </div>
                    </div>
                </div>
            </div>
        `

        }

        document.getElementById('cash-in-list').innerHTML = cashInHtml;
    }
}

function getCashOut() {
    const transactions = data.transactions;

    const cashOut = transactions.filter(item => item.type === "2");

    if (cashOut.length) {
        let cashOutHtml = ``;
        let limit = 0;

        if (cashOut.length > 5) {
            limit = 5;
        } else {
            limit = cashOut.length;
        }

        for (let index = 0; index < limit; index++) {
            cashOutHtml += `
            <div class="row mb-4">
                <div class="col-12">
                    <h3 class="fs-2">R$ ${cashOut[index].value.toFixed(2)}</h3>
                    <div class="container p-0">
                    <div class="row">
                        <div class="col-12 col-md-8">
                        <p>${cashOut[index].description}</p> 
                        </div>
                        <div class="col-12 col-md-3 d-flex justify-content-end">
                        <span>${cashOut[index].date}</span> 
                        </div>
                    </div>
                    </div>
                </div>
            </div>
        `

        }

        document.getElementById('cash-out-list').innerHTML = cashOutHtml;
    }
}

function getTotal() {
    const transactions = data.transactions;
    let total = 0;

    transactions.forEach((item) => {
        if (item.type === "1") {
            total += item.value;
        } else {
            total -= item.value;
        }
    })

    document.getElementById('total').innerHTML = `R$ ${total.toFixed(2)}`;
}

function saveData(data) {
    localStorage.setItem(data.login, JSON.stringify(data));
}

n this is my html page, i don't know but could it be her?

<!DOCTYPE html>
<html lang="pt">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Nikel - Codaí</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet"
        integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.7.0/font/bootstrap-icons.css">
    <link rel="stylesheet" href="./css/styles.css">
</head>

<body id="app">
    <header>
        <nav class="navbar navbar-expand navbar-light bg-white">
            <div class="container-fluid">
                <a class="navbar-brand" href="#">
                    <img src="./assets/images/nikel-small-logo.png" class="img-fluid" alt="nikel logo image" />
                </a>
                <button class="navbar-toggler" type="button" data-bs-toggle="collapse"
                    data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent"
                    aria-expanded="false" aria-label="Toggle navigation">
                    <span class="navbar-toggler-icon"></span>
                </button>
                <div class="collapse navbar-collapse justify-content-end" id="navbarSupportedContent">
                    <div class="d-flex menu">
                        <a href="home.html"><button class="btn" type="button"><i
                                    class="bi bi-house-door-fill fs-4 color-secondary"></i></button></a>
                        <a href="transactions.html"><button class="btn" type="button"><i
                                    class="bi bi-currency-exchange fs-4"></i></button></a>

                        <div class="dropdown">
                            <button class="btn" type="button" data-bs-toggle="dropdown" aria-expanded="false"><i
                                    class="bi bi-person-circle fs-4"></i></button>
                            <ul class="dropdown-menu logout" aria-labelledby="dropdownMenuButton1">
                                <li><button id="logout-button" class="dropdown-item">Sair</button></li>
                            </ul>
                        </div>
                    </div>
                </div>
            </div>
        </nav>
    </header>
    <main>
        <div class="container-lg">
            <div class="row">
                <div class="col-8 d-flex mt-4 justify-content-start align-items-center">
                    <div>
                        <i class="bi bi-cash-coin color-primary icon-detail"></i>
                        <span class="fs-2 bg-white" id="total">R$ 0,00</span>
                    </div>
                </div>
                <div class="col-4 d-flex mt-4 justify-content-end">
                    <div class="text-center">
                        <img src="./assets/images/coins-small.png" class="img-fluid" alt="coins image" />
                    </div>
                </div>
            </div>
            <div class="row">
                <div class="col-12 info shadow-lg">
                    <div class="container">
                        <div class="row">
                            <div class="col-6"><span class="fs-4 align-middle">Entradas </span> <i
                                    class="bi bi-arrow-down-circle fs-2 align-middle"></i></div>
                            <div class="col-6"><span class="fs-4 align-middle">Saídas </span> <i
                                    class="bi bi-arrow-up-circle fs-2 align-middle"></i></div>
                            <div class="col-12 my-2">
                                <hr />
                            </div>
                        </div>
                        <div class="row">
                            <div class="col-6">
                                <div class="container p-0" id="cash-in-list">

                                </div>
                            </div>
                            <div class="col-6">
                                <div class="container p-0" id="cash-out-list">

                                </div>
                            </div>

                            <div class="col-12 mb-4">
                                <button type="button" class="btn button-default" id="transactions-button">Ver
                                    todas</button>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
            <button class="btn button-float" data-bs-toggle="modal" data-bs-target="#transaction-modal"><i
                    class="bi bi-plus"></i></button>
        </div>
        <!-- Modal -->
        <div class="modal fade" id="transaction-modal" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1"
            aria-labelledby="staticBackdropLabel" aria-hidden="true">
            <div class="modal-dialog">
                <div class="modal-content">
                    <div class="modal-header">
                        <h5 class="modal-title" id="staticBackdropLabel">Adicionar lançamento</h5>
                        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
                    </div>
                    <form id="transaction-form">
                        <div class="modal-body">
                            <div class="mb-3">
                                <label for="value-input" class="form-label">Valor</label>
                                <input type="number" step="any" class="form-control" id="value-input">
                            </div>
                            <div class="mb-3">
                                <label for="description-input" class="form-label">Descrição</label>
                                <input type="text" class="form-control" id="description-input">
                            </div>
                            <div class="mb-3">
                                <label for="date-input" class="form-label">Data</label>
                                <input type="date" class="form-control" id="date-input">
                            </div>
                            <div class="mb-3">
                                <div class="form-check form-check-inline">
                                    <input class="form-check-input" type="radio" name="type-input" id="type-input1"
                                        value="1" checked>
                                    <label class="form-check-label" for="type-input1">Entrada</label>
                                </div>
                                <div class="form-check form-check-inline">
                                    <input class="form-check-input" type="radio" name="type-input" id="type-input2"
                                        value="2">
                                    <label class="form-check-label" for="type-input2">Saída</label>
                                </div>
                            </div>
                        </div>
                        <div class="modal-footer">
                            <button type="button" class="btn btn-secondary button-cancel"
                                data-bs-dismiss="modal">Cancelar</button>
                            <button type="submit" class="btn button-default">Adicionar</button>
                        </div>
                    </form>
                </div>
            </div>
        </div>
    </main>

    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"
        integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p"
        crossorigin="anonymous"></script>
    <script src="./js/home.js"></script>
</body>

</html> 

What changes do I need to make to fix this? Any help is appreciated. I already try a downgrade version of bootstrap bundle.


Solution

  • Let's try to find following by steps:

    1. The typeof data.transactions starts as Array:
    let data = {
        transactions: []
    };
    
    1. Unshift method exists in array and sholdn't return error, so variable data.transactions got different type somewhere, and the only place you update data value is in data = JSON.parse(dataUser);

    Make sure JSON.parse(dataUser) returns the same structure as initiated (an object containing transactions array), otherwise will throw an Error.

    This error shows because .transactions don't exists in data object.

    Uncaught TypeError: Cannot read properties of undefined (reading 'unshift')