Reactjs map over redux store - reactjs

I am trying to map over the items i am receiving from my API and are in my store
this is how the data look like in the state:
{
vessels: {
vessels: [
{
id: 1,
component_count: 3,
inventory_item_count: 1,
name: 'Aylah',
imo: 'Aylah123',
image: 'http://127.0.0.1:8000/media/vessel_image/aylah.jpg'
},
{
id: 2,
component_count: 1,
inventory_item_count: 0,
name: 'Sinaa',
imo: 'sinaa123',
image: 'http://127.0.0.1:8000/media/vessel_image/DSCF9831.jpg'
},
{
id: 3,
component_count: 0,
inventory_item_count: 0,
name: 'Amman',
imo: 'amman123',
image: 'http://127.0.0.1:8000/media/vessel_image/amman.jpg'
},
{
id: 4,
component_count: 0,
inventory_item_count: 0,
name: 'Queen',
imo: 'Queen 123',
image: 'http://127.0.0.1:8000/media/vessel_image/1.jpg'
}
]
}
}
i am just trying to use the map function but i cant seem to get it work
here i am trying to print all the names of the vessels :
OverviewFleet.js:
import React, { useEffect } from "react";
import { useDispatch, useSelector } from "react-redux";
import { fetchVessels } from "../../../features/vesselSlice";
import VesselCard from "./VesselCard";
function OveriewFleet() {
const vessels = useSelector((state) => state.vessels);
const dispatch = useDispatch();
useEffect(() => {
fetchVessels()(dispatch);
}, [dispatch]);
return (
<div className="fleet-overview">
<div className="fleet-overview-container">
<span className="fleet-overview-heading-title">Fleet overview :</span>
<div className="fleet-overview-cards">
{vessels.map((vessel) => ({ vessel.name }))}
</div>
</div>
</div>
);
}
export default OveriewFleet;

Looks like you are having object inside vessels with name vessels.
try with vessels?.vessels?.map
{vessels?.vessels?.map((vessel) => ({ vessel.name }))}

Related

Is this an Array of Object BUG? Ionic v6 React

As the image shows, it only renders one array of objects.
How to reproduce:
Create a Blank Template and paste this code on ExploreContainer.tsx:
import {
IonCard,
IonCardHeader,
IonCardSubtitle,
IonCardTitle,
IonCardContent,
} from '#ionic/react'
import { useEffect, useState } from 'react'
import './ExploreContainer.css'
interface ContainerProps {}
interface TestArrayObject {
key: string
id: string
name: string
age: number
}
const ExploreContainer: React.FC<ContainerProps> = () => {
const [testArray, setTestArray] = useState<TestArrayObject[]>([])
const arraySample: TestArrayObject[] = [
{
key: '1',
id: '12345',
name: 'Jack',
age: 40,
},
{
key: '2',
id: '67890',
name: 'Black',
age: 30,
},
]
useEffect(() => {
arraySample.map((arr: TestArrayObject) => {
setTestArray([...testArray, arr])
})
}, [])
const listArray = testArray.map((arr) => {
return (
<IonCard>
<IonCardHeader>
<IonCardSubtitle>{arr.id}</IonCardSubtitle>
<IonCardTitle>{arr.name}</IonCardTitle>
</IonCardHeader>
<IonCardContent>
Keep close to Nature's heart... {arr.age}
</IonCardContent>
</IonCard>
)
})
return <>{ listArray }</>
}
export default ExploreContainer
I'm trying to figure out the solution, but happens that i`m more than 24hours trying to figure out and nothing. could someone help?

React/Firebase. How can i filter some products by categories using firebase?

