React Router passing data from one component to another - javascript

So I have a problem with passing data from one Component to another. So I have Free To Play Component which has is taking freetoplay array from json and displaying it. I have also a Link which should open up a Payment Route and pass the data, In the Payment I have a filter function, which is fitering objects based on their id, Anyway when I press on the Link, it should display the image class and price, but it does not, I dont know why. If anyone could help me I would be very grateful. Cheers
import React from 'react'
import { useParams, Link } from "react-router-dom";
import data from "../data.json";
function Payment() {
const { productId } = useParams();
const filteredData = data.filter((product) => product.id === productId)[0];
return (
<div className='Payment'>
<img src={filteredData.image}></img>
<h1>{filteredData.price}</h1>
<h1>{filteredData.name}</h1>
</div>
)
}
export default Payment
import React from 'react'
import data from "./data.json";
import {
Link
} from "react-router-dom";
import { SearchContext } from './SearchContext';
function FreeToPlay() {
const {filterProduct}=React.useContext(SearchContext);
return (
<>
<div className='All' >
{data[0].freetoplay.filter(filterProduct).map((product) => {
return (
<div className='f2p' key={product.id}>
<img src={product.image}></img>
<h2>{product.name}</h2>
<h5>{product.price}</h5>
<Link
to={`/payment/${product.id}`}
className='link'
>
Buy Now
</Link>
</div>
);
})}
</div>
</>
);
}
export default FreeToPlay
json
[
{
"freetoplay": [{
"id": "0",
"image": "src=fsdf",
"price": "60$",
"name": "CS Go"
},
{
"id": "1",
"image": "src=fsdf",
"price": "6$",
"name": "Fifa"
}
],
"action": [{
"id": "2",
"image": "src=fsdf",
"price": "60$",
"name": "doom"
},
{
"id": "3",
"image": "src=fsdf",
"price": "66$",
"name": "cyberpunk"
}
],
}
]
this is the Route
<Route path="/payment/:productId">
<Payment/>
</Route>

It looks like your issue might be in the handling of your data.filter in the Payment component.
You use:
const filteredData = data.filter((product) => product.id === productId)[0];
But your data imported from data.json is an object, not an array.
You must have meant either:
const filteredData = data.action.filter((product) => product.id === productId)[0];
Or:
const filteredData = data.freetoplay.filter((product) => product.id === productId)[0];

Related

React.js with OpenWeatherMap, getting weathers.map is not a function

I am learning React.js for college and am a bit stuck. I am getting this error:
weathers.map not a function
I am sure it's something simple but can't figure it out! It is a standard create-react-app, created a directory called components and these 2 files live there:
Weathers.js:
import {useState} from 'react'
import axios from 'axios'
import Weather from './Weather'
function Weathers() {
const [weathers, setWeathers] = useState()
const [city, setCity] = useState('')
const API = {
link: "http://api.openweathermap.org/data/2.5/weather?q=",
key: "&appid=xxxxx"
}
function handleSearchCity(e) {
e.preventDefault()
setCity(e.target.value)
}
async function searchWeathers(e) {
e.preventDefault()
console.log()
var response = await axios.get(API.link + city + API.key)
console.log(response)
setWeathers(response.data)
}
return (
<div>
<input value={city} onChange={handleSearchCity} />
<button onClick={searchWeathers}>Search</button>
<div>
</div>
{
weathers.map(function(i, index){
return (
<div>
<Weather name={i.name} />
</div>
)
})
}
</div>
)
}
export default Weathers;
Weather.js:
function Weather(props) {
return (
<div>
{props.name}
</div>
);
}
export default Weather;
You are getting an error because the result from the api is not an array. It is an object that looks like this (for London):
{
"coord": {
"lon": -0.1257,
"lat": 51.5085
},
"weather": [
{
"id": 500,
"main": "Rain",
"description": "light rain",
"icon": "10n"
}
],
"base": "stations",
"main": {
"temp": 278.91,
"feels_like": 276.51,
"temp_min": 277.25,
"temp_max": 280.02,
"pressure": 1021,
"humidity": 88
},
"visibility": 10000,
"wind": {
"speed": 3.09,
"deg": 330
},
"rain": {
"1h": 0.89
},
"clouds": {
"all": 100
},
"dt": 1646438029,
"sys": {
"type": 2,
"id": 2019646,
"country": "GB",
"sunrise": 1646375984,
"sunset": 1646415906
},
"timezone": 0,
"id": 2643743,
"name": "London",
"cod": 200
}
If you want the name propriety inside the result, you could get it like so:
import {useState} from 'react'
import axios from 'axios'
import Weather from './Weather'
function Weathers() {
const [weathers, setWeathers] = useState()
const [city, setCity] = useState('')
const API = {
link: "http://api.openweathermap.org/data/2.5/weather?q=",
key: "&appid=xxxxx"
}
function handleSearchCity(e) {
e.preventDefault()
setCity(e.target.value)
}
async function searchWeathers(e) {
e.preventDefault()
console.log()
var response = await axios.get(API.link + city + API.key)
console.log(response)
setWeathers(response.data)
}
return (
<div>
<input value={city} onChange={handleSearchCity} />
<button onClick={searchWeathers}>Search</button>
{weathers && <Weather name={weathers.name} />}
</div>
)
}
export default Weathers;
Since weathers is initialized to an empty array, you shouldn't actually have the error weathers.map is not a function.
Maybe you can add a conditional rendering to only return the jsx expression when you get the weathers data from the API.
return weathers && (
<div>
// ...
</div>
)
}
export default Weathers;

