So here i want to show the data of customers from redux and the data is successfulls stored in redux I checked it with ReactDevTools the error is when i use useSelect to retrive the data from the redux toom
error:
TypeError: entries.map is not a function
at Entries (http://localhost:5173/src/pages/Entries.jsx?t=1718705214409:80:59)
at renderWithHooks (http://localhost:5173/node_modules/.vite/deps/chunk-QO4NA2F3.js?v=1f9f66b9:11568:26)
at mountIndeterminateComponent (http://localhost:5173/node_modules/.vite/deps/chunk-QO4NA2F3.js?v=1f9f66b9:14946:21)
at beginWork (http://localhost:5173/node_modules/.vite/deps/chunk-QO4NA2F3.js?v=1f9f66b9:15934:22)
at beginWork$1 (http://localhost:5173/node_modules/.vite/deps/chunk-QO4NA2F3.js?v=1f9f66b9:19781:22)
at performUnitOfWork (http://localhost:5173/node_modules/.vite/deps/chunk-QO4NA2F3.js?v=1f9f66b9:19226:20)
at workLoopSync (http://localhost:5173/node_modules/.vite/deps/chunk-QO4NA2F3.js?v=1f9f66b9:19165:13)
at renderRootSync (http://localhost:5173/node_modules/.vite/deps/chunk-QO4NA2F3.js?v=1f9f66b9:19144:15)
at recoverFromConcurrentError (http://localhost:5173/node_modules/.vite/deps/chunk-QO4NA2F3.js?v=1f9f66b9:18764:28)
at performConcurrentWorkOnRoot (http://localhost:5173/node_modules/.vite/deps/chunk-QO4NA2F3.js?v=1f9f66b9:18712:30)
App.jsx where all the data is dispactched in store
useEffect(() => {
const initializeApp = async () => {
try {
const userData = await authService.getCurrentUser();
if (userData) {
dispatch(login({ userData }));
} else {
dispatch(logout());
}
const entries = await service.getEntries();
if (entries ) {
dispatch(setEntries(entries));
}
} catch (error) {
console.error('Initialization error:', error);
} finally {
setLoading(false);
}
};
initializeApp();
}, [dispatch]);
Entries.jsx Where I am trying to show the data
import React from 'react';
import { useSelector } from 'react-redux';
import { Link } from 'react-router-dom';
function Entries() {
const entries = useSelector(state => state.entry.entries)
console.log(entries);
return (
<div className='flex flex-col'>
<div className='mb-4'>
<Link className='bg-slate-600 text-white p-2 rounded' to='/addentry'>Add Entry</Link>
</div>
<div className="w-full">
{entries.length === 0 ? (
<div>No entries available</div>
) : (
<table className="min-w-full bg-white">
<thead>
<tr>
<th className="py-2">Customer Name</th>
<th className="py-2">Document Name</th>
<th className="py-2">Reception Date</th>
<th className="py-2">Submitter's Name</th>
<th className="py-2">Restitution Date</th>
<th className="py-2">Collector's Name</th>
</tr>
</thead>
<tbody>
{entries.map((entry) => (
<tr key={entry.id} className="text-center border-b">
<td className="py-2">{entry.customer_name}</td>
<td className="py-2">{entry.document_name}</td>
<td className="py-2">{entry.date}</td>
<td className="py-2">{entry.submitors_name}</td>
<td className="py-2">{entry.restitution_date }</td>
<td className="py-2">{entry.collectors_name}</td>
</tr>
))}
</tbody>
</table>
)}
</div>
</div>
);
}
export default Entries;
service class:
(I have used proxy here therefor half url and its working correctly)
import axios from 'axios';
export class Service {
async createEntry({ docName, subName }) {
try {
const response = await axios.post('/api/v1/e', {
docName,
subName
});
return response.data;
} catch (error) {
console.log("Custom backend service :: createEntry :: error", error);
}
}
async updateEntry({ docName, subName, entryid }) {
try {
const url = `/api/v1/e/${entryid}`;
const response = await axios.put(url, {
docName, subName
});
return response.data;
} catch (error) {
console.log("Custom backend service :: updateEntry :: error", error);
}
}
async deleteEntry(entryid) {
try {
const url = `/api/v1/e/${entryid}`;
await axios.delete(url);
return true;
} catch (error) {
console.log("Custom backend service :: deleteEntry :: error", error);
return false;
}
}
async getEntries() {
try {
const response = await axios.get('api/v1/e');
return response.data;
} catch (error) {
console.log("Custom backend service :: getEntries :: error", error);
return false;
}
}
async getEntry(entryid) {
try {
const response = await axios.get('/api/v1/e');
return response.data.data;
} catch (error) {
console.log("Custom backend service :: getPost :: error", error);
return false;
}
}
}
const service = new Service();
export default service;
entrySlice.js:
import { createSlice } from "@reduxjs/toolkit";
const initialState = {
entries: [],
};
const entrySlice = createSlice({
name: "entry",
initialState,
reducers: {
setEntries: (state, action) => {
state.entries = action.payload;
},
addEntry: (state, action) => {
state.entries.push(action.payload);
},
},
});
export const { setEntries, addEntry } = entrySlice.actions;
export default entrySlice.reducer;
Store.js:
import {configureStore} from '@reduxjs/toolkit';
import authSlice from './slice/authSlice';
import custSlice from './slice/custSlice';
import entrySlice from './slice/entrySlice';
const store = configureStore({
reducer: {
auth : authSlice,
entry: entrySlice,
customer: custSlice,
}
});
export default store;
data example from Post man
{
"statusCode": 200,
"data": [
{
"id": 1,
"customer_id": null,
"employe_id": null,
"document_name": "Pan",
"reception_date": "2024-03-04T18:30:00.000Z",
"submitors_name": "ved bhoskar",
"restitution_date": null,
"collectors_name": null
},
{
"id": 2,
"customer_id": null,
"employe_id": null,
"document_name": "Pan",
"reception_date": "2024-03-04T18:30:00.000Z",
"submitors_name": "ved bhoskar",
"restitution_date": null,
"collectors_name": null
},
],
"message": "Entries retrieved successfully",
"success": true
}
and any changes I should make?
Suggestions are welcomed
console logging entries
>Solution :
You’re trying to map over an object, that won’t work.
You’ll need entries.data.map since you’re pasting the complete object in your store, but the array you want to map over is in data.
Also consider updating the if:
{entries?.data.length === 0 ? (
<div>No entries available</div>
) : (
entries.data.map()
)}