Next js Problem - Sending data from one page to another - javascript

I have a file called Data.js where i've exported a list with some objects as below
export const DATA = [
{
'loc':'WEB',
'title':"Bukkit List",
'img':'/img/Projects/Bukkit-List.PNG',
'desc':"Bukkit-List is a easy to use and free task managing webapp, with password protection now!",
'fullDesc':""
},
{
'loc':'WEB',
'title':"SilenxIka-Github",
'img':'/img/Projects/SilenxIkaGithub.PNG',
'desc':"First github website for Project SilenxIka, which is completly made from vanilla HTML/CSS/JS",
'fullDesc':""
}
]
Now i have a page called projects.js where i've imported this list and displayed it's content in HTML as below
import Image from 'next/image';
import Link from 'next/link'
import { DATA } from '../../components/Data'
const WEB_RELATED = []
const PC_EXES = []
for(let i=0;i<DATA.length; i++){
if(DATA[i]['loc'] == 'WEB'){
WEB_RELATED.push(DATA[i])
}
else if(DATA[i]['loc'] == 'EXE'){
PC_EXES.push(DATA[i])
}
}
const WEB = WEB_RELATED.map(item =>
<div className="PROJECTS_Projects">
<div className="PROJECTS_Projects_Image">
<Image
className='PROJECTS_Projects_image'
src={item['img']}
layout='fill'
// objectFit='contain'
/>
</div>
{/* if someone clicks on this link i want them to go to [project].js and send This item to [projcet].js */}
// Link-2
<Link href={'/projects/' + WEB_RELATED.indexOf(item)}>
<a>{item['title']}</a>
</Link>
<p>{item['desc']}</p>
</div>
);
const PC = PC_EXES.map(item =>
<div className="PROJECTS_Projects">
<div className="PROJECTS_Projects_Image">
<Image
className='PROJECTS_Projects_image'
src={item['img']}
layout='fill'
// objectFit='contain'
/>
</div>
{/* if someone clicks on this link i want them to go to [project].js and send This item to [projcet].js */}
// LINK -1
<Link href={'/projects/' + PC_EXES.indexOf(item)}>
<a>{item['title']}</a>
</Link>
<p>{item['desc']}</p>
</div>
);
export default function index() {
return (
<div className="PROJECTS_Container">
<div className="PROJECTS_Sub_Container">
<div className="PROJECTS_New">
<h1>Web-Related</h1>
<div className="PROJECTS_Present">
{WEB}
</div>
</div>
<div className="PROJECTS_New">
<h1>Pc apllications</h1>
<div className="PROJECTS_Present">
{PC}
</div>
</div>
</div>
</div>
)
}
then i have a link in this page with link /projectsDisplay/{index_of_item_in_Data.js_List} which then leads to the page below
This projectDisplay.js file is covered in [] so it has the router.query thingie
export default function title({project}) {
return (
<div className='DISPLAY_Container'>
<div className="DISPLAY_Sub_Container">
<div className="DISPLAY_Image">
<Image
// src={`'/${img}'`}
src={'/img/Projects/Cluq.PNG'}
// src={data['img']}
layout='fill'
/>
</div>
<div className="DISPLAY_Info">
<h3>Here also</h3>
SUS
<p>Want data here</p>
</div>
</div>
</div>
)
}
I wanna display the same data the user clicked for in the first page, in simple words the item in the first page shall be accessible here in the last page's HTML

Related

Django REST / NextJS Problem displaying paginated api - TypeError: p.map is not a function