Calling json postData properly

Hello stackoverflow members. So I wanna call this action nested array in json to Action Component but I dont know how. If I could get some help that would be highly appriciated
import React from 'react'
import data from "../data.json";
function Action() {
return (
<div>
{data.map((postData) => {
console.log(postData);
return(
<div key={postData.id}>
<h1 >{postData.action.name}</h1>
</div>
)})}
</div>
)
}
export default Action
[
{
"action":[{
"id":"0",
"image": "src=fsdf",
"price" : "60$",
"name" :"cs"
},
{
"id":"1",
"image": "src=fsdf",
"price" : "6$",
"name" :"whatever"
}],
"adventure":[{
"id":"10",
"image": "src=fsdf",
"price" : "60$",
"name" :"Cs"
}]
}
]
You need to store your data.json file in the public folder if you want to access the data in json format and then make use of useEffect Hook and fetching data within useEffect() Hook itself to get the data.
Here is the WORKING DEMO on Codesandbox:
https://codesandbox.io/s/json-fanda-stydg
FULL CODE:
import React from "react";
import { useEffect, useState } from "react";
import "./styles.css";
function App() {
const [data, setData] = useState([]);
useEffect(() => {
fetch("./data/data.json")
.then((response) => response.json())
.then((json) => {
console.log(json);
setData(json);
});
});
return (
<div>
{data.length > 0 &&
data.map((postData) => {
console.log(postData);
return (
<div key={data.id}>
{postData.action.map((action) => {
return <h1>{action.name}</h1>;
})}
<p>
{postData.adventure.map((adventure) => {
return <h1>{adventure.name}</h1>;
})}
</p>
</div>
);
})}
</div>
);
}
export default App;
JSON: You JSON is perfectly fine :)
[
{
"action": [
{
"id": "0",
"image": "src=fsdf",
"price": "60$",
"name": "cs"
},
{
"id": "1",
"image": "src=fsdf",
"price": "6$",
"name": "whatever"
}
],
"adventure": [
{
"id": "10",
"image": "src=fsdf",
"price": "60$",
"name": "Cs"
}
]
}
]
You could change your code to something like this:
import data from "../data.json";
//...
export default function App() {
return (
<div className="App">
<div>
{data[0].action.map((postData) => {
return (
<div key={postData.id}>
<h1>{postData.name}</h1>
</div>
);
})}
</div>
</div>
);
}
data is an array with one object with two properties: action and adventure that are arrays.
As prasanth points out given your current data you could also remove the outer most array and make data a single object.
Then you can just map over data.action.
sandbox

React Native Networking with react-native-router-flux

