Display data dynamically from component using javascript in astro.js - javascript

Astro.js & Javascript
Inside of a component i'm trying to map over some data one time and display different data from each rendered component in another file.
The component responsible for mapping the data
---
const skills = [
{
name: 'Frontend',
id: 1,
frontend: [ 'HTML', 'CSS' ]
},
{
name: 'Backend',
id: 2,
backend: [ 'Firebase', 'PHP' ]
}
]
---
{skills.map(skill => (
<li>
<h4 class="role me-2 astro-FP6HE37A"> {skill}
<span class="invert position-absolute d-flex align-items-center justify-content-center h-100 w-100 astro-FP6HE37A"> {skill}</span>
</h4>
</li>
))}
The file responsible for displaying the said component
---
import SkillsIcon from '../components/SkillsIcon.astro';
---
<h3>Frontend</h3>
<SkillsIcon />
<h3>Backend</h3>
<SkillsIcon />

you can place everything in one component like this, note renaming generic field as 'tags' not to create a dependency of the array elements to their own content
---
const skills = [
{
name: 'Frontend',
id: 1,
tags: [ 'HTML', 'CSS' ]
},
{
name: 'Backend',
id: 2,
tags: [ 'Firebase', 'PHP' ]
}
]
---
{skills.map(skill => (
<h3>{skill.name}</h3>
<ul>
{skill.tags.map(tag => (
<li>
<h4 class="role ... ">
<span class="invert ...">{tag}</span>
</h4>
</li>
))
}
</ul>
))}
If it is important to have two separate components, you can place your data on an external JSON file and import it in both components and pass as argument to the child component the array index you want to map in the component, like this
{skills.map((skill,index) => (
<h3>{skill.name}</h3>
<SkillIcon index={index} />
))}
reference for json import in astro https://docs.astro.build/en/guides/imports/#json

Related

How to declare file-path in Javascript for object mapping?

I am working on a personal react project for learning and considering to mapping data from a JavaScript object file (not JSON in this case). There are many ways to do it. This method of works for me
import product1 from "../../assets/images/products/product1.jpeg";
<img src={ product1 } alt="item_image" />
But I want to do it differently. I want retrieve data from a JavaScript object file (not JSON) using mapping. My data.js file contains data like this-
const data = [
{
id: 1,
title: "Meat",
price: €2.5,
category: "Grocery",
path: "../../assets/images/products/product1.jpeg",
},
{
id: 2,
title: "Milk",
price: €1.25,
category: "Drink",
path: "../../assets/images/products/product2.jpeg",
}
]
export function getData () {
return data;
}
and mapping data in this way
import { getData } from "./data";
function Product () {
const product = getData();
return (
<>
{
product.map((item) => (
<div>
<div>
<div>
<div>
<span> { item.title } </span>
</div>
<div>
<span> { item.price } </span>
</div>
</div>
<div>
<img src={ item.path } alt="item-img" />
</div>
<div>
<div>
<span> { item.category } </span>
</div>
</div>
</div>
</div>
))
}
</>
);
}
export default Product;
But I failed to get the image from this. After looking on internet, I tried to declare the path property using this method path: "file:///home/user/Documents/testapp/src/assets/images/products/product1.jpeg"
Unfortunately this method also failed to get the product image. I am expecting a better solution from the community. --Thanks.

When I use React Images won't display when i store the URL in an object

I have just started working with react recently but I have been running into an issue with the project that I am working on where I'm trying to display a list of icons with links.
when storing the src for each icon in the list below it stops the entire page from rendering, and logs an error that it can't find the image. If I paste the scr directly into the code there is no error when loading the images, but for reusability and readability, I thought it would be best practice to map a list into HTML components instead.
import SideLinksCss from './sideLinks.module.css';
export default function SideLinks() {
const links = [
{
name: "linkedin",
url: "",
src: "../assets/linkedin-icon.png"
},
{
name: "github",
url: "",
src: "../assets/github-icon.png"
},
]
return (
<div className="side-links">
<ul>
{links.map(link =>
<li>
<a>
<img src={link.src} alt={link.name} />
</a>
</li>
)}
</ul>
</div>
);
}
if there is something dumb I'm missing id love to hear since I'm new to react, or if there is a better way to do it.
You do not need to import or require the images. Just put them in the public folder and they will be available. Then you can do:
function App() {
const links = [
{
alt: "fig1",
src: "./0001.jpg",
},
{
alt: "fig2",
src: "./0002.jpg",
},
];
return (
<div className="App">
<ul>
{links.map((link) => (
<li key={link.alt}>
<a>
<img src={link.src} alt={link.alt} />
</a>
</li>
))}
</ul>
</div>
);
}
export default App;
Because the images aren't imported at the top of the file it is required that you use require() inside the list of links and not inside the mapping function. If you change the code to
import SideLinksCss from './sideLinks.module.css';
export default function SideLinks() {
const links = [
{
name: "linkedin",
url: "",
src: require("../assets/linkedin-icon.png")
},
{
name: "github",
url: "",
src: require("../assets/github-icon.png")
},
]
return (
<div className="side-links">
<ul>
{links.map(link =>
<li key = {link.name}>
<a>
<img src={link.src} alt={link.name} />
</a>
</li>
)}
</ul>
</div>
);
}
it will correctly display the images