So I'm attempting to redo a personal blog site that I built entirely in Django with the template system with a DRF / Next.js set up. The problem is that I can display the blog posts on the page no problem with and unpaginated django serializer. When I paginate the django serializer because I only want a few posts on the from page I get the error
TypeError: p.map is not a function
Here is the code that works:
import Head from 'next/head'
import Image from 'next/image'
import styles from '../styles/Home.module.css'
import React, { Component } from 'react'
import Header from '../components/header'
import Link from 'next/link';
function Home({ p }) {
return (
<React.Fragment>
<Header />
<header className="masthead">
<div className="container position-relative px-4 px-lg-5">
<div className="row gx-4 gx-lg-5 justify-content-center">
<div className="col-md-10 col-lg-8 col-xl-7">
<div className="site-heading">
<h1>test</h1>
<span className="subheading">Test subheading</span>
</div>
</div>
</div>
</div>
</header>
{p.map((post) => (
<div className="container px-4 px-lg-5" key={post.id}>
<div className="row gx-4 gx-lg-5 justify-content-center">
<div className="col-md-10 col-lg-8 col-xl-7">
<div className="post-preview">
<Link href={`/posts/${encodeURIComponent(post.slug)}`}>
<a><h2 className="post-title">{ post.title }</h2>
<h3 className="post-subtitle">{ post.article_body.substr(0,50)}</h3></a>
</Link>
<p className="post-meta">
Posted by { post.author } in { post.article_type }
on { post.date_posted }
</p>
</div>
</div>
</div>
</div>
))}
<div className='container'>
<hr className="my-4" />
<div className="d-flex justify-content-end mb-4"><a className="btn btn-primary text-uppercase" href="/allposts">All Posts →</a></div>
</div>
</React.Fragment>
)
}
export async function getStaticProps() {
const res = await fetch("https://www.api.com/api");
const p = await res.json();
console.log
return{
props: {
p
},
};
};
export default Home;
This code displays all blog entries that are in the database and works just fine.
As soon as I change the api address to the paginated version I get the error:
TypeError: p.map is not a function
This api is being paginated by Django Rest Framework serializer.
If anyone could help me here it would be great. I've been banging my head against the wall for the last two days trying to figure this out.
At first check does your api returns an array? if it says map is not a function that's for sure that p is not an array

How can I implement cloudinary to display images as backgrounds dynamically? I can't see to fetch them correctly

I was wondering why I can't fetch the image from cloudinary, I want to post an image as an background,apparently I'm not fetching the image correctly.
function Post({post}){
return(
<div className='PostBlock'
style={{backgroundImage: `url(${post.getImage})`}}>
<div>
{console.log(post.getImage)}
<h3>genere:{post.getGenere}</h3>
</div>
<div>
<h3>Title: {post.getTitle}</h3>
</div>
<div>
<p>{post.getBody}</p>
</div>
</div>
)
}
export default Post
my PostForm which is a modal,this is where I succesfully upload my images after I click "save post", although the problem relies on fetching and showing the image url, which apparently I'm not doing so correctly, scroll down to the "Post" component code snippet
import { useState } from "react"
import Axios from "axios"
function PostFormModal({onAdd}){
let [getGenere,setGenere]=useState('Travel')
const [getTitle,setTitle]=useState('')
const [getBody,setBody]=useState('')
let [getImage,setImage]=useState('')
const uploadImage = () => {
const formData = new FormData()
formData.append("file",getImage)
formData.append("upload_preset","ddyy5zbx")
Axios.post("https://api.cloudinary.com/v1_1/dk5lv4qj5/image/upload",formData)
.then((res)=>console.log(res))
.catch((e)=>console.log(e))
}
//const genere = ['Travel','LifeStyle','Business','Food','Work']
const onSubmit=(e)=>{
e.preventDefault()
onAdd({getGenere,getTitle,getBody,getImage})
}
return(
<div className='formStyle' >
<form onSubmit={onSubmit} >
<div className="formStyleInner">
<label>Choose a genere: </label>
<select value={getGenere} onChange={e=>setGenere(e.target.value)}>
<option value='Travel'>Travel</option>
<option value='Lifestyle'>LifeStyle</option>
<option value='Business'>Business</option>
<option value='Food'>Food</option>
<option value='Work'>Work</option>
</ select>
</div>
<div className="formStyleInner">
<label>Title:</label>
<input type="text"
value={getTitle}
placeholder='add a title!'
onChange={(e)=>setTitle(e.target.value)}>
</input>
</div>
<div className="formStyleInner">
<label>Background Image:</label>
<input type="file"
onChange={(e)=>setImage(e.target.files[0])}>
</input>
</div>
<div className="formStyleInner">
<textarea type='textarea'
rows='10'
cols="35"
value={getBody}
placeholder='add text!'
onChange={(e)=>setBody(e.target.value)}>
</textarea>
</div>
<input type="submit" value="Save post" onClick={uploadImage}/>
</form>
</div>
)
}
export default PostFormModal
here's my App()
import { useState } from "react";
import PostList from "./component/PostList";
import PostModalBtn from "./component/postModalBtn";
import PostFormModal from "./component/PostFormModal";
import FilterButton from "./component/FilterButton";
//Filter MAP
const FilterMap = {
All:() => true,
Travel: genSel => genSel.Travel,
LifeStyle:genSel=> genSel.LifeStyle,
Business:genSel=> genSel.Business,
Food:genSel=> genSel.Food,
Work:genSel=>genSel.Work
}
const FilterNames=Object.keys(FilterMap)
function App({onAdd}) {
const [isModalDisplayed,setIsModalDisplayed]=useState(false)
const[filter, setFilter]= useState('All')
const[posts,setPosts]=useState(
[
{
id:1,
getTitle:'Titulo Generico',
getGenere:'Travel',
getBody:'Prueba de body'
},
]
)
//FilterList
const filterList = FilterNames.map(name=>(
<FilterButton
key={name}
name={name}
isPressed={name === filter}
setFilter={setFilter}/>
))
//addPost action
const addPost = (post)=>{
const id= Math.floor(Math.random()*1000)+1
const getPost = {id,...post}
setPosts([...posts,getPost])
}
return (
<>
<div className='headerTitle'>
<h5>Making your life easier</h5>
</div>
<div className='titleCont'>
<h1>Discovering the world</h1>
</div>
<div className='FilterBtnStyle'>
{filterList}
</div>
<div className='buttonCont'>
<PostModalBtn onClick={onAdd}/>
</div>
<PostFormModal onAdd={addPost}/>
<PostList posts={posts}/>
</>
);
}
export default App;
"Post" Component, this is where the background image is supposed to be brought dynamically, apparently I'm not calling it correctly because It's not fetching the right path...
function Post({post}){
return(
<div className='PostBlock'
style={{backgroundImage: `url(${post.getImage})`}}>
<div>
{console.log(post.getImage)}
<h3>genere:{post.getGenere}</h3>
</div>
<div>
<h3>Title: {post.getTitle}</h3>
</div>
<div>
<p>{post.getBody}</p>
</div>
</div>
)
}
export default Post
Inspecting the upload from the console, we can see that the object uploaded to cloudinary indeed has an url for us to use
What I'm actually fetching is an object appended to "getImage" and not an "url"
From what I've been reading, I cannot bring up images from cloudinary unless I use the IMAGE tag from cloudinary-react and cloudinary-core libraries, but I have NO clue how to implement that into an background-image
Once you have uploaded the image to Cloudinary, you can use the image URL like any other image URL to display the image on the HTML page. However, if you would like to use any of the Cloudinary helper methods then the public_id which is the name of the image on Clouudinary should be used which in this case is the one beginning with mqrhnpw.. (the last part of the Cloudinary URL after the version number).

