React 18.2.0-style property not rendering image - reactjs

I am currently working through the ZTM React course version 18.2.0 in Udemy. For whatever reason, posting questions has been disabled on Udemy website so I am posting here. The following code renders fine when I run it-all except for the images. The image url is valid when put into a browser. There are no other errors whatsoever. The only issue is that the image is not showing.
import "./categories.styles.scss"
//import CategoryItem from "./components/category-item/category-item.component";
const App = () => {
const categories = [
{
"id": 1,
"title": "hats",
"imageUrl": "https://i.ibb.co/cvpntL1/hats.png"
},
{
"id": 2,
"title": "jackets",
"imageUrl": "https://i.ibb.co/px2tCc3/jackets.png"
},
{
"id": 3,
"title": "sneakers",
"imageUrl": "https://i.ibb.co/0jqHpnp/sneakers.png"
},
{
"id": 4,
"title": "womens",
"imageUrl": "https://i.ibb.co/GCCdy8t/womens.png"
},
{
"id": 5,
"title": "mens",
"imageUrl": "https://i.ibb.co/R70vBrQ/men.png"
}
];
return (
<div className="categories-container">
{categories.map(({title,id,imageUrl}) => (
<div key={id} className="category-container">
<div
className='background-image'
style={{
backgroundImage: `url(${imageUrl})`
}}>
</div>
<div className='category-body-container'>
<h2>{title}</h2>
<p>Shop Now</p>
</div>
</div>
))}
</div>
);
};
export default App;

Your categories should be an array of objects like this
const categories = [
{
id: 1,
title: 'hats',
imageUrl: 'https://i.ibb.co/cvpntL1/hats.png',
},
{
id: 2,
title: 'jackets',
imageUrl: 'https://i.ibb.co/px2tCc3/jackets.png',
},
{
id: 3,
title: 'sneakers',
imageUrl: 'https://i.ibb.co/0jqHpnp/sneakers.png',
},
{
id: 4,
title: 'womens',
imageUrl: 'https://i.ibb.co/GCCdy8t/womens.png',
},
{
id: 5,
title: 'mens',
imageUrl: 'https://i.ibb.co/R70vBrQ/men.png',
},
];
Your example of categories above is json-like

Also, the links are not working. Try download the images locally

Related

Mapping an array inside an object inside an array