How to map dictionary in react class component

Hello, community! Hope you all are good.
I was trying to map a dictionary in my class component but it gives me a hooks error.
I wanted to create several cards with different information so that I approached like this but now it shows me the Hooks error and I tried many things and find out that this piece of code has an error but can't figure out what please help me.
My code is below
export class AskModal extends Component {
constructor(props) {
super(props);
this.state = {
modalState: true,
services: {
"Employement": [
"/employement",
"/images/humhai-static-data/employment.jpg",
"This para is for Employement",
"text-dark"
],
"Business opportunity": [
"/self-employement",
"/images/humhai-static-data/buisness-opportunity.jpg",
"This para is for Self Employement",
"text-dark"
],
"Covid Helpdesk": [
"../covid-helpline",
"/images/humhai-static-data/covid-helpdesk.jpg",
"This para is for Covid help desk",
"text-danger"
],
"Volunteer": [
"../covid-helpline/volunteer",
"/images/humhai-static-data/volunteer.jpg",
"This para is for Volunteer",
"text-dark"
],
},
};
this.toggle = this.toggle.bind(this);
}
toggle = () => {
this.setState({
modalState: !this.state.modalState
});
}
render() {
return (
<>
{Object.keys(this.state.services).map(name => (
<MDBCol md="3" size="6" className="mx-auto my-2">
<MDBCard className="border rounded h-100 z-depth-5" color={this.state.services[name][3]}>
<Link to={this.state.services[name][0]} onClick={this.toggle} className={this.state.services[name][3]}>
<MDBCardImage className="img-fluid" src={this.state.services[name][1]} />
<MDBCardBody>
<MDBCardTitle><i className="fa fa-chevron-right"></i> {name}</MDBCardTitle>
<div className="d-none d-lg-block">
<hr />
<MDBCardText>
<p>{this.state.services[name][2]}</p>
</MDBCardText>
</div>
</MDBCardBody>
</Link>
</MDBCard>
</MDBCol>
))
}
</>
);
}
}
I think the error is because you are doing a map on this.state.services and it ideally shouldn't even be related to hooks as you are not using them here in this component.
If you check your state object, this.state.services would return an object and not an array. So, if you could revisit your code and check the same.
Also, the way you have created the services object might not be the best way, just putting a snippet below if it helps as to how you can make it more scalabale.
const services = [
{ name: "Employment", route: "/employment", image: "path/to/image.jpg", text: "Text", mode: "dark mode" }, // and so on
]

How to iterate through JSON data and dynamically create and populate components in React?

