React object rendering to fontawesome - reactjs

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" }}
/>
...

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);
}
}

how to dynamically fetch data in react while deploying?

Here's the thing, it all works fine if I run it with the npm run dev script, but images in testimonials.avatar don't render with npm run build.
const Testimonials = ({ testimonials }) => {
return (
<div id='testimonials' className='mt-20'>
<div className='text-center mb-8'>
<p className='text-xs uppercase mb-4 md:text-base'>Testimonials</p>
<h1 className='text-3xl md:text-5xl font-bold capitalize mb-10'>Read What Other<br />have to Say</h1>
</div>
<div className='flex flex-col gap-4 items-center md:flex-row'>
{testimonials.map(item =>
<div className='bg-light-gray rounded-3xl p-8 transition-transform duration-300 hover:-translate-y-2'>
<div className='w-32 h-32 mx-auto mb-4'>
<img src={item.avatar} alt="Person's avatar" className='rounded-full border' />
</div>
<p className='font-bold text-center'>{item.fullName}</p>
<p className='text-center mt-6'>{item.feedback}</p>
</div>
)}
</div>
</div>
)
}
Here I have a component which receives an array testimonials through props and then renders them in a div.
This is the array in App.jsx file.
const testimonials = [
{
avatar: '../src/images/avatars/avatar-1.png',
fullName: 'Andrew Rathore',
feedback: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc ullamcorper scelerisque mi, in malesuada felis malesuada vel. '
},
{
avatar: '../src/images/avatars/avatar-2.png',
fullName: 'Vera Duncan',
feedback: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc ullamcorper scelerisque mi, in malesuada felis malesuada vel. '
},
{
avatar: '../src/images/avatars/avatar-3.png',
fullName: 'Mark Smith',
feedback: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc ullamcorper scelerisque mi, in malesuada felis malesuada vel. '
}
];
I guess I know that the main reason why it does not work while deploying is because of a non-existent path since I will no longer have src/images/avatar during a deploy.
I also guess this is a dumb question because I am quite new to React and JavaScript in general, but would appreciate any answer regarding the problem.
You have to wrap the avatar path in require() like require('../src/images/avatars/avatar-1.png') I hope this works. thanks
Fixed this by creating an external file and then fetching it to the component like so.
data.js
import avatar1 from '../public/images/avatars/avatar-1.png';
import avatar2 from '../public/images/avatars/avatar-2.png';
import avatar3 from '../public/images/avatars/avatar-3.png';
export const testimonials = [
{
authorImg: avatar1,
authorName: 'Andrew Rathore',
authorText: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc ullamcorper scelerisque mi, in malesuada felis malesuada vel.'
},
{
authorImg: avatar2,
authorName: 'Vera Duncan',
authorText: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc ullamcorper scelerisque mi, in malesuada felis malesuada vel.'
},
{
authorImg: avatar3,
authorName: 'Mark Smith',
authorText: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc ullamcorper scelerisque mi, in malesuada felis malesuada vel.'
}
];
Testimonials.jsx
import React from 'react';
import { testimonials } from '../data/data';
const Testimonials = () => {
return (
<div className='flex flex-col gap-4 justify-between items-center md:flex-row'>
{testimonials.map((testimonial, index) =>
<div key={index} className='bg-light-gray rounded-3xl p-8 transition-transform duration-300 hover:-translate-y-2'>
<div className='w-32 h-32 mx-auto mb-4'>
<img src={testimonial.authorImg} alt="Person's avatar" className='rounded-full border' />
</div>
<p className='font-bold text-center'>{testimonial.authorName}</p>
<p className='text-center mt-6'>{testimonial.authorText}</p>
</div>
)}
</div>
)
}
export default Testimonials;
The main reason why it didn't work well in the first place was the fact that I specified path to the images in the object itself like so:
{
key: '../../../value.png'
}
That is why I ran into as error every time while deploying, 'cause it simply couldn't find that path due to its non-existence.

Props not rendering for storybook component

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";

Problem fetching data in react using getStaticProps