Queried data disappears when webpack initially loads, then appears when I go to other page on website and return

Can anyone explain what's going on here?
On the index page referenced below there is a section where I source data from a WordPress API to generate the four most recent posts from a client. When running in develop mode with Gatsby, the website is presented fine, but when I upload the website to Netlify and build it out, the data disappears and leaves nothing more than an empty set of p tags.
When I go into development tools and step through breakpoints, I notice that the data in question appears on the website, but then disappears once the webpack fires and the modules are bundled. It's almost as if this data is getting overwritten. When I navigate away from this page on the same website, and then return, the p tags HAVE the data in question. I'm assuming the webpack overwrites the initial code, and then when I come back to the page the webpack has already fired so it loads the information fine? How do I work around this? Excuse me if this is a silly/obvious question.
Full code in reference:
import React from "react"
import { Link, graphql, useStaticQuery } from 'gatsby'
import Layout from '../components/layout'
import indexStyles from '../components/modules/index.module.css'
import Carousel from 'nuka-carousel'
import header1 from '../img/header1.jpg'
import header2 from '../img/header2.jpg'
import header3 from '../img/header3.jpg'
const IndexPage = () => {
const data = useStaticQuery(graphql`
query {
allWordpressPost (sort: {fields:date, order:DESC}) {
edges {
node {
title
slug
excerpt
date(formatString:"MMMM DD, YYYY")
}
}
}
}
`)
return (
<Layout>
<div className={indexStyles.indexCarousel_container}>
<Carousel
autoplay={true}
autoplayInterval={5000}
pauseOnHover={false}
wrapAround={true}
renderCenterLeftControls={({ previousSlide }) => (
<button onClick={previousSlide} className={indexStyles.indexCarousel_button}><i className="fas fa-arrow-left"></i></button>
)}
renderCenterRightControls={({ nextSlide }) => (
<button onClick={nextSlide} className={indexStyles.indexCarousel_button}><i className="fas fa-arrow-right"></i></button>
)}>
<div className={indexStyles.indexCarousel_slideContainer}>
<img src={header1} alt="Pencil case with cat, heart, and cupcake design."></img>
<div>
<h2>Shop</h2>
</div>
</div>
<div className={indexStyles.indexCarousel_slideContainer}>
<Link to="/blog"><img src={header2} alt="Notepad next to a cup of coffee."></img></Link>
<div>
<h2>Blog</h2>
</div>
</div>
<div className={indexStyles.indexCarousel_slideContainer}>
<img src={header3} alt="Colorful pencil cases."></img>
<div>
<h2>Cute Castle VIP</h2>
<p>Save 20%!</p>
</div>
</div>
</Carousel>
</div>
<h1 className={indexStyles.indexHeader}>Latest Posts</h1>
<div className={indexStyles.indexPost_container}>
<div className={indexStyles.indexPost_container}>
{data.allWordpressPost.edges.map((edge, i) => {
if (i < 4) {
return (
<div className={indexStyles.index_post}>
<h2><Link to={`/blog/${edge.node.slug}`} className={indexStyles.post_title} dangerouslySetInnerHTML={{ __html: edge.node.title }}></Link></h2>
<p className={indexStyles.post_date}>{edge.node.date}</p>
<p className={indexStyles.post_excerpt} dangerouslySetInnerHTML={{ __html: edge.node.excerpt }} />
<p><Link to={`/blog/${edge.node.slug}`} className={indexStyles.post_link}>Read more</Link></p>
</div>
)
}
})}
</div>
</div>
</Layout >
)
}
export default IndexPage
The section of code that disappears and reappears:
<div className={indexStyles.indexPost_container}>
<div className={indexStyles.indexPost_container}>
{data.allWordpressPost.edges.map((edge, i) => {
if (i < 4) {
return (
<div className={indexStyles.index_post}>
<h2><Link to={`/blog/${edge.node.slug}`} className={indexStyles.post_title} dangerouslySetInnerHTML={{ __html: edge.node.title }}></Link></h2>
<p className={indexStyles.post_date}>{edge.node.date}</p>
<p className={indexStyles.post_excerpt} dangerouslySetInnerHTML={{ __html: edge.node.excerpt }} />
<p><Link to={`/blog/${edge.node.slug}`} className={indexStyles.post_link}>Read more</Link></p>
</div>
)
}
})}
</div>
</div>
A link to the Netlify project.
https://zealous-engelbart-509321.netlify.com/
Thanks in advance for your help!