I'm new to React and JSX and have created a component which displays a title and image which will serve all as a link. I would now like to set the title and image by iterating through JSON data (currently my JSON is accessible via a locally defined variable).
I would like to know how to dynamically create and populate the components with the appropriate data. My code currently looks like this:
<script>
var RecipeList = React.createClass({
const items = [
{
id: 2234567,
title: "Fried Chicken",
image-url: "https://images.media-allrecipes.com/userphotos/560x315/4577069.jpg",
ingredient: ["Chicken", "Flour", "Eggs", "Salt", "Pepper"]
},
{
id: 2234567,
title: "Grilled Chicken",
image-url: "https://images.media-allrecipes.com/userphotos/560x315/4577069.jpg",
ingredient: ["Chicken", "Olive oil", "Salt", "Pepper"]
}
]
getDefaultProps: function() {
return {items: []}
},
render: function() {
var listItems = this.props.items.map(function(item) {
return(
<div className="container-fluid">
<div className="row">
<div className="recipeContainer col-sm-12 col-md-6 col-lg-4">
<h3 className="recipeTitle">{this.props.title}</h3>
<div className="recipeImage">
<img src="{this.props.image}" />
</div>
<div className="recipeBtn">See recipe</div>
</div>
</div>
</div>
);
});
return (
{listItems}
);
}
});
ReactDOM.render(
<div>
<IngredientList></IngredientList>
<RecipeList items={items}></RecipeList>
<RecipeSection></RecipeSection>
</div>
, document.getElementById("module"));
</script>
This can be achieved by passing the JSON data into the items prop of your <RecipeList /> so that this data is used to dynamically render the component via that data.
Additionally, there are a few other things to update to get this to work:
you'll want to fix the format of your input JSON so that item keys are either wrapped with quotes, or don't have hyphens.
ensure you're accessing data from the item in map() when rendering the list items, rather than accessing the item data from this
wrap the list items that you're rendering with a "root element" at the return line of your render() method. A simple solution is to usually wrap the return result with a <div>, however with more recent versions of React you can use <React.Fragment> (this allows you to return multiple elements in a render() result, without adding the extra "div element" to be resulting DOM).
Here's a working snippet:
<div id="module"></div>
<script src="https://unpkg.com/react#16/umd/react.production.min.js" crossorigin></script>
<script src="https://unpkg.com/react-dom#16/umd/react-dom.production.min.js" crossorigin></script>
<script type="text/babel">
/*
Use class to define component using React16
*/
class RecipeList extends React.Component {
render() {
var listItems = this.props.items.map(function(item) {
return(
<div className="container-fluid">
<div className="row">
<div className="recipeContainer col-sm-12 col-md-6 col-lg-4">
<h3 className="recipeTitle">{item.title}</h3> { /* <-- Corrected this to use item.title */ }
<div className="recipeImage">
<img src={item.image} /> { /* <-- Corrected this to use item.image */ }
</div>
<div className="recipeBtn">See recipe</div>
</div>
</div>
</div>
);
});
/*
When rendering multiple DOM elements as a list, you
must wrap these with React.Fragment, or something else
like a div
*/
return (<React.Fragment>{listItems}</React.Fragment>);
}
};
/*
Declare items data array which will passed to the items
prop of the <RecipeList> component
*/
const items = [{
'id': 2234567,
'title': "Fried Chicken",
'image': "https://images.media-allrecipes.com/userphotos/560x315/4577069.jpg",
'ingredient': ['Chicken', 'Olive oil', 'Salt', 'Pepper']
},
{
'id': 2234567,
'title': "Grilled Chicken",
'image': "https://images.media-allrecipes.com/userphotos/560x315/4577069.jpg",
'ingredient': ['Chicken', 'Olive oil', 'Salt', 'Pepper']
}];
ReactDOM.render(
<div>
{ /* Pass the items data array to the items prop */ }
<RecipeList items={items}></RecipeList>
</div>,
document.getElementById("module"));
</script>
Hope that helps!

Switcher of languages on Vue.js

On my site there is a language switch, it works all by standards, in the template comes arrays of languages:
$headerBar = [
'langs' => [
[
'name' => 'Українська',
'img' => 'images/flags/ua.png',
'code' => 'ua',
'active' => true,
],
[
'name' => 'Русский',
'img' => 'images/flags/ru.png',
'code' => 'ru',
'active' => false,
],
[
'name' => 'English',
'img' => 'images/flags/uk.png',
'code' => 'uk',
'active' => false,
]
]
];
Language output template:
<template slot="language-bar">
<language-switcher v-bind:langs='{!! json_encode($langs) !!}'></language-switcher>
</template>
And the component vue.js itself:
<template>
<div class="lang-currency-switcher-wrap" :class="{ show: isVisible }">
<div class="lang-currency-switcher dropdown-toggle" #click="isVisible = true">
<span class="language">
<img :alt="activeLang.name" :src="activeLang.img"></span>
<span class="currency">{{ activeLang.code }}</span>
</div>
<div class="dropdown-menu">
<a v-for="lang in langs" v-if="!lang.active" class="dropdown-item">
<img :src="lang.img" alt="">{{ lang.name }}
</a>
</div>
</div>
</div>
</template>
<script>
export default {
props: ['langs'],
data() {
return {
isVisible: false
};
},
computed: {
activeLang() {
let activeLang = [];
for (let lang of this.langs) {
if (lang.active) {
activeLang = lang;
}
}
return activeLang;
}
},
mounted() {
}
}
</script>
It works like this: The server renders an array of languages ​​with clever calculations, one of which is active, it all comes to the blade template and the vue.js component is already called
The component vue.js in its turn outputs an available list of languages ​​except active, and the active calculates and displays for the user.
When the user clicks on the language wrapper, then vue displays the entire available list.
Now the question is:
How correctly to hide all languages, in that cases, if the user clicked on any of the areas of the site, except the most wrapper languages?
Also interesting is the criticism, perhaps it could have been done differently, in a more beautiful way :)
Thank you.

Categories