Hey guys I have a short question. I want to give every Button a other Page.
import React, { Component } from 'react';
import { ActivityIndicator, FlatList, Text, View, TouchableOpacity } from 'react-native';
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
data: [],
isLoading: true
};
}
componentDidMount() {
fetch('https://reactnative.dev/movies.json')
.then((response) => response.json())
.then((json) => {
this.setState({ data: json.movies });
})
.catch((error) => console.error(error))
.finally(() => {
this.setState({ isLoading: false });
});
}
render() {
const { data, isLoading } = this.state;
return (
<View style={{ flex: 1, padding: 24 }}>
{isLoading ? <ActivityIndicator/> : (
<FlatList
data={data}
keyExtractor={({ id }, index) => id}
renderItem={({ item }) => (
<TouchableOpacity>
<Text>{item.title}</Text>
</TouchableOpacity>
)}
/>
)}
</View>
);
}
};
The Code give me the movie names as Button and I can click on everyone. Right now I want to open for every Button a other page with react-native-router-flux.
{
"title": "The Basics - Networking",
"description": "Your app fetched this from a remote endpoint!",
"movies": [
{
"id": "1",
"title": "Star Wars",
"releaseYear": "1977"
},
{
"id": "2",
"title": "Back to the Future",
"releaseYear": "1985"
},
{
"id": "3",
"title": "The Matrix",
"releaseYear": "1999"
},
{
"id": "4",
"title": "Inception",
"releaseYear": "2010"
},
{
"id": "5",
"title": "Interstellar",
"releaseYear": "2014"
}
]
}
This is the Json Data where I fetch the names. Maybe the "id" will help me, but I really dont know what can I right now do.
I can only give you some recommend, because it is too rough to explain although is is a short question.
I remember using react-native-router-flux have to import your scene(page) and using Actions.somepage() to route to the page. But using FlastList is hard to Actions.eachpage like this. (Maybe just my skills are not good enough to achieve)
If you want to achieve like your description, I will recommend you to create a new page component to handle all of the scene now we just called "HandlePage", and then you could add it to your TouchableOpacity by using like
import HandlePage from "./HandlePage";
...
<TouchableOpacity onPress={() => { Actions.HandlePage({page: item.id}); }}
So that you could control the page at HandlePage , take this parameter(id) to handle which page you want to render. Actually, is only using one Actions.HandlePage to route but have more flexible to render what you want.
Hope it could help.
Update:
Something like:
import StarWars from "./StarWars";
import TheMatrix from "./TheMatrix";
import Inception from "./Inception";
import Interstellar from "./Interstellar";
export default class HandlePage extends React.Component {
checkSwitch = param => {
switch (param) {
case "1":
return <StarWars/> ;
case "2":
return <TheMatrix recordCount = {this.state.recordCount}/>;
case "3":
return <Inception disabled = {this.state.disabled3}/>;
case "4":
return <Interstellar alert = {this.state.alert4}/>;
default:
return null;
}
};
render() {
return ({
this.checkSwitch(this.props.page)
})
}
}

React-Redux: Page becomes blank white screen after clicking a button and components do not appear

I am working on a React application and I am using Redux to store the state. I have the following code:
category-arrows.component.jsx:
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { increaseCategoryRank, decreaseCategoryRank } from '../../redux/menu/menu.actions';
import './category-arrows.styles.scss';
class CategoryArrows extends Component {
handleClick = (id) => {
this.props.increaseCategoryRank(id);
}
render() {
const { categoryRank, categoryId, increaseCategoryRank, decreaseCategoryRank } = this.props;
return (
<div class="arrows-container">
<div class="up-arrow" onClick={this.handleClick(categoryId)}></div>
<div class="category-rank">
<p>{categoryRank}</p>
</div>
<div class="down-arrow"></div>
</div>
)
}
}
export default connect( { increaseCategoryRank, decreaseCategoryRank } )(CategoryArrows);
menu-category.component.jsx:
import React from 'react';
import { connect } from 'react-redux';
import MenuItem from '../../components/menu-item/menu-item.component';
import MenuCarousel from '../../components/menu-carousel/menu-carousel.component';
import NewItemCard from '../../components/new-item-card/new-item-card.component';
import DeleteCategory from '../../components/delete-category/delete-category.component';
import CategoryArrows from
'../../components/category-arrows/category-arrows.component';
import { editCategory } from '../../redux/menu/menu.actions';
import { MANAGER } from '../../redux/user/user.staff-types';
import './menu-category.styles.scss';
const MenuCategory = ({ currentUser, editCategory, isEditing, ...category }) => {
const isManager = currentUser && currentUser.type === MANAGER;
const editableProps = {
className: isManager ? 'category-editable' : null,
contentEditable: !!isManager,
suppressContentEditableWarning: true
};
return (
<div key={category._id} className='menu-category'>
<h2 {...editableProps} onBlur={event => editCategory({ ...category, name: event.target.innerText })}>
{category.name}
</h2>
<p {...editableProps} onBlur={event => editCategory({ ...category, description: event.target.innerText })} >
{category.description}
</p>
<MenuCarousel>
{isManager && isEditing ? <CategoryArrows className='category-rank-arrows' categoryRank={category.rank} categoryId={category._id} /> : null}
{isManager ? <NewItemCard categoryId={category._id} /> : null}
{category.items.map(menuItem => <MenuItem key={menuItem._id} categoryId={category._id} {...menuItem} />)}
{isManager ? <DeleteCategory name={category.name} categoryId={category._id} className='delete-bin' /> : null}
</MenuCarousel>
</div>
)
}
const mapStateToProps = state => ({
currentUser: state.user.currentUser
})
export default connect(mapStateToProps, { editCategory })(MenuCategory);
menu.component.jsx:
import React, { Component } from 'react';
import { connect } from 'react-redux';
import MenuCategory from '../../components/menu-category/menu-category.component'
import NewCategoryButton from '../../components/new-category-button/new-category-button.component';
import EditMenuButton from '../../components/edit-menu-button/edit-menu-button.component';
import './menu.styles.scss';
class MenuPage extends Component {
state = {
menuEditable: false
}
toggleMenuEditable = () => this.setState({ menuEditable: !this.state.menuEditable })
render() {
return (
<div className='menu-page'>
{this.props.menu ? this.props.menu.map(category => <MenuCategory key={category._id} {...category} isEditing={this.state.menuEditable} />) : null}
<div className='edit-menu-buttons'>
<div className='menu-button'>
{this.props.currentUser ? <NewCategoryButton /> : null}
</div>
<div className='menu-button'>
{this.props.currentUser ? <EditMenuButton onClick={this.toggleMenuEditable} isEditing={this.state.menuEditable} /> : null}
</div>
</div>
</div>
)
}
}
const mapStateToProps = state => ({
currentUser: state.user.currentUser,
menu: state.menu
})
export default connect(mapStateToProps)(MenuPage);
menu.actions.js:
import { INCREASE_CATEGORY_RANK, DECREASE_CATEGORY_RANK } from './menu.types';
export const increaseCategoryRank = categoryId => dispatch => {
dispatch({ type: INCREASE_CATEGORY_RANK, payload: categoryId })
}
export const decreaseCategoryRank = categoryId => dispatch => {
dispatch({ type: DECREASE_CATEGORY_RANK, payload: categoryId })
}
menu.types.js:
export const INCREASE_CATEGORY_RANK = "INCREASE_CATEGORY_RANK";
export const DECREASE_CATEGORY_RANK = "DECREASE_CATEGORY_RANK";
menu.reducer.js:
import INITIAL_STATE from './menu.data';
import { INCREASE_CATEGORY_RANK, DECREASE_CATEGORY_RANK } from './menu.types';
export default (state = INITIAL_STATE, action) => {
switch (action.type) {
case INCREASE_CATEGORY_RANK:
console.log(action.payload._id);
return;
case DECREASE_CATEGORY_RANK:
console.log(action.payload._id);
return;
default:
return state;
}
}
menu.data.js:
export default [
{
"_id": "c0daac6ab8954a40606dd8b81d24a0ef",
"name": "Entree",
"rank": "0",
"items": [
{
"title": "Curry Puffs",
"price": 14,
"_id": "615caa7dd573bcf84781c9e4382b520d"
},
{
"title": "Spring Rolls",
"price": 12,
"_id": "542f711856b7854b71d9862797620e23"
},
{
"title": "Tandoori Cauliflower",
"price": 20,
"_id": "f0c0f2fa02e392ad4e74dfaaf6068fb1"
}
]
},
{
"_id": "934aeba1e96e6d6a4207cd5ba207b52a",
"name": "Lunch",
"rank": "1",
"items": [
{
"title": "Spaghetti",
"price": 20,
"_id": "db414e2b9951ed621fbf6fb40df36ee3"
},
{
"title": "Spaghetti",
"price": 20,
"_id": "253592733a8f7835f390d3d9ed8bda95"
},
{
"title": "Spaghetti",
"price": 20,
"_id": "a22741f27a346cda93d3cf752e371779"
}
]
}
]
In the above code, I have a CategoryArrows component that is rendered in the MenuCategory component only if the isEditing value which is passed from the MenuPage component to the MenuCategory component as a props is true. When the EditMenuButton component is clicked, isEditing is set to true, and the CategoryArrows components appear on the menu page.
When the up-arrow div is clicked I want to dispatch the action increaseCategoryRank, which takes the category id as a parameter. I have added code for this action.
However, when I click the EditMenuButton component, the CategoryArrows do not appear and the screen turns blank white. I get the following error when I inspect the page:
Uncaught Error: Invalid value of type object for mapStateToProps argument when connecting component CategoryArrows.
I am not sure what this error means and how to resolve it. Any insights are appreciated.
You have not passed correct parameter inputs to redux connect function in your code.
The connect function first argument must be the mapStateToProps function which returns the reduced state.
export default connect( null, { increaseCategoryRank, decreaseCategoryRank } )(CategoryArrows);
Pass null as the first parameter to connect since you don't seem to pass any props from the redux store.
Please update your category-arrows.component.jsx connect as given above.
Your first argument to connect is an object here:
export default connect( { increaseCategoryRank, decreaseCategoryRank } )(CategoryArrows);
The first argument to connect should be mapStateToProps which is a function. If you want to access dispatch, but don't need state, you need to pass null as first argument to connect:
connect(null, mapStateToDispatch)