How can i filter some products by categories using firebase? This is a fragment of my code
Not sure if you have a correct db.json file, i had to flatMap the result but here is a working code. I used require to load you json file and left const [products, setProducts] = useState([]); just in case. Also i switched categories to useMemo so this variable will not update on each re-render.
import React, { useState, useEffect, useMemo } from "react";
import "./styles.scss";
import { Link } from "react-router-dom";
const dbProducs = require("./db.json");
const CategoriesPage = () => {
// const {product} = useContext(Context)
const [products, setProducts] = useState([]);
const categories = useMemo(() => {
return [
{ id: 1, title: "Tablets" },
{ id: 2, title: "Computers" },
{ id: 3, title: "Consoles" },
{ id: 4, title: "Photo and video" },
{ id: 5, title: "Technics" },
{ id: 6, title: "Game Content" },
{ id: 7, title: "Notebooks" },
{ id: 8, title: "Smartphones" },
{ id: 9, title: "Headphones" },
{ id: 10, title: "Steam" }
// {id: 11,imageSrc:steamcards, title: 'Стиральные машины'},
// {id: 12,imageSrc: coffeemaschine, title: 'One stars'},
// {id: 13,imageSrc:headphones, title: 'Холодильники'},
];
}, []);
useEffect(() => {
const flatMapped = dbProducs.flatMap((x) => x.products);
setProducts(flatMapped);
}, []);
return (
<section className="popular__categories">
<h3 className="events__title">
<span>Categories</span>
</h3>
<div className="categories__wrapper">
{categories.map((category) => (
<Link
to={`${category.id}`}
className="categories__content"
key={category.id}
>
<h2 className="categories__title">{category.title}</h2>
<img
className="categories__img"
alt={category.title}
src={category.imageSrc}
/>
<ul>
{products
.filter((p) => p.category === category.title)
.map((p) => (
<li key={p.id}>{p.name}</li>
))}
</ul>
</Link>
))}
</div>
</section>
);
};
export default CategoriesPage;
Technically it would be better to clone and extend your categories objects with additional array property with useMemo, or you can add additional Map object with key = Category(title) and value = products (filtered) but it is up to you.
Full example with Context, Routes, Navigation:

NextJs nested dynamic routes based on API

I am stuck with Nextjs : I need to create nested dynamic routes based on my (local) data.
Here are the routes that I would like to create :
.../cars/ -> displays all the categories (sedan, suv, 4x4)
.../cars/category/ -> displays cars in the category
ex : .../cars/sedan -> displays cars in the sedan category
.../cars/category/id -> displays the details of the car from category which has id = 1
ex : .../cars/sedan/1 -> displays the details of the sedan car with id = 1
For routes 1 and 2 it's ok but I don't know how to do the last one. Can you help me please ?
data.js
export const cars = [
{
id: 1,
name: 'sedan',
models: [
{
id: 1,
name: 'model1',
image: '/sedan1.jpg',
},
{
id: 2,
name: 'model2',
image: '/sedan2.jpg',
},
{
id: 3,
name: 'model3',
image: '/sedan3.jpg',
},
],
},
{
id: 2,
name: 'suv',
models: [
{
id: 1,
name: 'model1',
image: '/suv1.jpg',
},
{
id: 2,
name: 'model2',
image: '/suv2.jpg',
},
{
id: 3,
name: 'model3',
image: '/suv3.jpg',
},
],
},
{
id: 3,
name: '4x4',
models: [
{
id: 1,
name: 'model1',
image: '/4x4_1.jpg',
},
{
id: 2,
name: 'model2',
image: '/4x4_2.jpg',
},
{
id: 3,
name: 'model3',
image: '/4x4_3.jpg',
},
],
},
];
/cars/index.js
import { cars } from '../../data';
import Link from 'next/link';
export default function Categories({ car }) {
return (
{car.map((c) => (
<Link key={c.id} href={`/cars/${c.name}`} passHref>
<div>{c.name}</div>
</Link>
))}
);
}
export const getStaticProps = async () => {
return {
props: {
car: cars,
},
};
};
/cars/[name].js
import React from 'react';
import { cars } from '../../data';
export default function CategoriesCars({ cars }) {
return (
<div>
{cars.models.map((m) => (
<p key={m.id}>{m.name}</p>
))}
</div>
);
}
export const getStaticPaths = async () => {
const paths = await cars.map((c) => ({
params: {
name: c.name,
},
}));
return { paths, fallback: false };
};
export const getStaticProps = async (context) => {
const { params } = context;
const response = await cars.filter((c) => c.name === params.name);
return {
props: {
cars: response[0],
},
};
};
The page folder must be:
pages/
cars/
[category]/
[id]/
index.jsx
index.jsx
then go /cars/sedan/2 you can access to category and id variables like this:
cars/[category]/[id]/index.jsx
import React from 'react';
import { useRouter } from 'next/router';
export default function Index() {
const router = useRouter();
// router.query.category -> sedan
// router.query.id -> 2
return <div>{JSON.stringify(router.query)}</div>;
}
// or
export const getServerSideProps = async (context) => {
const { params } = context;
console.log(params); // { category: 'sedan', id: '2' }
return {
props: {
cars: {},
},
};
};
// or if you wish use getStaticProps for SSG (with getStaticPaths)
export const getStaticPaths = async (context) => {
const paths = cars
.map((car) =>
car.models.map((model) => ({
params: {
id: model.id.toString(),
category: car.name,
},
}))
)
.flat(); // this is important
return { paths, fallback: false };
};
export const getStaticProps = async (context) => {
const { params } = context;
console.log(params);
return {
props: {
cars: {},
},
};
};
Example: StackBlitz

Can't load mock data while mounting component