I'm currently trying to fetch some data in my Next.js project using the getStaticProps() function and I continue to get this error:
TypeError: Cannot read property 'map' of undefined
My code looks like this:
export const getStaticProps = async () => {
const data = [
{
"id": 1,
"question": "Lorem ipsum dolor sit amet consectetur adipisicing elit.",
"answer": "Lorem ipsum dolor sit amet consectetur adipisicing elit. Iste magni at magnam placeat. Non, saepe?"
},
{
"id": 2,
"question": "Lorem ipsum dolor sit amet consectetur adipisicing elit.",
"answer": "Lorem ipsum dolor sit amet consectetur adipisicing elit. Iste magni at magnam placeat. Non, saepe?"
}
]
return {
props: {
questions: data
}
}
}
export default function FAQ({ questions }) {
return (
<div className="p-8 grid bg-blanco" >
<div className="grid place-content-center text-center mt-10 md:mt-0" >
<h1 className="text-2xl text-gun-rose-700 font-bold" >¿Tiene preguntas? Mira aquí</h1>
<h3 className="text-gun-rose-300 mt-4 max-w-2xl" >Lorem ipsum dolor sit amet consectetur adipisicing elit. Sunt, suscipit. Aliquid molestias eveniet ullam? Dolores, minus? Perspiciatis neque voluptates iste!</h3>
</div>
{questions.map(q => (
<div className="" key={q.id}>
<h3 className="">{q.question}</h3>
<p className="">{q.answer}</p>
</div>
))}
</div>
)
}
Any guidence will be appreciated, thanks in advance :)
It could be an async issue where questions is not immediately available. Try with a null check at the start of questions.
export default function FAQ({ questions }) {
return (
<div className="p-8 grid bg-blanco" >
<div className="grid place-content-center text-center mt-10 md:mt-0" >
<h1 className="text-2xl text-gun-rose-700 font-bold" >¿Tiene preguntas? Mira aquí</h1>
<h3 className="text-gun-rose-300 mt-4 max-w-2xl" >Lorem ipsum dolor sit amet consectetur adipisicing elit. Sunt, suscipit. Aliquid molestias eveniet ullam? Dolores, minus? Perspiciatis neque voluptates iste!</h3>
</div>
{questions && questions.map(q => (
<div className="" key={q.id}>
<h3 className="">{q.question}</h3>
<p className="">{q.answer}</p>
</div>
))}
</div>
)
}
Edit 1:
The getStaticProps method can only be used on the top level component of a page as stated in the caveats
The fix is to move the getStaticProps method to the top level page component. I've demo'ed this in a sandbox as folder structures are so important, link here.

Selecting an 'object' logic

I have done this before but I can't for the life of me remember how. I want a user to be able to select a product by clicking a button in an <li> then have that passed to an array. As well as that, the <li> needs to have a class 'active' once that item is in the selected array:
<li class="row" data-ng-repeat="product in products">
<div class="col-lg-9">
<h3>{{product.name}}</h3>
<p>{{product.description}}</p>
</div>
<div class="col-lg-3">
<button class="btn btn-primary" data-ng-click="selectProduct(product.id)">Select Product</button>
</div>
</li>
is the HTML and this is the controller:
app.controller("MainController", function($scope, $http) {
$scope.selected_products = []
$scope.products = [
{
name: 'Example product',
description: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Id, assumenda, dolor, ipsa, atque obcaecati tempora perspiciatis earum vitae amet cum nostrum blanditiis ducimus culpa molestiae temporibus porro debitis voluptatibus libero.',
category: 'VT'
},
{
name: 'Example product 2',
description: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Id, assumenda, dolor, ipsa, atque obcaecati tempora perspiciatis earum vitae amet cum nostrum blanditiis ducimus culpa molestiae temporibus porro debitis voluptatibus libero.',
category: 'VT'
}
]
$scope.selectProduct = function(name) {
console.log(name)
}
})
Does anyone have any pointers as to how to do this?
Here you are:
$scope.isSelected = function(product){
return this.selected_products.indexOf(product)>-1;
}
$scope.selectProduct = function(product) {
if(!this.isSelected(product)){
this.selected_products.push(product);
}
}
Use it like:
<button ng-disabled="isSelected(product)" data-ng-click="selectProduct(product)">Select Product</button>
Working example: http://plnkr.co/edit/sPAN36?p=preview

Resources