我是Index DB的新手,所以这可能是一个简单的修复,但我似乎无法在代码中找到任何修复。我使用live server来显示它,我面临的问题是它应该在html中显示总金额,但它在控制台中给了我一个错误:Here .谢谢你的考虑
下面是我的dbFunctions。js
let db;
let request = indexedDB.open("financeManager", 1);
request.onupgradeneeded = function(event){
db = event.target.result;
db.createObjectStore("expenses", { keyPath:'id', autoIncrement: true});
db.createObjectStore("incomes", {keyPath: 'id', autoIncrement: true});
db.createObjectStore("totalMoney", {keyPath: 'id', autoIncrement: true});
};
if(!db.objectStoreNames.contains("totalMoney")){
}
request.onsuccess = function(event){
db = event.target.result;
};
request.onerror = function(event){
console.log('error', event.target.errorCode);
};
function updateTotalMoney(updatedTot){
var transaction = db.transaction(['totalMoney'], 'readwrite');
var objectStore = transaction.objectStore('totalMoney');
var getTotal = objectStore.get(1);
getTotal.onsuccess = function(event){
var data = event.target.result;
if(data){
data.total = updatedTot;
var updateRequest = objectStore.put(data);
updateRequest.onsuccess = function(){
console.log('Successfully Updated Total');
}
updateRequest.onerror = function(){
console.log("Error with Updating: ", event.target.error);
}
} else{
console.log("no existing totalMoney found, please initialize it first before updating");
}
}
getTotal.onerror = function(event){
console.log("error retrieving Total: ", event.target.error);
}
}
//GetDatabyname funciton essentially
function getDataByName(storeName, nameValue, callback){
let transaction = db.transaction([storeName], 'readonly');
let objectStore = transaction.objectStore(storeName);
let result = [];
objectStore.openCursor().onsuccess = function(event){
let cursor = event.target.result;
if(cursor){
if(cursor.value.name === nameValue){
result.push(cursor.value);
}
cursor.continue();
} else{
callback(result);
}
}
}
//should only be used once, adds totalMoney as a db
function initializeTotalMoney(total){
var transaction = db.transaction(['totalMoney'], 'readwrite');
var objectStore = transaction.objectStore('totalMoney');
var totalMoney = {
'total': total
};
var request = objectStore.add(totalMoney);
request.onsuccess = function(event){
console.log("Successfull");
}
request.onerror = function(event){
console.log("error adding total:" ,event.target.error);
}
}
function checkAndInitializeTotalMoney(InitialValue){
var transaction = db.transaction(['totalMoney'], 'readonly');
var objectStore = transaction.objectStore('totalMoney');
var getRequest = objectStore.get(1);
getRequest.onsuccess = function(e){
if (!e.target.result){
initializeTotalMoney(InitialValue);
} else{
console.log("totalMoney already initialized: ", e.target.result);
}
};
getRequest.onerror = function(e){
console.log("Error checking tot money: ", e.target.error);
};
}
//db boilerplate function to add an expense, use addExpense with a name and amount
function addExpense(name, amount, type, interestRate = 0, importance = "N/A"){
var transaction = db.transaction(['expenses'], 'readwrite');
var objectStore = transaction.objectStore('expenses');
var expense = {
'name': name,
'amount': amount,
'interestRate': interestRate,
'type': type,
'date': new Date(),
'importance': importance
};
var request = objectStore.add(expense);
request.onsuccess = function(event){
console.log('Successfully added Expense');
}
request.onerror = function(event){
console.log('Error adding Expense: ', event.target.error);
};
}
function addIncome(name, amount, type, interestRate = 0, frequency = "N/A"){
var transaction = db.transaction(['incomes'], 'readwrite');
var objectStore = transaction.objectStore('incomes');
var income = {
'name': name,
'amount': amount,
'type': type,
'interestRate': interestRate,
'date': new Date(),
'frequency': frequency
};
var request = objectStore.add(income);
request.onsuccess = function(event){
console.log('Successfully added Income');
}
request.onerror = function(event){
console.log('Error adding Income: ', event.target.error);
};
}
下面是收入。js和addIncome。HTML
const dropdownIncome = document.getElementById("dropdownIncome");
const optionForms = document.querySelectorAll(".options");
//submit btns form
const submitOneTime = document.getElementById("submitOneTime");
const submitMonthly = document.getElementById("submitMonthly");
const submitInterest = document.getElementById("submitInterest");
//oneTimeInput
const oneTimeInputLabel = document.getElementById("oneTimeInputLabel");
const oneTimeInput = document.getElementById("oneTimeInput");
//monthlyInput
const monthlyInputLabel = document.getElementById("monthlyInputLabel");
const monthlyInput = document.getElementById("monthlyInput");
const radiosMonthly = document.getElementsByName("radioMonthlyIncome");
//interestInput
const interestInputLabel = document.getElementById("interestInputLabel");
const interestInput = document.getElementById("interestInput");
const interestRateInput = document.getElementById("interestRateInput");
//ultimately displays the selected item of the dropdown
dropdownIncome.addEventListener("change", function(){
const selectedOption = this.value;
const showForm = document.getElementById(selectedOption);
//makes each form invisible
optionForms.forEach(form => {
form.style.display = 'none';
});
//shows the selected form
showForm.style.display = "block";
});
//ultimately adds data in input to db and updates totalMoney
submitOneTime.addEventListener("click", function(){
let oneTimeInputValue = parseFloat(oneTimeInput.value);
if(isNaN(oneTimeInputValue)){
alert("Please Enter A Number");
}
else{
//defines expenseName and expenseAmount to be put into addExpense
var incomeName = oneTimeInputLabel.value;
var incomeAmount = oneTimeInputValue;
//adds the name and amount into the db
addIncome(incomeName, incomeAmount, "oneTime");
getDataByName("totalMoney", "total", function(data){
if (data && data[0]){
var currentTotal = data[0].total;
var newTotal = currentTotal + oneTimeInputValue;
updateTotalMoney(newTotal);
} else{
console.log("Error retreiving total Money");
}
});
}});
//ultimately adds data in input to db
submitMonthly.addEventListener("click", function(){
let monthlyInputValue = parseFloat(monthlyInput.value);
if(isNaN(monthlyInputValue)){
alert("Please Enter A Number");
}
else{
for (var i=0, length=radiosMonthly.length; i < length; i++){
if(radiosMonthly[i].checked){
var selected = radiosMonthly[i];
break;
}
}
//defines expenseName and expenseAmount to be put into addExpense
var incomeName = monthlyInputLabel.value;
var incomeAmount = monthlyInputValue;
var incomeFrequency = selected.value;
//adds the name and amount into the db
addIncome(incomeName, incomeAmount, "monthly", undefined, incomeFrequency);
//ADD UPDATETOTALMONEY HERE, DEPENDING ON inCOME FREQUENCY//
}});
submitInterest.addEventListener("click", function(){
let interestInput = parseFloat(interestInput.value);
let interestRateInput = parseFloat(interestRateInput.value);
if(isNaN(interestInput) || isNaN(interestRateInput)){
alert("Please enter numbers for both inputs");
}
else{
var incomeName = interestInputLabel.value;
var incomeAmount = interestInput;
var incomeInterest = interestRateInput;
addIncome(incomeName, incomeAmount, "interest", incomeInterest);
}
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<select id="dropdownIncome">
<option value="default">--</option>
<option value="optionOneTime">
One-Time Income
</option>
<option value="optionMonthly">
Monthly Income
</option>
<option value="optionInterest">
Interest Income
</option>
</select>
<div id="default" class="options" style="display:none;"> </div>
<div id="optionOneTime" class = "options" style="display:none;">
<input type = "text" placeholder="Label" id="oneTimeInputLabel">
<input type= "text" placeholder="Enter your One-Time Income" id ="oneTimeInput">
<button id="submitOneTime" class="btnIncome">Submit</button>
</div>
<div id="optionMonthly" class="options" style="display:none;">
<input type = "text" placeholder="Label" id="monthlyInputLabel">
<input type="text" placeholder="Enter your Monthly Income" id="monthlyInput">
<button id="submitMonthly" class="btnIncome">Submit</button>
<input type="radio" name="radioMonthlyIncome" id="Weekly">Weekly
<input type="radio" name="radioMonthlyIncome" id="BiWeekly">Bi-Weekly
<input type="radio" name="radioMonthlyIncome" id="Monthly">Monthly
</div>
<div id="optionInterest" class="options" style="display:none;">
<input type="text" placeholder="Label" id="interestInputLabel">
<input type="text" placeholder="Enter your Base Interest Income" id="interestInput">
<input type="text" placeholder="Enter your Interest Rate" id="interestRateInput">
<button id="submitInterest" class="btnIncome">Submit</button>
</div>
<script src="dbFunctions.js"></script>
<script src="addIncome.js"></script>
</body>
</html>
下面是addExpenses。js和addExpenses。html文件。
const dropdownExpenses = document.getElementById("dropdownExpenses");
const optionForms = document.querySelectorAll(".options");
//submit btns form
const submitMonthly = document.getElementById("submitMonthly");
const submitOneTime = document.getElementById("submitOneTime");
const submitMortgage = document.getElementById("submitMortgage");
//oneTimeInput
const oneTimeInputLabel = document.getElementById("oneTimeInputLabel");
const oneTimeInput = document.getElementById("oneTimeInput");
const radiosOneTime = document.getElementsByName("radioOneTime");
//monthlyInput
const monthlyInputLabel = document.getElementById("monthlyInputLabel");
const monthlyInput = document.getElementById("monthlyInput");
const radiosMonthly = document.getElementsByName("radioMonthly");
//mortgageInput
const mortgageInputLabel = document.getElementById("mortgageInputLabel");
const mortgageBasePayInput = document.getElementById("mortgageBasePayInput");
const mortgageInterestRateInput = document.getElementById("mortgageInterestRateInput");
//ultimately displays the selected item of the dropdown
dropdownExpenses.addEventListener("change", function (){
const selectedOption = this.value;
const showForm = document.getElementById(selectedOption);
//makes each form invisible
optionForms.forEach(form => {
form.style.display = 'none';
});
//shows the form selected
showForm.style.display = "block";
});
//ultimately adds data in input field to db, and updates total money
submitOneTime.addEventListener("click", function(){
let oneTimeInputValue = parseFloat(oneTimeInput.value);
if(isNaN(oneTimeInputValue)){
alert("Please Enter A Number");
}
else{
for (var i=0, length=radiosOneTime.length; i < length; i++){
if(radiosOneTime[i].checked){
var selected = radiosOneTime[i];
break;
}
}
//defines expenseName and expenseAmount to be put into addExpense
var expenseName = oneTimeInputLabel.value;
var expenseAmount = oneTimeInputValue;
var expenseImportance = selected.value;
//adds the name and amount into the db
addExpense(expenseName, expenseAmount, "oneTime", undefined, expenseImportance);
getDataByName("totalMoney", "total", function(data){
if (data && data[0]){
var currentTotal = data[0].total;
var newTotal = currentTotal - oneTimeInputValue;
updateTotalMoney(newTotal);
} else{
console.log("Error retreiving total Money");
}
});
}});
//ultimately adds data in input field to db
submitMonthly.addEventListener("click", function(){
let monthlyInputValue = parseFloat(monthlyInput.value);
if(isNaN(monthlyInputValue)){
alert("Please enter a Number");
}
else{
for (var i=0, length=radiosMonthly.length; i < length; i++){
if(radiosMonthly[i].checked){
var selected = radiosMonthly[i];
break;
}
}
var expenseName = monthlyInputLabel.value;
var expenseAmount = monthlyInputValue;
var expenseImportance = selected.value;
addExpense(expenseName, expenseAmount, "monthly", undefined, expenseImportance);
}
});
submitMortgage.addEventListener("click", function(){
let mortgageBasePayInputValue = parseFloat(mortgageBasePayInput.value);
let mortgageInterestRateInputValue = parseFloat(mortgageInterestRateInput.value);
if(isNaN(mortgageBasePayInputValue) || isNaN(mortgageInterestRateInputValue)){
alert("Please enter numbers for both inputs");
}
else{
var expenseName = mortgageInputLabel.value;
var expenseAmount = mortgageBasePayInputValue;
var expenseInterest = mortgageInterestRateInputValue;
addExpense(expenseName, expenseAmount, "mortgage", expenseInterest, undefined);
}
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href = "addExpenses.css">
<title>Document</title>
</head>
<body>
<a href="financetracker.html">
<p>Go Back</p>
</a>
<select id="dropdownExpenses">
<option value="default">--</option>
<option value="optionMonthly">
Monthly Expense
</option>
<option value = "optionOneTime">
One-Time Expense
</option>
<option value = "optionMortgage">
Mortgage Expense
</option>
</select>
<div id="default" style="display:none;" class="options"> </div>
<div id="optionMonthly" style="display:none;" class="options">
<input type="text" placeholder="Label" id="monthlyInputLabel">
<input type="text" placeholder="Select A Monthly Expense Amount" id="monthlyInput">
<button id="submitMonthly" class="btnExpenses">Submit</button>
<input type="radio" name="radioMonthly" id="Luxury">Luxury
<input type="radio" name="radioMonthly" id="Necessity">Necessity
<input type="radio" name="radioMonthly" id="Favorable">Favorable
</div>
<div id="optionOneTime" style = "display:none;" class="options">
<input type="text" placeholder="Label" id="oneTimeInputLabel">
<input type="text" placeholder="Select a One-Time Expense" id="oneTimeInput">
<button id="submitOneTime" class="btnExpenses">Submit</button>
<input type="radio" name="radioOneTime" id="Luxury">Luxury
<input type="radio" name="radioOneTime" id="Necessity">Necessity
<input type="radio" name="radioOneTime" id="Favorable">Favorable
</div>
<div id="optionMortgage" style="display:none;" class="options">
<input type="text" placeholder="Label" id="mortgageInputLabel">
<input type="text" placeholder="Select your base monthly Mortgage Expense" id="mortgageBasePayInput">
<input type="text" placeholder="Select your monthly interest rate" id="mortgageInterestRateInput">
<button id="submitMortgage" class="btnExpenses">Submit</button>
</div>
<script src="dbFunctions.js"></script>
<script src="addExpenses.js"></script>
</body>
</html>
下面是我的财务跟踪。js、. css和. HTML
//input daily expenses, incldues consistent expenses as well as one time purchases
//include monthly expenses as well as any overarching expenses
//categorize expenses: necessities, luxuries, one time expenses etc etc
//include wages, put in hours of work and output total profit
//then, visualize the data with various charts and tracking
//finally, for now suggest ways to cut spending
//want to calculate Income and Expenses on the daily, except for instant payments/debts.
//make choice btw implementing flat monthly rates on graph with instant or over time.
//prob over time since it would fit better on this big top max of budget/ income
//manually set totalMoney (usually to 0), then log that value in the db
document.addEventListener("DOMContentLoaded", function(){
var totalMoney = 10000000;
checkAndInitializeTotalMoney(totalMoney);
//puts commas in totalMoney as well as updates text box
function displayTotalMoney(total){
console.log("Display Total Money is being called");
var totalMoneyS = total.toString();
for (let i = totalMoneyS.length - 3; i > 0; i-=3){
totalMoneyS = totalMoneyS.slice(0, i) + ',' + totalMoneyS.slice(i);
}
document.getElementById("moneyAmount").textContent = totalMoneyS;
}
//takes the value of total in totalMoney and runs displayTotalMoney there
function assignMoneyUse(data){
//checks if data is not empty and that it has at least one element
if(data && data[0]){
displayTotalMoney(data[0].total);
}else{
console.log("no data found for total in totalMoney");
}
}
//gets db data for totalMoney
getDataByName("totalMoney", "total", assignMoneyUse);
});
.viewButtons{
width: 350px;
height: 200px;
font-size: 50px;
font-family: 'Times New Roman', Times, serif;
border-radius: 10px;
}
.balanceBottomLine{
position: relative;
top: 200px;
left: 100px;
width: 1500px;
height: 5px;
background-color: black;
}
#addExpenses{
position: absolute;
top:100px;
left:100px;
}
#addIncome{
position: absolute;
top: 100px;
left: 500px;
}
#statistics{
position: absolute;
top: 100px;
left: 900px;
}
.dataVisBox{
position: relative;
top: 600px;
left:125px;
width:1500px;
height:1000px;
border:5px solid black;
}
.moneyHave{
position: absolute;
top: -110px;
font-size: 100px;
font-family: Arial, Helvetica, sans-serif;
}
.moneyHave p{
display: inline;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="financetracker.css">
</head>
<body>
<div class="balanceBottomLine">
<a href="addExpenses.html">
<button id="addExpenses" class="viewButtons">Add Expenses </button>
</a>
<a href = "addIncome.html">
<button id="addIncome" class="viewButtons">Add Income</button>
</a>
<a href = "checkStatistics.html">
<button id="statistics" class="viewButtons">Check Statistics</button>
</a>
<div class="moneyHave">
<p class="currencySign">$</p> <p class="moneyAmount" id="moneyAmount">000,000,000,000</p>
</div>
</div>
<div class="dataVisBox">
</div>
<script src="dbFunctions.js"></script>
<script src="financetracker.js"></script>
</body>
</html>
1条答案
按热度按时间ghhkc1vu1#
这里错误的原因是dbFunctions.js文件中的db变量在checkAndInitializeTotalMoney()方法中显示为未定义。
溶液1
**解决方案1:**您可以通过使用Promise和await构造来解决此问题,这样首先访问db,然后使用checkAndInitializeTotalMoney()方法。这是第一个解决方案。
其中:dbFunctions.js AND finanstracker.html
并像这样调用financetracker.js中的init()方法:
溶液2
**解决方案2:**如果你想要一个不太复杂的结构;您可能希望在每次数据库操作之前打开数据库并执行操作。
dbFunctions.js
并像这样调用financetracker.js中的init()方法:
尝试这两种解决方案后,控制台输出: