Props not rendering for storybook component - reactjs

I have a component that will take an array of objects and will render a grid of lists
//Awards
import React from "react";
import MarkDown from "components/Design/MarkDown";
import { Grid } from "components/Design/Grid/Grid";
export const Awards = ({ list }) => {
return (
<Grid>
{list
.sort((a, b) => b.year - a.year)
.map((award) => (
<div
key={award.id}
className="flex flex-col gap-16 font-mulish col-span-4">
<h3 className="font-bold text-14-24 text-gray-dark">
{award.year}
</h3>
<div className="text-14-24 text-gray-text">
<MarkDown>{award.description}</MarkDown>
</div>
</div>
))}
</Grid>
);
};
When I try to write a story for the component, I get a warning TypeError: Object(...) is not a function. After several refresh I get Cannot access 'Awards' before initialization
//Awards.stories.jsx
import React from "react";
import { Awards } from "components/Awards";
export default {
title: "component/Awards",
component: Awards,
};
const list = [
{
id: 1,
year: 2018,
description:
"- Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\n\n - Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\n\n - Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.\n\n - Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.",
},
{
id: 2,
year: 2017,
description:
"- Lorem ipsum dolor sit amet\n\n - consectetur adipiscing elit.",
},
{
id: 3,
year: 2016,
description:
"- Lorem ipsum dolor sit amet\n\n - consectetur adipiscing elit.",
},
{
id: 4,
year: 2015,
description:
"- Lorem ipsum dolor sit amet\n\n - consectetur adipiscing elit.",
},
{
id: 5,
year: 2014,
description: "- Lorem ipsum dolor sit amet",
},
];
export const AwardsBlock = () => {
return <Awards list={list} />;
};
While debugging I found that if replace the part
{list
.sort((a, b) => b.year - a.year)
.map((award) => (
<div
key={award.id}
className="flex flex-col gap-16 font-mulish col-span-4">
<h3 className="font-bold text-14-24 text-gray-dark">
{award.year}
</h3>
<div className="text-14-24 text-gray-text">
<MarkDown>{award.description}</MarkDown>
</div>
</div>
))}
with something static
<span>——</span>
It works like a charm. Maybe something to do with lists throwing some error or not rendering.
What am I missing here?

Did you mean to do a named import for the Markdown component?
As in
import {MarkDown} from "components/Design/MarkDown";
instead of
import MarkDown from "components/Design/MarkDown";

Related

How to post to json sever