ReactJS mapping to API

import React, { Component } from 'react';
import axios from 'axios';
class Meetups extends Component {
constructor(props) {
super(props);
console.log('in constructor');
this.state = {
results: [],
};
}
componentDidMount() {
console.log('meetup feed');
axios.get('https://api.meetup.com/2/categories?offset=0&format=json&photo-host=public&page=20&order=shortname&desc=false&sig_id=211627025&sig=ae69aec13f23c7837cd55c5a68b99e00719fa225')
//response
.then(response => response.json())
.then(data => this.setState({results:data.results}));
}
render() {
const {results} =this.state;
return(
<div>
{results.map(result =>
<div key={result.id} className='container'>
{result.name}
</div>
)}
</div>
);
}
}
export default Meetups;
JSON format which I'm receiving:
{
"results": [
{
"name": "Arts & Culture",
"sort_name": "Arts & Culture",
"id": 1,
"shortname": "Arts"
},
{
"name": "Book Clubs",
"sort_name": "Book Clubs",
"id": 18,
"shortname": "Book Clubs"
},
{
"name": "Career & Business",
"sort_name": "Career & Business",
"id": 2,
"shortname": "Business"
}
]
}
I am trying to use Meetup API in my project. But could not able to connect with it. There might be a problem with mapping. I want to know exact mapping for the given json format. Please help me out. Thanks
import React, { Component } from 'react';
import axios from 'axios';
class Meetups extends Component {
state = {
results: []
}
componentDidMount() {
axios.get('https://api.meetup.com/2/categories?offset=0&format=json&photo-host=public&page=20&order=shortname&desc=false&sig_id=211627025&sig=ae69aec13f23c7837cd55c5a68b99e00719fa225')
.then(response => {
let results = response.data.results;
this.setState({ results: results });
console.log(response);
})
}
render() {
let studentsDisplay = (
this.state.results.map( (result, index) =>
<div key={index} className="card" style= { {width: '18rem'} }>
{result.name}
<br/>
{result.shortname}
</div>
));
return (
<div className='container'>
{
studentsDisplay
}
</div>
);
}
}
export default Meetups;

Categories

Resources