How to pass data from component to another component - reactjs

I'm trying to pass some data (response of fetch to API) from a component to another component, but I don't find the way to pass them.
In the Class AddresForm, I get the serialized data from form, this data is send to API with fecth method. The response has important information and I need use this information contained on response in another component.
class AddressForm extends React.Component{
constructor(props) {
super(props);
this.handleSubmit = this.handleSubmit.bind(this);
this.validatePredio = this.validatePredio.bind(this);
this.state = {
isApartment: false,
required: false
};
this.cities = [];
this.cities.push(["11001" ,"XXX"]);
this.cities.push(["05001", "YYY"]);
this.cities.push(["76001", "ZZZ"]);
}
handleSubmit(event) {
event.preventDefault();
const data = serialize(event.target, { hash: true });
data['direccion'] = data['direccion']+"+"+data['num1']+"+"+data['num2']+"+"+data['num3'];
fetch('https://api.....', {
method: 'POST',
headers: header,
body: JSON.stringify(data),
})
.then((response) => response.json())
.then((responseData) => {
console.log(responseData); // this data is needed in another component (MapSection)
});
}
And in this Class I need use the response of fetch from the previous component, exactly I need use some coordinates to render a Map.
export class MapSection extends React.Component{
constructor(props) {
super(props);
this.setState = this.setState.bind(this);
}
state = {
address: null
};
get googleMapDiv(){
return document.getElementById("mapa");
}
googleMapRef = createRef();
render(){
console.log(this.props,this.googleMapRef);
return(
<section className="hidden2" id="mapaSection">
<div className="container">
<div className="row mt-5">
<div className="col mt-5">
<h3>Confirma la ubicación de tu inmueble</h3>
<div className="row mt-5">
<div className="col">
<p id="direccionGeo"> {this.state.address !== null ? this.state.address : ""} </p>
</div>
</div>
<div id="mapa"
ref={this.googleMapRef}
style={{ width: 'auto', height: '55vh' }}
className="card-panel white map-holder"
/>
<div className="botonesMapa row mt-5">
<div className="col-6" align="center">
<button type="button" className="btn btn-info corregirBtn">Corregir dirección</button>
</div>
<div className="col-6" align="center">
<button type="button" className="btn btn-info confirmarBtn">Ubicación correcta</button>
</div>
</div>
</div>
</div>
</div>
</section>
)
}
componentDidMount() {
const self = this;
const googleMapScript = document.createElement('script');
googleMapScript.src = 'https://maps.googleapis.com/maps/api/js?key=yourKEY';
window.document.body.appendChild(googleMapScript);
googleMapScript.addEventListener('load',() => {
var coord = { lat: 4.6903289512, lng: -74.0522237222};
this.googleMap = this.createGoogleMap(coord);
this.marker = this.createMarker();
window.google.maps.event.addListener(this.marker, 'dragend', function(e) {
var request = {
"entrada": "address",
"mpio_ccdgo": "11001",
"lat": e.latLng.lat(),
"lng": e.latLng.lng()
};
fetch('https://api....', {
method: 'POST',
headers: header,
body: JSON.stringify(request),
}).then((response) => response.json())
.then(responseData => {
self.setState({
address: responseData.direccion_formato
});
});
});
});
}
createGoogleMap = ( data ) => {
return new window.google.maps.Map(this.googleMapRef.current, {
zoom: 16,
center:{
lat: data.lat, //4.6903289512
lng: data.lng//-74.0522237222
},
disableDefaultUI: true
});
};
createMarker = () => {
return new window.google.maps.Marker({
position: {lat: 4.6903289512, lng: -74.0522237222},
map: this.googleMap,
title: 'Avaluamos',
draggable: true
});
};
}
Finally I've a Class that join all components
class InitialForm extends React.Component{
constructor(props) {
super(props);
}
render(){
return(
<div>
<AddressForm />
<MapSection/>
<FeaturesForm/>
</div>
)
}
}
Many Thanks for your time and knowledge.

An idea would be to add a method to InitialForm that takes a string and saves it to InitialForm's state. You can pass this method as a prop to AddressForm and call it with the api response as an argument. Now you got the response in InitialForm and you can pass it down to MapSection.
Is that clear?

Related

ReactJS select value from json array

So I'm trying to get some data from my api and then select that data and send it to the other api, but I can't figure it out how to select the data.
import React, { Component } from 'react'
import Dropdown from 'react-dropdown'
import 'react-dropdown/style.css'
class Testas extends Component {
constructor(props){
super(props);
this.state = {
}
}
componentDidMount() {
const headers = {
'Authorization': 'Bearer ',''
};
fetch(`https://spiceworks/api/printserver/printers`,{ headers }
)
.then(res => res.json())
.then(json => {
this.setState({
isLoaded: true,
items: json.printers,
})
});
}
render() {
const { items } = this.state
const type = ['test', 'python', 'web', 'all']
const amount = [1,2,3,4,5,6,7,8,9,10]
return (
<div className="content">
<form>
<div className="row">
<div className="col-sm">
<div className="card">
<div className="card-body">
<h3 className="card-title">Printer Test</h3>
<Dropdown className="drop" options={this.state.items} placeholder="Pasirinkti printerį" />
<Dropdown className="drop2" options={type} placeholder="Būdas" />
<Dropdown className="drop2" options={amount} placeholder="Kiekis" />
Test
</div>
</div>
</div>
</div>
</form>
</div>
)
}
}
export default Testas
the data I recieve from api looks like this
{
"printers": [
"ZEB-SOFA15",
"ZEB-120",
"GDX-SOFUZ4",]}
i tried with e value onchange code but then I always get error that data.map is not a function.

conditional render disappears after a few seconds

Hi I am making a website front end (react) which talks to my back end (npm express/npm mssql)
I have made a page in which it uses a map function to render a separate component containing questions.
I have tried to implement a conditional render so that when question complete is set as true it then renders a new component but the new component will vanish after a second or so and will go back to its original state.
these are both in the same file so only one set of imports are required in this situation.
This is my display questions class using a .map to render the separate component.
import React from "react";
import { Link } from "react-router-dom";
import { Modal } from "react-bootstrap";
class DisplayQuestions extends React.Component {
constructor() {
super();
this.state = { questions: [], QuestionsAnswer: [], QuestionsSeverity: [] };
this.onSubmit = this.handleSubmit.bind(this);
}
// sets the questions form sql into state for questions
getItems() {
fetch("/user-questions")
.then(recordset => recordset.json())
.then(results => {
this.setState({ questions: results.recordset });
});
}
//when the component mounts make the sql questions the s
componentDidMount() {
this.setState({
questions: this.getItems()
});
}
handleSubmit(e) {
e.preventDefault();
const data = {
QuestionID: this.QuestionID,
QuestionsAnswer: this.state.QuestionsAnswer,
QuestionSeverity: this.state.QuestionsSeverity
};
try {
fetch("/Question-Response", {
method: "POST", // or 'PUT'
headers: {
Accept: "application/json, text/plain, */*",
"Content-Type": "application/json"
},
body: JSON.stringify(data)
})
.then(response => response.json())
.then(data => {
console.log("Success:", data);
})
.catch(error => {
console.error("Error:", error);
});
} catch (error) {}
}
refresh() {
window.location.reload();
}
render() {
var self = this;
console.log(this.state.questions);
return (
<div>
<h3 style={{ textAlign: "center" }}>
<u>Desk Assessment</u>
</h3>
<ul>
<button
disabled
className="btn btn-secondary"
style={{ float: "left " }}
>
Desk Assessment
</button>
<Link to="./user-history">
<button className="btn btn-secondary" style={{ float: "left " }}>
View History
</button>
</Link>
<br />
<br />
{this.state.questions &&
this.state.questions.map(function(questions, index) {
return (
<div >
<ul>
<WorkStations questions={questions}></WorkStations>
</ul>
</div>
);
})}
</ul>
</div>
);
}
}
export default DisplayQuestions;
This is my Questions component which is rendered
class WorkStations extends React.Component {
constructor(props) {
super(props);
console.log(props);
this.state = { ...props, show: false, QuestionAnswer: "", QuestionComplete: false };
this.QuestionDecline = this.QuestionDecline.bind(this);
this.QuestionOnChange = this.QuestionOnChange.bind(this);
this.OnCommit = this.OnCommit.bind(this);
}
QuestionDecline(e) {
e.preventDefault();
if (this.state.ShowInput) {
this.setState({ ShowInput: false });
alert(this.state.ShowInput);
} else if (!this.state.ShowInput) {
this.setState({ ShowInput: true });
alert(this.state.ShowInput);
}
}
QuestionOnChange(e) {
this.setState({ QuestionAnswer: e.target.value });
}
//////////////////////////////////////////////////////////// I believe its within here something is off
OnCommit(e) {
e.preventDefault();
alert(this.state.QuestionAnswer);
var today = new Date(),
date = `${today.getUTCFullYear()}-${today.getUTCMonth() +
1}-${today.getUTCDate()} ${today.getHours()}:${today.getMinutes()}:${today.getSeconds()}.${today.getMilliseconds()} `;
let User = window.localStorage.getItem("User")
const data = {
QuestionId: this.state.questions.QuestionId,
QuestionAnswer: this.state.QuestionAnswer,
date : date,
User
};
fetch("/question-response", {
method: "POST", // or 'PUT'
headers: {
Accept: "application/json,",
"Content-Type": "application/json"
},
body: JSON.stringify(data)
}).then(response => {
console.log("response before it is broken down " + response);
// return response.json();
});
if (this.state.QuestionComplete) {
this.setState({ QuestionComplete: false });
alert(this.state.QuestionComplete);
} else if (!this.state.QuestionComplete) {
this.setState({ QuestionComplete: true });
alert(this.state.QuestionComplete);
}
window.location.reload();
}
////////////////////////////////////////////////
render() {
if (!this.state.QuestionComplete ){
if (!this.state.ShowInput && !this.state.QuestionComplete) {
return (
<div className="jumbotron">
<button
onClick={this.QuestionDecline}
className="btn btn-danger"
style={{ float: "right" }}
>
Decline
</button> <button
onClick={this.deleteQuestion}
className="btn btn-primary"
style={{ float: "right" }}
>
Accept
</button>
<br />
<li> Question ID: {this.state.questions.QuestionId}</li>
<li> Question:{this.state.questions.Question}</li>
</div>
);
} else if(this.state.ShowInput && !this.state.QuestionComplete) {
return (
<div className = "jumbotron">
<li>Question Id: {this.state.questions.QuestionId}</li>
<li>
<textarea
placeholder= "How can this be improved ?"
style={{ width: "100%" }}
onChange={this.QuestionOnChange}
/>
</li>
<button
style={{ float: "right", padding: "2px" }}
className="btn btn-primary"
onClick={this.OnCommit}
>
Submit
</button>
<button
onClick={this.EditQuestion}
style={{ float: "right", padding: "2px" }}
className="btn btn-secondary"
>
Revert
</button>
<br />
</div>
);
}
}else if (this.state.QuestionComplete) {
return(<h3> <li>Question Id: {this.state.questions.QuestionId}</li></h3>)
}
}
}

how to make api call using props

im trying to make an api call in one component using state from a different component , however when i use props in the API call im getting an error saying cannot read property props of undefined. basicly im trying to make an api call using data from a different component in then display it in the main component , but am not sure how to do it. Can someone pls tell me what im doing wrong ? thanks for the help!
class App extends Component {
constructor() {
super();
this.state = {
places2: [] ,
isLoaded2: true,
isLoaded: true,
latitude: 37.774929,
longitude: -122.419416,
};
// this is the data i want to pass
geocodeByAddress(address)
.then(res => getLatLng(res[0]))
.then(({ lat, lng }) => {
this.setState({
latitude: lat,
longitude: lng,
});
})
.catch(error => {
this.setState({ isGeocoding: false });
console.log('error', error); // eslint-disable-line no-console
});
}
render() {
return (
<div id="h">
{this.state.isLoaded ?
<Health
latitude={this.state.latitude}
longitude={this.state.longitude}
parentMethod={this.parentMethod}
parentMethod2={this.parentMethod2}
/>
: <div>.</div>}
<Map center= {{lat: this.state.latitude, lng: this.state.longitude}}/>
{this.state.isLoaded ?
<div id="location-basic-info" >
<UserForm
address={this.state.address}
Latitude={this.state.latitude}
Longitude={this.state.longitude}
/>
</div> : <div>.</div>}
{this.state.isLoaded2 ?
<Health
latitude={this.state.latitude}
longitude={this.state.longitude}
parentMethod={this.parentMethod}
parentMethod2={this.parentMethod2}
/>
: <div>.</div>}
{this.state.isLoaded2 ?
<div id="location-basic-info" >
<div> {this.state.place} {this.state.places2} </div>
</div> : <div>.</div>}
</div>
<div>
</div>
</div>
);
}
};
export default App;
health.js
class Health extends Component {
constructor() {
super();
this.state = {
zoom: 13,
maptype: 'roadmap',
place_formatted: '',
place_id: '',
place_location: '',
address: '',
latitude: 37.774929,
longitude: -122.419416,
marker:[],
places: [], isLoaded: false,
places2: []
};
}
getplace(){
var param = {
//this is giving me the error
lat: this.props.latitude,
long: this.props.longitude,
temp:1
}
axios.post(`http://localhost:5000/search-champ`, {
param
}).then((data)=>{
this.setState({places: data});
console.log( this.state.places);
console.log(data);
const places = data.data.data[0].results.slice(0,10).map((place) => {
console.log(place.name)
console.log(place.geometry.location.lat)
console.log(place.geometry.location.lng)
let name = place.name;
let vicinity= place.vicinity;
return <div class="col-xs-6 col-sm-6">
<ul id="places-list">
<li><a onClick={() => this.hello(name, vicinity)}> {place.name} </a> </li>
</ul>
</div>
})
console.log('places', places);
const places2 = data.data.data[1].results.slice(0,10).map((place) => {
console.log(place.name)
console.log(place.geometry.location.lat)
console.log(place.geometry.location.lng)
let name = place.name;
let vicinity= place.vicinity;
return <div class="col-xs-6 col-sm-6">
<ul id="places-list">
<li><a onClick={() => this.hello(name, vicinity)}> {place.name} </a> </li>
</ul>
</div>
});
this.setState({ place: places , isLoaded: true});
this.setState({ places2: places2 , isLoaded: true});
})
}
render(){
return(
<div>
<ul class="nav nav-pills" id="f">
<li class="active" onClick={this.props.parentMethod}> Info</li>
<li onClick={this.props.parentMethod2}>Food</li>
<li onClick={this.getplace}>Health</li>
<li>Menu 3</li>
</ul>
{this.state.isLoaded2 ?
<div id="location-basic-info" >
<div> {this.state.places} {this.state.places2} </div>
</div> : <div>.</div>}
</div>
);
}};
export default Health;
Your call to the api must be in the componentDidMount method.
componentDidMount: This method is called once all our children Elements and our Component instances are mounted onto the Native UI
Simple life cycle:
class Example extends React.Component {
constructor()
{
console.log('constructor')
}
componentWillMount()
{
console.log('Pre-mounting ')
}
componentDidMount()
{
console.log('Post-mounting ')
//TODO: call api axios or fetch
}
render()
{
console.log('render ui')
return(....)
}
}
Also i saw something like that in your code:
render() {
// BAD: Do not do this!
this.setState({ place: places , isLoaded: true});
this.setState({ places2: places2 , isLoaded: true});
}
Happy coding!

Unbearable TypeError: this.state.products.map is not a function

I am trying to pull data from woocommerce in which this data gets put into an empty array and for each object in that array I will get a particular piece of data from it.
Here is my code:
export class MainRight extends Component {
constructor(props) {
super(props);
this.state = {
products: []
};
}
componentDidMount() {
const productsURL = "http://localhost:8888/wp-json/wc/v2/products/28/variations";
fetch(productsURL)
.then(response => response.json())
.then(response => {
this.setState({
products: response
});
});
}
render() {
let lengthVariations = this.state.products.map((product, index) => {
return (
<div key={index}>
<LengthSelectorButtons lengths={product.option} />
</div>
);
});
return (
<div style={{ display: "inline-block" }}>
<div className="mainRightContainer">
<h1 className="hairTitle">{this.props.hairPatternName}</h1>
<p className="subTitles">{this.props.hairTextureName}</p>
<LaceSelectorButtons />
<p style={{ paddingTop: "121.5px" }} className="subTitles">
Lengths
</p>
{lengthVariations}
<div className="cartButton">
<h1 className="cartTitle">ADD TO CART</h1>
</div>
<ReviewsShopPage />
</div>
</div>
);
}
}

React - Map content inside a div

Good Morning! Why does my map content stay outside the "blog--div" div?
It's getting loose on Body and I do not know why. Help-me, please!
I try to put a border around the contents of the "blog--div" but the content becomes loose, making it impossible to apply styles.
imports[...]
class Blog extends Component {
constructor(props) {
super(props)
this.state = {
post: [],
}
}
componentDidMount() {
this.setState({ isLoading: true })
fetch(`${API}`)
.then(res => res.json())
.then(res => {
this.setState({
post: [res],
isLoading: false,
})
})
}
render() {
const { isLoading } = this.state
if (isLoading) {
return <Loading />
}
return (
<div className="blog">
<p className="blog__title">Blog</p>
{this.renderBlog()}
</div>
)
}
renderBlog() {
const page = this.state.post.map((post, key) => {
return (
<div className="blog--div" key={key}>
<div className="blog__post">
<div className="blog__post--title">
<p><a target="_blank" rel="noopener noreferrer" href={post[0].link}>{post[0].title.rendered.replace('Visit.Rio', 'Projeto 1')}</a></p>
</div>
<div className="blog__post--description">
<p>{post[0].excerpt.rendered.replace('Visit.Rio', 'Projeto 1')}</p>
</div>
</div>
</div>
)
})
return page
}
}
export default Blog

Resources