tried posting to json db but only gets the Id in the json server with no postdate, posttitle, postdesc and image. i dont know i am doing wrong.
I would also like to like to update a post and then should be redirected to the homepage after updating the post.
I had tried using Redirect, useHistory and then useNavigate ffrom react-router-dom but still isnt working
import { useEffect, useState } from "react";
import "./write.css";
import { useNavigate } from "react-router-dom";
export default function Write() {
const [image, setImage] = useState();
const [posttitle, setPostTitle] = useState("");
const [postdesc, setPostDesc] = useState("");
const [postdate, setPostDate] = useState("20/30/2020");
// const [postDate, setPostDate] = useState("");
const navigate = useNavigate();
//==============================================================//
//Publishing or posting a post to the json server
const formSubmit = (e)=> {
e.preventDefault();
const docs = {
image,
posttitle,
postdate,
postdesc,
};
fetch("http://localhost:8005/posts", {
method: "POST",
headers: { contentType: "application/json" },
body: JSON.stringify(docs),
}).then(() => {
navigate.push("/home");
});
console.log(docs);
}
//===============================================================//
// const { id } = useParams(); not working
// getting the id of the post to be edited using window.location.href
const url = window.location.href;
const id = url.substring(url.lastIndexOf("=") + 1);
// //editing/Updating post data in the json-server file
// function editBtn() {
// fetch("http://localhost:8005/posts/" + id, {
// method: "PUT",
// body: JSON.stringify(),
// headers: {
// contentType: "application.json",
// },
// });
// }
return (
<div className="write">
<form className="writeform" onSubmit={formSubmit}>
<div>
<input />
date here
</div>
<div className="image_container">
{image && (
<div>
<img
className="writeimage"
alt="postimage"
src={URL.createObjectURL(image)}
onChange={(e) => {
setImage(e.target.src);
}}
/>
</div>
)}
</div>
<div className="writeformgroup">
<label htmlFor="fileinput">
<i className="writeicon fa-solid fa-plus"></i>
</label>
<input
id="fileinput"
type="file"
onChange={(e) => {
setImage(e.target.files[0]);
}}
style={{ display: "none" }}
/>
<input
type="text"
// value={postTitle}
className="writeinput"
onChange={(e) => {
setPostTitle(e.target.value);
}}
autoFocus
/>
</div>
<div className="writeformgroup">
<textarea
// value={postDesc}
onChange={(e) => {
setPostDesc(e.target.value);
}}
type="text"
className="writeinput writetext"
></textarea>
</div>
<button className="writesubmit">Publish</button>
</form>
<p>{posttitle}</p>
</div>
);
}
//JSON DB
{
"posts": [
{
"image": "https://images.pexels.com/photos/9968415/pexels-photo-9968415.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1",
"posttitle": "Lorem ipsum dolor sit amet ",
"postdate": "20-29-2022",
"postdesc": "Lorem ipsum dolor sit amet consectetur adipisicing elit. Saepe, suscipit inventore. Facilis ducimus quod ratione, fugiat temporibus, porro vitae consequuntur aspernatur Lorem ipsum dolor sit amet consectetur adipisicing elit. Saepe, suscipit inventore. Facilis ducimus quod ratione, fugiat temporibus, porro vitae consequuntur aspernatur sequi ad eveniet necessitatibus reiciendis dolor deleniti qui mod",
"id": 1
},
{
"image": "https://images.pexels.com/photos/13957041/pexels-photo-13957041.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1",
"posttitle": "Lorem ipsum dolor sit amet ",
"postdate": "20-29-2022",
"postdesc": "Lorem ipsum dolor sit amet consectetur adipisicing elit. Saepe, suscipit inventore. Facilis ducimus quod ratione, fugiat temporibus, porro vitae consequuntur aspernatur Lorem ipsum dolor sit amet consectetur adipisicing elit. Saepe, suscipit inventore. Facilis ducimus quod ratione, fugiat temporibus, porro vitae consequuntur aspernatur sequi ad eveniet necessitatibus reiciendis dolor deleniti qui mod",
"id": 2
},
{
"image": "https://images.pexels.com/photos/13715795/pexels-photo-13715795.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1",
"posttitle": "Lorem ipsum dolor sit amet ",
"postdate": "20-29-2022",
"postdesc": "Lorem ipsum dolor sit amet consectetur adipisicing elit. Saepe, suscipit inventore. Facilis ducimus quod ratione, fugiat temporibus, porro vitae consequuntur aspernatur Lorem ipsum dolor sit amet consectetur adipisicing elit. Saepe, suscipit inventore. Facilis ducimus quod ratione, fugiat temporibus, porro vitae consequuntur aspernatur sequi ad eveniet necessitatibus reiciendis dolor deleniti qui mod",
"id": 3
},
{
"image": "https://images.pexels.com/photos/13420447/pexels-photo-13420447.jpeg?auto=compress&cs=tinysrgb&w=400&lazy=load",
"posttitle": "Lorem ipsum dolor sit amet ",
"postdate": "20-29-2022",
"postdesc": "Lorem ipsum dolor sit amet consectetur adipisicing elit. Saepe, suscipit inventore. Facilis ducimus quod ratione, fugiat temporibus, porro vitae consequuntur aspernatur Lorem ipsum dolor sit amet consectetur adipisicing elit. Saepe, suscipit inventore. Facilis ducimus quod ratione, fugiat temporibus, porro vitae consequuntur aspernatur sequi ad eveniet necessitatibus reiciendis dolor deleniti qui mod",
"id": 4
},
{
"image": "https://images.pexels.com/photos/13950829/pexels-photo-13950829.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1",
"posttitle": "Lorem ipsum dolor sit amet ",
"postdate": "20-29-2022",
"postdesc": "Lorem ipsum dolor sit amet consectetur adipisicing elit. Saepe, suscipit inventore. Facilis ducimus quod ratione, fugiat temporibus, porro vitae consequuntur aspernatur sequi ad eveniet necessitatibus reiciendis dolor deleniti qui mod",
"id": 5
},
{
"image": "https://images.pexels.com/photos/11055161/pexels-photo-11055161.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1",
"posttitle": "Lorem ipsum dolor sit amet ",
"postdate": "20-29-2022",
"postdesc": "Lorem ipsum dolor sit amet consectetur adipisicing elit. Saepe, suscipit inventore. Facilis ducimus quod ratione, fugiat temporibus, porro vitae consequuntur aspernatur sequi ad eveniet necessitatibus reiciendis dolor deleniti qui mod",
"id": 6
}
]
}
Try useHistory for redirect issues
import { useHistory } from 'react-router-dom';
const histroy = useHistory();
histroy.push({ pathname: '/home' });
Try async /await for fetch
const formSubmit = async () => {
try{
const response = await fetch("http://localhost:8005/posts", {
method: "POST",
headers: { contentType: "application/json" },
body: JSON.stringify(docs),
});
if(!response || !response.ok){
throw new Error('error message');
}
const data = response.json();
console.log(data);
}catch(error){
console.log(error);
}
}