I have a component that should render a list of mock items. The initial value is an empty array, and I want to load mock data during component render. But it doesn't work correctly - list in component is empty when I try to check it out by printing in console, but Redux Devtools shows that it is not. What am I doing wrong?
Component
import React, { Component } from 'react';
import TagsBlock from './TagsBlock';
import ActionButton from './ActionButton';
import { connect } from 'react-redux';
import { actionLoadCoctails, actionToggleDetail } from '../actions/actionCreators';
class ResultsCoctails extends Component {
componentDidMount() {
this.props.actionLoadCoctails();
}
list = this.props.loadCoctails.map(({ img, name, tags}, key) => {
const showDetail = (e) => {
e.preventDefault();
this.props.actionToggleDetail();
}
return (
<div
className="item"
key={`coctail-${key}`}
>
<a
href="#"
onClick={(e) => showDetail(e)}
>
<div className="img">
<img src={img} alt="error" />
</div>
<div className="desc">
<div className="name">{name}</div>
<TagsBlock tags={tags}></TagsBlock>
</div>
</a>
</div>
)
});
render() {
return (
<div className="result-coctails">
<div className="block">
{this.list}
</div>
<ActionButton txt="morе"></ActionButton>
</div>
)
}
}
export default connect(state => ({
loadCoctails: state.loadCoctails
}), { actionLoadCoctails, actionToggleDetail })(ResultsCoctails);
Reducer
import { LOAD_COCTAILS } from '../constants';
const INIT_COCTAILS = [
{
img: 'some url',
name: 'Cocktail Mary',
tags: ['one', 'two', 'three'],
},
{
img: 'some url',
name: 'White Russian',
tags: ['one', 'two', 'three'],
},
{
img: 'some url',
name: 'Cocktail Mary',
tags: ['one', 'two', 'three'],
},
{
img: 'some url',
name: 'White Russian',
tags: ['one', 'two', 'three'],
},
{
img: 'some url',
name: 'Cocktail Mary',
tags: ['one', 'two', 'three'],
}
];
export const loadCoctails = (state = [], { type }) => {
switch(type) {
case LOAD_COCTAILS:
return {
...state, ...INIT_COCTAILS
}
default:
return state;
}
}
ActionCreator
import {
LOAD_COCTAILS,
TOGGLE_DETAIL,
LOAD_DETAIL
} from '../constants';
export const actionLoadCoctails = () => {
return {
type: LOAD_COCTAILS
}
}
export const actionToggleDetail = () => {
return {
type: TOGGLE_DETAIL
}
};
export const actionLoadDetail = (img, name, tags, deg, txt) => {
return {
type: LOAD_DETAIL,
img,
name,
tags,
deg,
txt
}
};
The problem is that the map() function can't work with objects - so, we should make an array and do map() with it:
const listArray = Object.values(this.props.loadCoctails);
const list = listArray.map(({ img, name, tags}, key) => {
.....

GSAP animate elements in an array fetched from the server

I would like to animate each element in an array with TweenMax.staggerFrom. At the moment I created this working sample
import React, { useRef, useEffect createRef } from 'react';
import { TweenMax } from 'gsap';
const AnimateView = () => {
const data = [
{ title: 'Title 1', value: 1000 },
{ title: 'Title 2', value: 1100 },
{ title: 'Title 3', value: 1200 },
];
const elementsRef = useRef(data.map(() => createRef()));
useEffect(() => {
const elements = elementsRef.current.map(el => el.current);
TweenMax.staggerFrom(elements, 1, { scale: 0 }, 0.3);
}, []);
return (
<>
{data.map((item, index) => (
<div ref={elementsRef.current[index]}>{item.title}</div>
))}
</>
);
};
export default AnimateView;
The difference is that I want data array to be fetched from the server. I cannot figure out why in elementsRef I'm getting no attached refs. Below you can check what I wanted to achieve.
import React, { useRef, useEffect createRef } from 'react';
import { TweenMax } from 'gsap';
import { connect } from 'react-redux';
import { fetchData } from 'actions';
const AnimateView = ({ combineFetching, income }) => {
const elementsRef = useRef(income.length && income.map(() => createRef()));
useEffect(() => {
const elements = elementsRef.current.map(el => el.current);
TweenMax.staggerFrom(elements, 1, { scale: 0 }, 0.3);
}, []);
return (
<>
<button onClick={fetchData}>Click</button>
{income.map((item, index) => (
<div ref={elementsRef.current[index]}>{item.title}</div>
))}
</>
);
};
const mapDispatchToProps = state => ({
income: state.budget.income,
});
export default connect(
mapDispatchToProps,
{ fetchData },
)(AnimateView);
On Click I want to fetch data from database and animate each element in the array.

Resources