I have page (MyNotes.js) that show all the notes specific for that user. So when a button is pressed for detail view the user is redirected to another page (NoteDetail.js) where I am passing the id specific of that specific note. In redirect page with help of the id I call an api and populate the data. But now if user presses the back button to the previous page (MyNotes.js) I get the below error
MyNotes.js:30 Uncaught TypeError: notes.map is not a function
at MyNotes (MyNotes.js:30:1)
at renderWithHooks (react-dom.development.js:14985:1)
at mountIndeterminateComponent (react-dom.development.js:17811:1)
at beginWork (react-dom.development.js:19049:1)
at HTMLUnknownElement.callCallback (react-dom.development.js:3945:1)
at Object.invokeGuardedCallbackDev (react-dom.development.js:3994:1)
at invokeGuardedCallback (react-dom.development.js:4056:1)
at beginWork$1 (react-dom.development.js:23964:1)
at performUnitOfWork (react-dom.development.js:22776:1)
at workLoopSync (react-dom.development.js:22707:1)
These are the codes of the pages I mentioned above
MyNotes.js
import React, { useEffect, useContext } from "react";
import { useNavigate } from "react-router-dom";
import Noteitem from "../components/NoteItem";
import AuthContext from "../context/AuthContext";
import noteContext from "../context/NotesContext";
const MyNotes = () => {
const context = useContext(noteContext);
const { user, authtoken } = useContext(AuthContext);
const { notes, getNotes } = context;
const navigate = useNavigate();
useEffect(() => {
if (user) {
getNotes();
} else {
navigate("/login");
}
// eslint-disable-next-line
}, []);
return (
<>
<div className="container my-4">
<h1>Hello {user.name}</h1>
</div>
<div className="row my-2">
<h1>Your Notes</h1>
<div className="container">
{notes.length === 0 && "No Notes to display"}
</div>
{notes.map((notes) => {
return <Noteitem key={notes.id} note={notes} />;
})}
</div>
</>
);
};
export default MyNotes;
NoteItem.js This is page that contains the function to handle the redirection
import React, { useContext, useEffect, useState } from "react";
import { Link, useNavigate } from "react-router-dom";
import noteContext from "../context/NotesContext";
import NoteDetail from "../pages/NoteDetail";
const NoteItem = (props) => {
const { note } = props;
const { deleteNote } = useContext(noteContext);
const navigate = useNavigate();
const toDetailPage = () => {
navigate(`/notedetail/${note.id}`, { state: { id: note.id } });
};
return (
<div className="col-md-3">
<div className="card">
<div className="card-body">
<div className="d-flex align-items-center">
<h5 className="card-title">{note.title}</h5>
<i
className="fas fa-trash-alt mx-2 delete"
onClick={() => {
deleteNote(note.id);
}}
></i>
<i className="far fa-edit mx-2 edit"></i>
</div>
<p className="card-text"> Tags: {note.tags}</p>
<button
onClick={() => {
toDetailPage();
}}
className="btn btn-primary"
>
Read Note
</button>
</div>
</div>
</div>
);
};
export default NoteItem;
NoteDetail.js
import React, { useContext, useEffect, useState } from "react";
import { useLocation } from "react-router-dom";
import noteContext from "../context/NotesContext";
const NoteDetail = () => {
const { notes, noteDetail } = useContext(noteContext);
const location = useLocation();
const { id } = location.state;
useEffect(() => {
noteDetail(id);
console.log("This is note recieved in NoteDetail.js", notes);
}, [id]);
return (
<div className="container">
<p>{notes.id}</p>
<p> {notes.title} </p>
<p> {notes.description} </p>
<p> {notes.tags} </p>
</div>
);
};
export default NoteDetail;
Please suggest me what shuld I do to rectify this error
CodePudding user response:
Simply check if notes are not undefined.
{notes && notes.length? notes.map((notes) => {
return <Noteitem key={notes.id} note={notes} />;
}) : <p>No notes found!</p>}
notes && notes.length are checkinf if notes exist and if it has anything in its array. And then the ternary operator either maps data, or returns no data found
CodePudding user response:
You can change your my-2 div to something like this:
<div className="row my-2">
<h1>Your Notes</h1>
{notes.length === 0 ? (
<div className="container">"No Notes to display"}</div>
) : (
notes.map(notes => <Noteitem key={notes.id} note={notes} />)
)}
</div>
If you have no notes, it'll render "No Notes to display" and otherwise, it'll render your component.