Why go back button doesn't trigger client side navigation in Next.js app?

I have a simple Next.js application that uses GraphQL to load articles from a server. Dynamic routing works perfectly fine unless you reload the page while you are on some article and want to go back.
A typical situation is completely fine
Index -> [slug] -> go back (Index)
But the issue is in this situation
[slug] -> go back(Index)
The page won't trigger rerender and while the url is pointing to Index, content on the page stays the same.
I've checked if my Link components are written correctly and they are.
This a component on Index page that contains link to redirect
const Index: FunctionComponent<IArticlePreviewProps> = (props) => {
const { article }: { article: IArticlePreviewData } = props;
return (
<Link href="/articles/[slug]" as={`/articles/${article.slug}`}>
<a>
<img src={article.thumbnail} alt=""/>
</a>
</Link>
)
}
And this is a component which is dynamic and shows article content
const Article: NextPage = (props) => {
const router = useRouter();
const { loading, data, error } = useQuery<IArticleQueryData>(ARTICLE_QUERY, {
variables: { id: router.query.slug }
});
if (loading) {
return null;
}
const article = data!.Article;
return (
<>
<div className="d-flex justify-content center">
<div className="container">
<div className="article">
<div className="article__header d-flex">
<div className="col-8 p-0 article__header-thumbnail">
<img src={article.thumbnail} alt=""/>
</div>
<div className="col-4 p-4 article__header-title d-flex flex-column justify-content-end">
<h1>{article.title}</h1>
<time className="article-date" dateTime={article.createdAt}>
{getArticlePreviewDate(article.createdAt)}
</time>
</div>
</div>
</div>
</div>
</div>
</>
)
}
It was just a bug in Next.js. It's already fixed.

ReactJS: Failed to execute 'removeChild' on 'Node' when updating component