I am having trouble displaying a pair of options for the corresponding prompt.
I made a .json file to hold the prompts and options.
This is the dataset:
[
{
"id": 1,
"text": "hey wut r u doin",
"options": [
{
"id": 1,
"text": "Playing Pokemon",
"nextPrompt": 2
},
{
"id": 2,
"text": "Watching a movie",
"nextPrompt": 7
}
]
},
{
"id": 2,
"text": "lol you still play that??",
"options": [
{
"id": 1,
"text": "It's fun!",
"nextPrompt": 18
}
{
"id": 2,
"text": "Just kidding ha ha...",
"nextPrompt": 7
}
}]
In the component I'm trying to go to the currentPrompt, look at the options and then from there map the text. When I console.log(currentPrompt.options) it says undefined... Why is that?
This is my component:
function PromptsAndOptions() {
const [currentPrompt, setCurrentPrompt] = useState(POA[0].text);
return (
<section>
<section>{currentPrompt}</section>
{console.log(currentPrompt)}
<section>
{currentPrompt.options &&
currentPrompt.options.map(({ text }) => (
<button key={currentPrompt.options.id}>{text}</button>
))}
</section>
</section>
);
}
I think your JSON file is wrong
Try the CodeSandBox
const POA = [
{
id: 1,
text: "hey wut r u doin",
options: [
{
id: 1,
text: "Playing Pokemon",
nextPrompt: 2
},
{
id: 2,
text: "Watching a movie",
nextPrompt: 7
}
]
},
{
id: 2,
text: "lol you still play that??",
options: [
{
id: 1,
text: "It's fun!",
nextPrompt: 18
},
{
id: 2,
text: "Just kidding ha ha...",
nextPrompt: 7
}
]
}];
const [id, setId] = useState(1);
const promp = POA[id].options;
return (
<section>
<section>{id}</section>
{console.log(id)}
<section>
{promp &&
promp.map((item, i) => {
return (
<>
<div key={i}>Items Text Is === {item.text}</div>
<br />
</>
);
})}
<div onChange={(e) => setId(e.target.value)}>
<input type="radio" value="0" name="gender" /> First
<input type="radio" value="1" name="gender" /> Second
</div>
</section>
</section>);

.map is not a function with MaterialUI Tab component

So I'm trying to populate a in-memory MirageJS' database with a post request of the data in useEffect, making a get request after. Then I save the result to columnsNames state and use it to map this array and read the information as a label of Tab MaterialUI component. However, I have some questions:
When I put a console.log after useEffect or inside get request, both response.data and columnsNames state have 2 identical arrays. Why 2 and not 1?
At runtime the console prints
Uncaught TypeError: columnsNames.map is not a function
The above error occurred in the <ScrollableTabsButtonAuto> component
and nothing is showed in the screen. Why?
Anyone that could help me, thanks in advance!
Data.ts
export const data = [
{
"id": 1,
"title": "Test 1",
"steps": [
"Read a starting book",
"Keep calm and drink coffee",
"Don't Panic so much",
]
},
{
"id": 2,
"title": "Test 2",
"steps": [
"Get some helpful help",
"Don't loose yourself",
]
},
{
"id": 3,
"title": "Test 3",
"steps": [
]
},
{
"id": 4,
"title": "Test 4",
"steps": [
]
},
{
"id": 5,
"title": "Test 5",
"steps": [
]
},
{
"id": 6,
"title": "Test 6",
"steps": [
]
}
]
App.tsx
import { createServer, Model } from 'miragejs';
createServer({
models: {
columns: Model,
},
routes() {
this.namespace = 'api'
this.get('columns', () => {
return this.schema.all('columns')
})
this.post('columns', (schema, request) => {
const data = JSON.parse(request.requestBody)
return schema.create('columns', data)
})
}
})
const root = ReactDOM.createRoot(
document.getElementById('root') as HTMLElement
);
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
Tab.tsx
interface ColumnTypes {
id: number,
title: string,
steps: string[]
}
export default function ScrollableTabsButtonAuto() {
const [value, setValue] = React.useState(0);
const [columnsNames, setColumnsNames] = React.useState<ColumnTypes[]>([])
const handleChange = (event: React.SyntheticEvent, newValue: number) => {
setValue(newValue);
};
React.useEffect(() => {
api.post('columns', data)
.then( () => {
api.get<ColumnTypes[]>('columns')
.then(response => setColumnsNames(response.data))
})
}, [])
return (
<Box sx={{ maxWidth: { xs: 320, sm: 1280 }, bgcolor: 'background.paper' }}>
<Tabs
value={value}
onChange={handleChange}
variant="scrollable"
scrollButtons="auto"
aria-label="scrollable auto tabs example"
>
{columnsNames.map(({ id, title }) => (
<Tab
label={title}
key={id}
/>)
)}
</Tabs>
</Box>
);
}

React: How to render a list of items grouped by category (using .map)

I have an array (myArray), stored like so (in firebase):
[
{
"id": "1",
"Category": "Hardware",
"Name": "Xtreme"
},
{
"id": "123",
"Category": "Software",
"Name": "Obsolete"
},
{
"id": "12345",
"Category": "Software",
"Name": "V1"
},
{
"id": "1234567",
"Category": "Hardware",
"Name": "CPU"
}
]
I am using the following code:
const sorterAR = [];
myArray.forEach((item) => {
let cat = sorterAR.find(
(cat) => cat.id === item.id
);
if (!cat) {
cat = {
id: item.id,
Category: item.Category,
items: [],
};
sorterAR.push(cat);
}
cat.items.push(item);
});
And then displaying like so:
<div className="App">
{sorterAR.map((cat) => (
<>
<div>
<b>{cat.Category}</b>
</div>
<ul>
{cat.items.map((item) => (
<li>{item.Name}</li>
))}
</ul>
</>
))}
</div>
This works in that it produces an output like:
**Hardware**
Xtreme
**Hardware**
CPU
**Software**
Obsolete
**Software**
V1
How do I alter this to produce the following output:
**Hardware**
Xtreme
CPU
**Software**
Obsolete
V1
So that it displays the category name and then all the items in that category, and then moves to the next one and so forth?
I assumed that order doesn't matter if Hardware or Software should come first.
First I categorized the array into an object of Category objects using Array.prototype.reduce().
From the resultant object you can build the JSX
var data1 = [
{
id: '1',
Category: 'Hardware',
Name: 'Xtreme',
},
{
id: '123',
Category: 'Software',
Name: 'Obsolete',
},
{
id: '12345',
Category: 'Software',
Name: 'V1',
},
{
id: '1234567',
Category: 'Hardware',
Name: 'CPU',
},
];
const categorizedData = data1.reduce((acc, curr) => {
const { id, Category, Name } = curr;
if (!acc[Category]) {
acc[Category] = {
items: [],
};
}
acc[Category].items.push(Name);
return acc;
}, {});
console.log(categorizedData);
Object.keys(categorizedData).map((key, index) => {
console.log(`Category: ${key}`);
categorizedData[key].items.map((item, index) =>
console.log(`Item ${index}: ${item}`)
);
});

How to search and filter in array of objects on setState

I'm trying to create a search based on an array of objects with react which data is in this format:
const data = [
{"category 1" : [
{
"name": "Orange",
"desc": "juice, orange, Water"
},
{
"name": "Ananas",
"desc": "juice, ananas, water"
}
]
},
{"category 2" : [
{
"name": "Banana Split",
"desc": "Banana, ice cream, chocolat, topping",
"allergens": "nuts"
},
{
"name": "Mango Sticky Rice",
"desc": "Mango, rice, milk",
"allergens": ""
}
]
}
]
I stored this data inside useState declaration to be able to render accordingly on data chnage:
const [filteredBySearch, setFilteredBySearch] = useState(data)
I have an input where we can type anything and set inside useState declaration.
Goal:
If I type in my input:
"Jui"
Output should be:
console.log(filteredBySearch)
/* output:
[
{"category 1" : [
{
"name": "Orange",
"desc": "juice, orange, Water"
},
{
"name": "Ananas",
"desc": "juice, ananas, water"
}
]
},
{"category 2" : []
}
]*/
Exemple 2:
If I type in my input:
"Orange banana"
Output should be:
console.log(filteredBySearch)
/* output: [
{"category 1" : [
{
"name": "Orange",
"desc": "juice, orange, Water"
}
]
},
{"category 2" : [
{
"name": "Banana Split",
"desc": "Banana, ice cream, chocolat, topping",
"allergens": "nuts"
}
]
}
]*/
I've try creating a new object with map and filter and set it with setFilteredBySearch, but I can't get anything, even creating this new object.
This the full component:
import Card from '../components/Card'
import React, { useState } from 'react';
export default function IndexPage({ data, search }) {
//search is the result of input value set on a useState
//Filter categoriesFoods by search
const [FilteredBySearch, setFilteredBySearch] = useState(data)
return (
<div className="main-content">
<div className="card-container">
{
FilteredBySearch.map(function(el, i) {
return (
<div key={i}>
<h2 className="category" id={Object.keys(el)}>{Object.keys(el)}</h2>
{
el[Object.keys(el)].map (function(itm,index){
return <Card key={index} infoItem={itm}/>
})
}
</div>
)
})
}
</div>
<style jsx>{`...`}</style>
</div>
)}
Any idea for me ?
Thanks a lot for your guidance!
I think this is what you are looking for. I have created below utilities for filtering as per your requirement.
const dataObj = [
{
'category 1': [
{
name: 'Orange',
desc: 'juice, orange, Water',
},
{
name: 'Ananas',
desc: 'juice, ananas, water',
},
],
},
{
'category 2': [
{
name: 'Banana Split',
desc: 'Banana, ice cream, chocolat, topping',
allergens: 'nuts',
},
{
name: 'Mango Sticky Rice',
desc: 'Mango, rice, milk',
allergens: '',
},
],
},
]
const checkIfInputMatches = (input, desc) => input.toLowerCase().split(" ").some(o => desc.toLowerCase().includes(o))
const filterByInput = (data, input) => {
let finalResult = [];
data.forEach(d => {
let keys = Object.keys(d);
let values = Object.values(d);
finalResult = [...finalResult, ...values.map((obj, index) => {
let result = obj.filter(o => checkIfInputMatches(input, o.desc))
return {[keys[index]]: result}
})]
})
return finalResult
}
console.log(filterByInput(dataObj, 'JUI'))
console.log(filterByInput(dataObj, "orange"))
console.log(filterByInput(dataObj, "rice"))
console.log(filterByInput(dataObj, "Orange banana"))
Hope this helps.

React react-icons-kit and get Icons dynamically

How to get Icons dynamically in React using extension React Icon kit? I try to find out the way to add a icon dynamically in a MAP-loop as I get them from array "sociallinks"
here is the part of the code
....
import { Icon } from 'react-icons-kit'
import {facebook} from 'react-icons-kit/feather/facebook';
import {instagram} from 'react-icons-kit/feather/instagram';
import {twitter} from 'react-icons-kit/feather/twitter';
....
// dynamic array from redux store
"sociallinks": [
{
"_id": 1,
"type": "facebook",
"linkname": "Facebook",
"link": "https://www.facebook.com/zzzzz/"
},
{
"_id": 2,
"type": "instagram",
"linkname": "Instagram",
"link": "https://www.instagram.com/yyy/"
},
{
"_id": 3,
"type": "twitter",
"linkname": "Twitter",
"link": "https://twitter.com/xxx"
},
{
"_id": 4,
"type": "youtube",
"linkname": "Youtube",
"link": "https://www.youtube.com/user/youtube"
}
]
// problem is here how to markup icon = {xxxxx} from map item.type? item.link and item.linkname works fine.. but not item.type :(((
<ul>
{this.props.data.socialLinks.map((item,i) => (
<li key = {i}> <a href = {item.link}><Icon size={18} icon={item.type} />{item.linkname}</a></li>
))
}
</ul>

Resources