I want to show the data of customers from Redux and the data is successfully stored in Redux. I checked it with ReactDevTools
the error is when I use useSelect
to retrieve the data from the store.
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 dispatched to 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 it’s 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
}
console logging entries
2
Answers
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 indata
.Also consider updating the
if
:Issue
You are storing the entire
entries
response into your store, which is an object and thus doesn’t havelength
ormap
properties to use in the UI.Solution Suggestion
While you could access the
entries.data
array of the object in the UI like the other answer suggests it would make a bit more sense to only store the exact data you need.Examples:
Or to select the exact state you want in the UI if you are storing the entire response object in the store.
Example:
From here
entries
will be the array you were expecting all along.