I keep getting this error when attempting to update a component with new data fetched from a server.
Description:
Portfolio.js
I have an app that has a portfolio where the projects of the site are shown. When you click an item in portfolio, you are redirected (with react-router) to the individual project.
Project.js
The project component uses the fetch api to retrieve data from a server. Which works perfectly because when the url specifies the project to be show like: /portfolio/project/:id, and based on the id received the data is fetched and displayed correctly.
The data retrieved
What is retrieved trough fetch api is just the result of a AJAX POST request to a server with the only parameter of the project id, which only returns the info of the project. (name, description, images, and other ones not much important)
The issue:
As far I've analyzed the application to see when this error is triggered, I found that this warning comes out when the amount of images for the new project loaded is smaller than the amount of images of the project already rendered.
An example:
We are inside a project. The url is portfolio/project/1 and the server data returned that this project has 5 images. They are loaded and you can view the project correctly.
Now, we use the menu to react-router-redirect to portfolio/project/2 and the server returned data with 7 images. They are loaded and the project data as well to view the project.
So, let say that we choose the option in the menu to view the project portfolio/project/3 which has 3 images, and then the warning comes up.
Browser:
Console log:
The code:
Since the error says the problem is inside Project.js, I am only adding this code so the question doesn't look overloaded and full of weird code.
Project.js
import React,{Component} from 'react'
import Footer from '../Footer/Footer'
import Header from '../Header'
import SubNav from '../SubNav'
import Details from './Details'
import {Link} from 'react-router-dom'
import {Configurations} from '../AppConfig'
class Project extends Component{
state = {
projectInfo: null,
reloadHandlerActive: false,
projectID : this.props.match.params.id,
projectName: "",
topProjectInfo: [],
images: []
}
createImages = (project) =>{
let Images = Object.values(project.images),
ImagesURI = Images.map((img, index)=>{
if( img.includes('Desarrollos.jpg') || img.includes('Home.jpg') || img.includes('H.jpg') ){
return null
}
return project.path+img
})
ImagesURI = ImagesURI.filter(function (e) { //Clear null values
return e != null;
})
return ImagesURI
}
reloadHandler = (id) =>{
const {createImages} = this
fetch(Configurations.API.projectInfo(id))
.then((result)=>{return result.json() })
.then((project)=>{
if(project === "error"){
alert("Error")
}else{
this.setState({
projectInfo: project,
images: createImages(project)
},function(){
document.getElementsByClassName("nav-button")[0].click()
})
}
})
}
componentWillMount(){
const {createImages} = this
fetch(Configurations.API.projectInfo(this.state.projectID))
.then((result)=>{return result.json() })
.then((project)=>{
if(project === "error"){
alert("Error")
}else{
this.setState({
projectInfo: project,
images: createImages(project)
},function(){
window.initDogma()
})
}
})
}
componentDidMount(){
window.onload = window.initShit()
}
render(){
const {projectInfo,images} = this.state
console.log(projectInfo)
if(!projectInfo){
return(<h1>. . .</h1>)
}
return(
<div >
<Header />
<SubNav reloadHandler={this.reloadHandler} />
<div className="content full-height no-padding">
<div className="fixed-info-container">
<Link to="/portfolio"><button className="goBackBtn">Desarrollos</button></Link>
<h3>{projectInfo.project.project}</h3>
<div className="separator" />
<div className="clearfix" />
<p>
{projectInfo.project.address}
</p>
<span className="project-status">{projectInfo.project.status}</span>
<h4>Características</h4>
<Details price={projectInfo.project.price} features={projectInfo.project.features} />
<Link className=" btn anim-button trans-btn transition fl-l" to={"/contact/?project="+projectInfo.id}>
<span>Informes</span>
<i className="fa fa-eye" />
</Link>
</div>
{/* fixed-info-container end*/}
{/* resize-carousel-holder*/}
<div className="resize-carousel-holder vis-info gallery-horizontal-holder">
{/* gallery_horizontal*/}
<div
id="gallery_horizontal"
className="gallery_horizontal owl_carousel"
>
{
images.map((img,index)=>{
return (
<div key={index}className="horizontal_item">
<div className="zoomimage">
<img src={img} className="intense" alt="" />
<i className="fa fa-expand" />
</div>
<img src={img} alt="" />
<div className="show-info">
<span>Info</span>
<div className="tooltip-info">
<h5>Imagen de muestra</h5>
<p>
Imagen del desarrollo
</p>
</div>
</div>
</div>
)
})
}
</div>
{/* resize-carousel-holder*/}
{/* navigation */}
<div className="customNavigation">
<a href="/" className="prev-slide transition">
<i className="fa fa-angle-left" />
</a>
<a href="/" className="next-slide transition">
<i className="fa fa-angle-right" />
</a>
</div>
{/* navigation end*/}
</div>
{/* gallery_horizontal end*/}
</div>
<Footer />
</div>
)
}
}
export default Project
I'm currently looking how to fix this, but if someone could give me an advice or the origin of the issue would be really helpful.
By the time your question was posted, there was an issue open at reactjs github repo talking about something similar. It is now solved, but you may want to read the article.

Categories