Toggle FieldSet from an other component

How to make PrimeReact FieldSet controllable from an other (parent) component on React?
I have a boolean object toggled, i would like to pass it into child component.
When toggled = true, the FieldSet should be opened.
When toggled = false, the FieldSet should be closed.
import React from "react";
import { Fieldset } from "primereact/fieldset";
const FieldsetDemo = () => {
return (
<div>
<div className="card">
<h5>Toggleable</h5>
<Fieldset legend="Header" toggleable>
<p>
Lorem ipsum dolor sit amet.
</p>
</Fieldset>
</div>
</div>
);
};
Its easy. Working code sandbox: https://codesandbox.io/s/quizzical-snow-so91tv?file=/src/demo/FieldsetDemo.js
const FieldsetDemo = (props) => {
return (
<div>
<div className="card">
<h5>Toggleable</h5>
<Fieldset legend="Header" toggleable collapsed={props.collapsed}>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim
ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
aliquip ex ea commodo consequat. Duis aute irure dolor in
reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
culpa qui officia deserunt mollit anim id est laborum.
</p>
</Fieldset>
</div>
</div>
);
};
const rootElement = document.getElementById("root");
ReactDOM.render(<FieldsetDemo collapsed={true} />, rootElement);

ReactComponent renders the same SVG Element

I am importing an SVG element using the ReactComponent method as below:
import { ReactComponent as Height } from "../../assets/Height.svg";
import { ReactComponent as Closet } from "../../assets/Closet.svg";
import { ReactComponent as Shirt } from "../../assets/Shirt.svg";
When I render them on the screen like this:
<Height />
<Shirt />
<Closet />
It shows the first Icon for all the three renders, for example, for the above code it renders the Height SVG element for all of them.
Here is the full component:
import React from "react";
import styles from "./Features.module.css";
import featureImage from "../../assets/featureImage.png";
import { ReactComponent as Height } from "../../assets/Height.svg";
import { ReactComponent as Closet } from "../../assets/Closet.svg";
import { ReactComponent as Shirt } from "../../assets/Shirt.svg";
import FeatureBackground from "../../assets/FeatureBackground.png";
const Features = () => {
const bodyContent = [
{
icon: <Height />,
title: "Body measurement tracking",
body: "Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi ",
},
{
icon: <Closet />,
title: "In home trial of clothes and closet",
body: "Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi ",
},
{
icon: <Shirt />,
title: "Recommendation of clothes using AI",
body: "Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi ",
},
];
return (
<div className={styles.container}>
<div className={styles.mainSection}>
<div className={styles.images}>
<img
className={styles.featureBackground}
src={FeatureBackground}
alt="feature background"
/>
<img
className={styles.featureImage}
src={featureImage}
alt="features Image"
/>
</div>
<div className={styles.content}>
<h1>EVERYTHING YOU NEED!</h1>
<div className={styles.body}>
{bodyContent.map((content, i) => (
<div key={i} className={styles.bodyContent}>
<div className={styles.icon}> {content.icon} </div>
<div>
<h3>{content.title}</h3>
<p>{content.body}</p>
</div>
</div>
))}
</div>
</div>
</div>
<div className={styles.footerSection}>
<h2>
Enhance your shopping experience with elevated expertise and efficient
time constraints.
</h2>
</div>
</div>
);
};
export default Features;

React object rendering to fontawesome

