Open MuskanNazim opened 2 weeks ago
The primary issue reported is that the dashboard and lists for budgets and incomes are not displaying any values. This is likely due to the dependency on the user
object and its properties, which are not being correctly populated or accessed. Additionally, there is a lack of error handling and loading states, which can lead to silent failures and poor user experience.
To solve this, we need to ensure that the user
object is correctly populated before making any database queries. We should also add error handling to log any issues and provide feedback to the user. Finally, we should introduce loading states to differentiate between loading data and having no data.
The bug is caused by the following issues:
user
object. If the user
object is not correctly populated, the functions will not fetch data.user?.primaryEmailAddress?.emailAddress
to filter data. If this property is not correctly populated, the queries will not return any results."use client"
import React, { useEffect, useState } from 'react'
import CreateBudget from './CreateBudget'
import { db } from '@/utils/dbConfig'
import { desc, eq, getTableColumns, sql } from 'drizzle-orm'
import { Budgets, Expenses } from '@/utils/schema'
import { useUser } from '@clerk/nextjs'
import BudgetItem from './BudgetItem'
function BudgetList() {
const [budgetList, setBudgetList] = useState([]);
const [loading, setLoading] = useState(true);
const { user } = useUser();
useEffect(() => {
if (user && user.primaryEmailAddress?.emailAddress) {
getBudgetList();
}
}, [user]);
const getBudgetList = async () => {
try {
const result = await db.select({
...getTableColumns(Budgets),
totalSpend: sql `sum(${Expenses.amount})`.mapWith(Number),
totalItem: sql `count(${Expenses.id})`.mapWith(Number)
}).from(Budgets)
.leftJoin(Expenses, eq(Budgets.id, Expenses.budgetId))
.where(eq(Budgets.createdBy, user.primaryEmailAddress.emailAddress))
.groupBy(Budgets.id)
.orderBy(desc(Budgets.id));
setBudgetList(result);
} catch (error) {
console.error("Failed to fetch budget list:", error);
} finally {
setLoading(false);
}
}
return (
<div className='mt-7'>
<div className='grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-5'>
<CreateBudget refreshData={() => getBudgetList()} />
{loading ? (
[1, 2, 3, 4, 5].map((item, index) => (
<div key={index} className='w-full bg-slate-200 rounded-lg h-[150px] animate-pulse'></div>
))
) : (
budgetList.length > 0 ? budgetList.map((budget, index) => (
<BudgetItem budget={budget} key={index} />
)) : (
<div>No budgets found.</div>
)
)}
</div>
</div>
)
}
export default BudgetList
import React, { useEffect, useState } from 'react';
import { db } from '@/utils/dbConfig';
import { desc, eq, getTableColumns, sql } from 'drizzle-orm';
import { Budgets, Expenses, Incomes } from '@/utils/schema';
import { useUser } from '@clerk/nextjs';
import CardInfo from './CardInfo';
import BarChartDashboard from './BarChartDashboard';
import ExpenseListTable from './ExpenseListTable';
import BudgetItem from './BudgetItem';
function DashboardPage() {
const [budgetList, setBudgetList] = useState([]);
const [incomeList, setIncomeList] = useState([]);
const [expensesList, setExpensesList] = useState([]);
const [loading, setLoading] = useState(true);
const { user } = useUser();
useEffect(() => {
if (user && user.primaryEmailAddress?.emailAddress) {
getBudgetList();
} else {
console.error("User email address is not available");
}
}, [user]);
const getBudgetList = async () => {
try {
const result = await db
.select({
...getTableColumns(Budgets),
totalSpend: sql`sum(${Expenses.amount})`.mapWith(Number),
totalItem: sql`count(${Expenses.id})`.mapWith(Number),
})
.from(Budgets)
.leftJoin(Expenses, eq(Budgets.id, Expenses.budgetId))
.where(eq(Budgets.createdBy, user?.primaryEmailAddress?.emailAddress))
.groupBy(Budgets.id)
.orderBy(desc(Budgets.id));
setBudgetList(result);
getAllExpenses();
getIncomeList();
} catch (error) {
console.error("Error fetching budget list:", error);
} finally {
setLoading(false);
}
};
const getIncomeList = async () => {
try {
const result = await db
.select({
...getTableColumns(Incomes),
totalAmount: sql`SUM(CAST(${Incomes.amount} AS NUMERIC))`.mapWith(Number),
})
.from(Incomes)
.groupBy(Incomes.id);
setIncomeList(result);
} catch (error) {
console.error("Error fetching income list:", error);
}
};
const getAllExpenses = async () => {
try {
const result = await db
.select({
id: Expenses.id,
name: Expenses.name,
amount: Expenses.amount,
createdAt: Expenses.createdAt,
})
.from(Budgets)
.rightJoin(Expenses, eq(Budgets.id, Expenses.budgetId))
.where(eq(Budgets.createdBy, user?.primaryEmailAddress?.emailAddress))
.orderBy(desc(Expenses.id));
setExpensesList(result);
} catch (error) {
console.error("Error fetching expenses list:", error);
}
};
return (
<div>
<CardInfo budgetList={budgetList} incomeList={incomeList} expensesList={expensesList} />
<BarChartDashboard budgetList={budgetList} incomeList={incomeList} expensesList={expensesList} />
<ExpenseListTable expensesList={expensesList} />
<div className='grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-5'>
{loading ? (
[1, 2, 3, 4, 5].map((item, index) => (
<div key={index} className='w-full bg-slate-200 rounded-lg h-[150px] animate-pulse'></div>
))
) : (
budgetList.length > 0 ? budgetList.map((budget, index) => (
<BudgetItem budget={budget} key={index} />
)) : (
<div>No budgets found.</div>
)
)}
</div>
</div>
);
}
export default DashboardPage;
"use client"
import React, { useEffect, useState } from 'react'
import CreateIncomes from './CreateIncomes'
import { db } from '@/utils/dbConfig'
import { desc, eq, getTableColumns, sql } from 'drizzle-orm'
import { Incomes, Expenses } from '@/utils/schema'
import { useUser } from '@clerk/nextjs'
import IncomeItem from './IncomeItem'
function IncomeList() {
const [incomelist, setIncomelist] = useState([]);
const [loading, setLoading] = useState(true);
const { user } = useUser();
useEffect(() => {
if (user) {
getIncomelist();
}
}, [user]);
const getIncomelist = async () => {
try {
const result = await db
.select({
...getTableColumns(Incomes),
totalSpend: sql`sum(${Expenses.amount})`.mapWith(Number),
totalItem: sql`count(${Expenses.id})`.mapWith(Number),
})
.from(Incomes)
.leftJoin(Expenses, eq(Incomes.id, Expenses.budgetId))
.where(eq(Incomes.createdBy, user?.primaryEmailAddress?.emailAddress))
.groupBy(Incomes.id)
.orderBy(desc(Incomes.id));
setIncomelist(result);
} catch (error) {
console.error("Error fetching income list:", error);
} finally {
setLoading(false);
}
};
return (
<div className="mt-7">
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-5">
<CreateIncomes refreshData={() => getIncomelist()} />
{loading ? (
[1, 2, 3, 4, 5].map((item, index) => (
<div key={index} className="w-full bg-slate-200 rounded-lg h-[150px] animate-pulse"></div>
))
) : incomelist.length > 0 ? (
incomelist.map((budget, index) => (
<IncomeItem budget={budget} key={index} />
))
) : (
<div>No incomes found.</div>
)}
</div>
</div>
);
}
export default IncomeList;
app/dashboard/page.jsx
, BudgetList.jsx
, and IncomeList.jsx
.By implementing the suggested changes, the issues related to user dependency, error handling, and loading states should be resolved, leading to the correct display of budget and income values on the dashboard.
Click here to create a Pull Request with the proposed solution
Files used for this task:
Error shows..function sum(varying character)does not exists On line 20 showing error on await db
See..I used your code for expense tracker from github...I have followed your YouTube video as well...but when I run the project everything is running...but not showing the values...means if I create the budget it's not showing..if I create a income source it's also not showing..don't know why..also on the dashboard page the tables containing values are empty..showing errors in app/dashboard/page.jsx and and in budgetlist.jsx,incomelist.jsx as well. Please help me