I added subproject(collection) to project (collection).
I put one of the elements in props. But It can't be defined.
I also would like to loop and display all elements? How Should I do?
The error =>
×
TypeError: Cannot read property 'RFv6bJMG2dmiBqWNZX8O' of undefined
TypeError: Cannot read property 'map' of undefined
23 |
| ^ 24 | {project.answers.map(answer => {
25 | return (
26 | {answer.id}
https://github.com/ayush221b/MarioPlan-react-redux-firebase-app/blob/master/src/Components/projects/ProjectDetails.js
const ProjectDetails = (props) => {
const { project } = props;
if (project) {
return (
<div className="container section project-details">
<div className="card z-depth-0">
<div className="card-content">
<span className="card-title">{ project.title }</span>
<p>{ project.content }</p>
</div>
<div className="card-action gret lighten-4 grey-text">
<div>Posted by {project.userName}</div>
<div>2nd, September, 2am</div>
</div>
<-- I would to display all data of sub projects-->
<div>{project.subproject['RFv6bJMG2dmiBqWNZX8O'].contents}</div>
{project.answers && project.answers.map(answer => {
return (
<div>{answer.id}
{answer.content}
</div>
)
</div>
</div>
)}
const mapStateToProps = (state, ownProps) => {
const id = ownProps.match.params.id;
const projects = state.firestore.data.projects;
const project = projects ? projects[id] : null;
const subprojects = project ? project.subprojects : "unloaded";
console.log("sub ="+JSON.stringify(subprojects));
return {
project: project
}
}
export default compose(
connect(mapStateToProps),
firestoreConnect(props => [
{collection: 'projects'},
{
collection: 'projects',
doc:props.match.params.id,
subcollections :[{collection:'subprojects'}] }
]
))(ProjectDetails);
Try:
<div>answers = {project.subproject?.['RFv6bJMG2dmiBqWNZX8O']?.contents}</div>
Related
I am a beginner who wants to build a blog using Notion API, Next.js and Tailwind CSS. I learned the following code from here: https://egghead.io/lessons/next-js-request-notion-database-data-from-the-api-with-next-js.
The following code works fine in /post/index.js, but I get this error when I put the following code into /components/PostTest.js and import it in /index.js.
How do I solve this problem?
Error information
error screenshot
Server Error
TypeError: Cannot read properties of undefined (reading 'map')
#line 9
return posts.map((posts) => (
Source Code
import Head from "next/head";
import Link from "next/link";
import { Client } from "#notionhq/client";
import { useState } from "react";
export const PostPage = ({ posts }) => {
const [post] = useState(null);
return posts.map((posts) => (
<div className="bg-[#F5F5F7] dark:bg-black px-4 py-2 md:py-4">
<div className="bg-[#FFFFFF] dark:bg-[#141414] max-w-sm rounded-xl overflow-hidden shadow-sm container mx-auto">
<img
className="aspect-[16/9] bg-cover bg-center"
src={posts.coverImage}
alt="Post Banner"
/>
<div className="px-6 py-4">
<p className="text-[12px] md:text-[14px] dark:text-[#888888] leading-5 font-[700] pt-2 uppercase tracking-normal mb-[8px]">
{posts.Category}
</p>
<Link href={`/post/${posts.PID}`}>
<div className="text-lg md:text-xl text-[#1d1d1f] dark:text-[#F5F5F7] leading-snug font-[700]">
{posts.Title}
</div>
</Link>
<p className="text-[14px] text-[#6e6e73] dark:text-[#888888] leading-5 font-[600] pt-2">
{new Date(posts.Date).toLocaleDateString()}
</p>
</div>
</div>
</div>
));
};
export const getStaticProps = async () => {
const notion = new Client({
auth: process.env.NOTION_TOKEN,
});
// get posts more than 100 pages.
let results = [];
let data = await notion.databases.query({
database_id: process.env.NOTION_POST_DATABASE_ID,
filter: {
property: "Status",
select: {
equals: "Published",
},
},
sorts: [
{
property: "Date",
direction: "descending",
},
],
});
results = [...data.results];
while (data.has_more) {
data = await notion.databases.query({
database_id: process.env.NOTION_POST_DATABASE_ID,
filter: {
property: "Status",
select: {
equals: "Published",
},
},
start_cursor: data.next_cursor,
});
results = [...results, ...data.results];
}
const posts = results.map((post) => ({
id: post.id,
Title: post.properties.Title.title[0].text.content,
Category: post.properties.Category.select.name,
category_color: post.properties.Category.select.color,
Date: post.properties.Date.date.start,
Tags: post.properties.Tags.multi_select.map((Tags) => Tags.name),
Tags_color: post.properties.Tags.multi_select.map((TagsColor) => TagsColor.color),
PID: post.properties.PID.rich_text[0].text.content,
Author: post.properties.Author.people.map((people) => people.name),
Author_avatar_url: post.properties.Author.people.map((people) => people.avatar_url),
coverImage:
post.cover.file?.url ||
post.cover.external?.url,
}));
return {
props: {
posts,
},
revalidate: 1,
};
};
export default PostPage;
First of all, post should be inited with an empty array:
const [post, ] = useState([]);
Secondly, you cannot return an array of JSX, so wrap it in a Fragment or <>.
return (
<>
posts.map((posts) => (
...
)
</>
)
if posts is null or it's not an array, you'll get that error.
Try this fix
return (
posts?.map((posts) => (
...
)
)
On my Localhost:3000, when I am running the code, I am getting an error saying:
Unhandled Runtime Error
TypeError: Cannot read properties of undefined (reading 'id')
For the Source part, it is showing a certain section of my code, which is:-
;(async () => {
20 | setSelectedMarketNft(
> 21 | listings.find((marketNft) => marketNft.asset?.id === selectedNft.id)
| ^
22 | )
23 | })()
24 | }, [selectedNft, listings, isListed])
There are certain questions of the similar type on stackOverflow, but I am unable to find any answers from any of them. I am making a web3 project, where I am using next.js, sanity and thirweb.
The source code that contains this is:-
const MakeOffer = ({ isListed, selectedNft, listings, marketPlaceModule }) => {
const [selectedMarketNft, setSelectedMarketNft] = useState()
const [enableButton, setEnableButton] = useState(false)
useEffect(() => {
if (!listings || isListed === 'false') return
;(async () => {
setSelectedMarketNft(
listings.find((marketNft) => marketNft.asset?.id === selectedNft.id)
)
})()
}, [selectedNft, listings, isListed])
useEffect(() => {
if (!selectedMarketNft || !selectedNft) return
setEnableButton(true)
}, [selectedMarketNft, selectedNft])
Link to the full source code of the file where this error is occuring is:-
https://github.com/hemang-h/Standard-Demo-Marketplace-and-Minting/blob/main/components/nft/Purchase.js
Can anyone guide me what I am doing wrong here?
EXTRAS
Just for a better understanding, this is the full source code of the file where I am facing this error:
import { useEffect, useState } from 'react'
import { HiTag } from 'react-icons/hi'
import { IoMdWallet } from 'react-icons/io'
import toast, { Toaster } from 'react-hot-toast'
const style = {
button: `mr-8 flex items-center py-2 px-12 rounded-lg cursor-pointer`,
buttonIcon: `text-xl`,
buttonText: `ml-2 text-lg font-semibold`,
}
const MakeOffer = ({ isListed, selectedNft, listings, marketPlaceModule }) => {
const [selectedMarketNft, setSelectedMarketNft] = useState()
const [enableButton, setEnableButton] = useState(false)
useEffect(() => {
if (!listings || isListed === 'false') return
;(async () => {
setSelectedMarketNft(
listings.find((marketNft) => marketNft.asset?.id === selectedNft.id)
)
})()
}, [selectedNft, listings, isListed])
useEffect(() => {
if (!selectedMarketNft || !selectedNft) return
setEnableButton(true)
}, [selectedMarketNft, selectedNft])
const confirmPurchase = (toastHandler = toast) =>
toastHandler.success(`Purchase successful!`, {
style: {
background: '#04111d',
color: '#fff',
},
})
const buyItem = async (
listingId = selectedMarketNft.id,
quantityDesired = 1,
module = marketPlaceModule
) => {
console.log(listingId, quantityDesired, module, 'david')
// yo RAZA lets goooo!!!
//yo Qazi, ok
// sure okay about to run it...
// just clicked buy now...
// still error
// where can i see the contract address of the marketplace module
// in [nftId.js]
await module
.buyoutDirectListing({
listingId: listingId,
quantityDesired: quantityDesired,
})
.catch((error) => console.error(error))
confirmPurchase()
}
return (
<div className="flex h-20 w-full items-center rounded-lg border border-[#151c22] bg-[#303339] px-12">
<Toaster position="bottom-left" reverseOrder={false} />
{isListed === 'true' ? (
<>
<div
onClick={() => {
enableButton ? buyItem(selectedMarketNft.id, 1) : null
}}
className={`${style.button} bg-[#2081e2] hover:bg-[#42a0ff]`}
>
<IoMdWallet className={style.buttonIcon} />
<div className={style.buttonText}>Buy Now</div>
</div>
<div
className={`${style.button} border border-[#151c22] bg-[#363840] hover:bg-[#4c505c]`}
>
<HiTag className={style.buttonIcon} />
<div className={style.buttonText}>Make Offer</div>
</div>
</>
) : (
<div className={`${style.button} bg-[#2081e2] hover:bg-[#42a0ff]`}>
<IoMdWallet className={style.buttonIcon} />
<div className={style.buttonText}>List Item</div>
</div>
)}
</div>
)
}
export default MakeOffer
selectedNFT is undefined as mentioned above.
The issue could be that it is running your code before it's defined.
This may go in your return function:
{(typeof selectedNFT != 'undefined') ? (
<div>Code that fetches from selectedNFT goes here.</div>
): (
<div>This could be a loading bar..</div>
)}
This will run your code ONLY after everything else executes.
You can check by console seletedNft inside makeoffer component to make sure you are getting props correctly and also check if its return object which has key with name "id" . Its cannot read id property in your selectedNft make sure its exist . I hope its help.
The error is solved, turns out that I just had to add
if(!selectedNft) return;
to successfully run my code. Final code will be as:
import { useEffect, useState } from 'react'
import { HiTag } from 'react-icons/hi'
import { IoMdWallet } from 'react-icons/io'
import toast, { Toaster } from 'react-hot-toast'
const style = {
button: `mr-8 flex items-center py-2 px-12 rounded-lg cursor-pointer`,
buttonIcon: `text-xl`,
buttonText: `ml-2 text-lg font-semibold`,
}
const MakeOffer = ({ isListed, selectedNft, listings, marketPlaceModule }) => {
const [selectedMarketNft, setSelectedMarketNft] = useState()
const [enableButton, setEnableButton] = useState(false)
useEffect(() => {
if(!selectedNft) return;
if (!listings || isListed === 'false') return
;(async () => {
setSelectedMarketNft(
listings.find((marketNft) => marketNft.asset?.id === selectedNft.id)
)
})()
}, [selectedNft, listings, isListed])
useEffect(() => {
if (!selectedMarketNft || !selectedNft) return
setEnableButton(true)
}, [selectedMarketNft, selectedNft])
const confirmPurchase = (toastHandler = toast) =>
toastHandler.success(`Purchase successful!`, {
style: {
background: '#04111d',
color: '#fff',
},
})
const buyItem = async (
listingId = selectedMarketNft.id,
quantityDesired = 1,
module = marketPlaceModule
) => {
console.log(listingId, quantityDesired, module, 'david')
// yo RAZA lets goooo!!!
//yo Qazi, ok
// sure okay about to run it...
// just clicked buy now...
// still error
// where can i see the contract address of the marketplace module
// in [nftId.js]
await module
.buyoutDirectListing({
listingId: listingId,
quantityDesired: quantityDesired,
})
.catch((error) => console.error(error))
confirmPurchase()
}
return (
<div className="flex h-20 w-full items-center rounded-lg border border-[#151c22] bg-[#303339] px-12">
<Toaster position="bottom-left" reverseOrder={false} />
{isListed === 'true' ? (
<>
<div
onClick={() => {
enableButton ? buyItem(selectedMarketNft.id, 1) : null
}}
className={`${style.button} bg-[#2081e2] hover:bg-[#42a0ff]`}
>
<IoMdWallet className={style.buttonIcon} />
<div className={style.buttonText}>Buy Now</div>
</div>
<div
className={`${style.button} border border-[#151c22] bg-[#363840] hover:bg-[#4c505c]`}
>
<HiTag className={style.buttonIcon} />
<div className={style.buttonText}>Make Offer</div>
</div>
</>
) : (
<div className={`${style.button} bg-[#2081e2] hover:bg-[#42a0ff]`}>
<IoMdWallet className={style.buttonIcon} />
<div className={style.buttonText}>List Item</div>
</div>
)}
</div>
)
}
export default MakeOffer
I am working on a big project and I got an error.
It's a popup window.
I added it inside my app js file.
Before I added, everything went well, but now I got an error.😭
If anyone knows what my problem is, please let me know.
It should look like this:
This is my code, I copied it from an HTML, CSS, and JS tutorial:
import React from 'react';
import "./Popup.styles.css";
function Popup() {
const openModalButtons = document.querySelectorAll('[data-modal-target]')
const closeModalButtons = document.querySelectorAll('[data-close-button]')
const overlay = document.getElementById('overlay')
openModalButtons.forEach(button => {
button.addEventListener('click', () => {
const modal = document.querySelector(button.dataset.modalTarget)
openModal(modal)
})
})
overlay.addEventListener('click', () => {
const modals = document.querySelectorAll('.modal.active')
modals.forEach(modal => {
closeModal(modal)
})
})
closeModalButtons.forEach(button => {
button.addEventListener('click', () => {
const modal = button.closest('.modal')
closeModal(modal)
})
})
function openModal(modal) {
if (modal == null) return
modal.classList.add('active')
overlay.classList.add('active')
}
function closeModal(modal) {
if (modal == null) return
modal.classList.remove('active')
overlay.classList.remove('active')
}
return (
<div>
<button data-modal-target="#modal">Open Modal</button>
<div class="modal" id="modal">
<div class="modal-header">
<div class="title">Example Modal</div>
<button data-close-button class="close-button">×</button>
</div>
<div class="modal-body">
Lorem ipsum...
</div>
</div>
</div>
)
}
export default Popup
And this is the error I got:
TypeError: null is not an object (evaluating 'overlay.addEventListener')
Popup
src/Popup.js:17
14 | })
15 | })
16 |
> 17 | overlay.addEventListener('click', () => {
| ^ 18 | const modals = document.querySelectorAll('.modal.active')
19 | modals.forEach(modal => {
20 | closeModal(modal)
Please answer, you won't hurt my feelings.
Thank you in advance!
Emiel
just can't seem to fix this null spread operator which is occurring when my charities (deconstructed from props) is empty. How do I best allow for this case? Any advice would be great. The error is occurring in the onCompleted function.
const Causes = ({ causes, charities }) => {
const [charitiesList, setCharitiesList] = useState(charities);
const causeIds = _.map(causes.edges, i => i.node.databaseId);
var causeYoutubeIds
const { data, loading, error } = useQuery(GET_CHARITIES_BY_CAUSE, {
variables: {
"id": causeIds
},
onCompleted(dt) {
const getCharitiesByCause = _.map(dt.charities.edges, i => ({ charity: i.node }));
setCharitiesList([...charitiesList , ...getCharitiesByCause]);
}
})
return (
<div>
<div className="columns is-multiline">
<div className="column">
<h2 className={styles.heading}>Charities Involved</h2>
<div className={styles.causeContainer}>
{
charitiesList &&
charitiesList.map((item) => {
return (
<div className={styles.charityCard}>
<Img src={item.charity.Charity.logo.mediaItemUrl} />
{item.charity.title}
</div>
)
})
}
</div>
</div>
</div>
</div>
)
}
From what it seems like. useState(charities); This charities is coming null. If it should have a value then you need to fix it. Or you can just add a check. useState(charities || []);
interface IRoleAddProps {
roles: Array<IRole>
}
interface IRoleAddState {
current: IRole | null
}
class RoleAdd extends React.Component<IRoleAddProps, IRoleAddState> {
state = {
current: null,
}
renderNoneSelect = () => {
return (
<div styleName="empty">
<SvgIcon name="arrow" styleName="icon-arrow" />
<span>Empty</span>
</div>
)
}
onRoleClick = (role: IRole) => {
this.setState({
current: role,
})
}
render() {
const { roles } = this.props
const current = this.state.current
return (
<div styleName="role-add">
<div styleName="role-list">
<div styleName="title">Select role:</div>
<div styleName="list">
{roles.map(role => {
const cls = classNames({
item: true,
active: current && ( current.id === role.id )
})
return (
<div
key={role.id}
styleName={cls}
className="g-text-inline"
onClick={this.onRoleClick.bind(this, role)}
>
<CheckBox />
<span>{role.name}</span>
</div>
)
})}
</div>
</div>
<div styleName="view">
{!current && this.renderNoneSelect()}
{current && 'view'}
</div>
</div>
)
}
}
export default RoleAdd
The code like this, but TS still tells me:
Even I tried:
And "!" also doesn't work
As you can see the "current" object can't be null because i have null check before i use it.
But typescript engine still show me that error.
I'm wondering is that because i initialized current object with null value, but ts can not figure out types from setState, so it takes current always null?
You'll need to assign a type to state, like
state: IRoleAddState = {
current: null
};
Then, state will be of type IRoleAddState and not { current: null }. After that, the methods you tried will work.
Explicitly defining the state in a constructor should solve the issue.
constructor(props) {
super(props);
this.state = {
current: null;
}
}