how do i render an object to a font awesome component. i have an object with different properties and i am rendering them dynamically into my cards component so i have many cards with different contents. below is my code.
import React from "react";
import "../Styles/card.css";
import "bootstrap/dist/css/bootstrap.css";
import { FontAwesomeIcon } from "#fortawesome/react-fontawesome";
import { faCar, faTruck, faHome } from "#fortawesome/free-solid-svg-icons";
const Card = () => {
const Cards = [
{
_uid: "BUY6Drn9e1",
Icon: "faHome",
head: "Free and Fast",
text: "Lorem ipsum dolor sit, amet consectetur adipisicing elit. Aliquam
tempora illum magni minima dolor id sequi quibusdam omnis.",
},
{
_uid: "BUY6Drn9e1",
Icon: "faTruck",
head: "Post Transportation",
text: "Lorem ipsum dolor sit, amet consectetur adipisicing elit. Aliquam tempora illum magni minima dolor id sequi quibusdam omnis.",
},
{
_uid: "BUY6Drn9e1",
Icon: "faCar",
head: "Free and Fast",
text: "Lorem ipsum dolor sit, amet consectetur adipisicing elit. Aliquam tempora illum magni minima dolor id sequi quibusdam omnis.",
},
];
const renderCard = (Card, index) => {
const shape = Card.Icon;
console.log(shape);
return (
<div className="card carded col mx-1 mb-2" key={index}>
<div className="flex">
<div className=" sameRow icon">
{/* <i class="bi bi-truck" style={{ fontSize: 35 }}></i> */}
</div>
<div className="sameRow body">
<FontAwesomeIcon
icon={faCar}
className="pic"
style={{ fontSize: 25, color: "#66b2e9" }}
/>
<h3 className="head">{Card.head}</h3>
<p className="text">{Card.text}</p>
</div>
</div>
</div>
);
};
return <div className="row mt-5 pt-5 px-5">{Cards.map(renderCard)}</div>;
};
export default Card;
i am trying to replace the faCar with {Card.Icon}
You have made a mistake,
Link the font awesome icon to each item using the import name, not as strings.
const Cards = [
{
_uid: "BUY6Drn9e1",
Icon: faHome,
head: "Free and Fast",
text:
"Lorem ipsum dolor sit, amet consectetur adipisicing elit. Aliquam tempora illum magni minima dolor id sequi quibusdam omnis."
},
{
_uid: "BUY6Drn9e1",
Icon: faTruck,
head: "Post Transportation",
text:
"Lorem ipsum dolor sit, amet consectetur adipisicing elit. Aliquam tempora illum magni minima dolor id sequi quibusdam omnis."
},
{
_uid: "BUY6Drn9e1",
Icon: faCar,
head: "Free and Fast",
text:
"Lorem ipsum dolor sit, amet consectetur adipisicing elit. Aliquam tempora illum magni minima dolor id sequi quibusdam omnis."
}
];
Access it when iterating as you have done for the text
...
<FontAwesomeIcon
icon={Card.Icon}
className="pic"
style={{ fontSize: 25, color: "#66b2e9" }}
/>
...

how to add dynamically multiple posts with jsonplaceholder

help me please, I display the html markup of 6 posts, the first click works correctly, the second click I display the same posts. how should I add six new posts, and so every time I click?
I don't know what can be used instead of the slice method. demo https://jsfiddle.net/u9zc7p5v/13/
const content = mrd.map(function(data, elem) {
return `
<div class="blog__item">
<h2 class="blog__item-title">
${data.title}
</h2>
<input type="checkbox" class="read-more-state" id="post-${elem}" />
<p class="blog__item-text">
${data.body} <span class="blog__item-more">Lorem ipsum dolor sit amet consectetur adipisicing elit. Autem itaque ducimus unde harum vitae quam provident. Lorem ipsum dolor sit amet consectetur adipisicing elit. Dicta sapiente odit laborum tempore sed quaerat a aliquam? Corrupti dolorum, tempora iste qui modi consectetur explicabo quia vel reiciendis nesciunt? Id!</span>
</p>
<label for="post-${elem}" class="blog__item-toggle" >Read More</label>
<div>${elem}</div>
</div>
`
}).slice(startNum, endNum).join('');
Increase the startNum value startNum+=6. then in slice function do startNum + endNum.
$(function(){
const blogs = document.querySelector('.blog__items')
const moreBtn = document.querySelector('.blog-btn')
let startNum = 0;
let endNum = 6;
async function getContent() {
let responce = await fetch('https://jsonplaceholder.typicode.com/posts');
let data = await responce.json();
return data;
}
$(moreBtn).on('click', async function(e) {
let mrd = await getContent();
console.log(mrd.length)
const content = mrd.map(function(data, elem) {
return `
<div class="blog__item">
<h2 class="blog__item-title">
${data.title}
</h2>
<p class="blog__item-text">
${data.body} <span class="blog__item-more">Lorem ipsum dolor sit amet consectetur adipisicing elit. Autem itaque ducimus unde harum vitae quam provident. Lorem ipsum dolor sit amet consectetur adipisicing elit. Dicta sapiente odit laborum tempore sed quaerat a aliquam? Corrupti dolorum, tempora iste qui modi consectetur explicabo quia vel reiciendis nesciunt? Id!</span>
</p>
<label class="blog__item-toggle" >Read More</label>
<div>${elem}</div>
</div>
`
}).slice(startNum, startNum+endNum).join('');
console.log(startNum)
const el = $(content);
$(blogs).append(el)
el.on('click', function() {
});
startNum+= 6
});
});

Resources