I am making a todo app in react and after taking input from the user on submit i am making a post request to update in the database and then updating the state. and then i am trying to clear the input field using
e.target.value = "". But this is not working. Iam fairly new to JS and React. can some one point me what i am doing wrong here.
class TodoApp extends Component {
constructor(props) {
super(props);
this.state = {
todos: [],
};`enter code here
this.handleTodos = this.handleTodos.bind(this);
this.handleLogout = this.handleLogout.bind(this);
this.removeTodo = this.removeTodo.bind(this);
};
componentDidMount() {
const authStr = 'Bearer ' + getJWTToken();
axios.get('/tasks', {
'headers': {
'Authorization': authStr
}
}).then(res => {
// console.log(res.data);
this.setState({
todos: res.data,
})
}).catch(err => {
console.log(err);
});
};
removeTodo = id => {
// console.log(id)
const authStr = 'Bearer ' + getJWTToken();
axios.delete('/tasks/' + id, {
'headers': {
'Authorization': authStr
}
}).then(res => {
// console.log(res.data);
let newTodos = [...this.state.todos];
newTodos = newTodos.filter(todo => {
return todo._id !== id;
});
//Update the State
this.setState({
todos: newTodos
});
}).catch(err => {
console.log(err);
});
};
handleTodos = e => {
e.preventDefault();
const authStr = 'Bearer ' + getJWTToken();
var todo = {
description: e.target.value
}
console.log(todo)
axios.post('/tasks', todo, {
'headers': {
'Authorization': authStr
}
}).then(res => {
// console.log(res.data);
this.setState({
todos: this.state.todos.concat(res.data)
})
}).catch(err => {
console.log(err)
});
e.target.value = "";
// console.log(todo);
};
handleLogout() {
localStorage.removeItem('jwtToken');
this.props.history.push("/");
}
render() {
const listLayout = {
labelCol: {
xs: { span: 24 },
sm: { span: 8 },
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 16 },
},
};
return (
<div className="container-fluid App">
<div className="todoContainer">
<Header
handleLogout={this.handleLogout}
/>
<h1 style={{ paddingTop: "10px" }}>TODO App</h1>
<Input
placeholder="What needs to be done?"
onPressEnter={this.handleTodos}
/>
<List
itemLayout="horizontal"
locale={{ emptyText: "No Todos" }}
dataSource={this.state.todos}
renderItem={item => (
<TodoItem
todo={item}
removeTodo={this.removeTodo}
/>
)}
/>
</div>
</div>
);
};
};
export default TodoApp;
The value of your input field should be bound to your state to properly control it. You can modify your state declaration like this:
this.state = {
todos: [],
whatToDo: ""
}
and bind your input field to your state like this:
<Input
placeholder="What needs to be done?"
onPressEnter={this.handleTodos}
value={this.state.whatToDo}
onChange={this.onInputChange} // will update the state on each change
/>
then create the onInputChange function:
onInputChange= (event, data) => {
this.setState({ whatToDo: data.value });
}
and lastly, change the line
e.target.value = "";
to
this.setState({ whatToDo: "" });
try this,
handleTodos = e => {
e.preventDefault();
const authStr = 'Bearer ' + getJWTToken();
var todo = {
description: e.target.value
}
console.log(todo)
axios.post('/tasks', todo, {
'headers': {
'Authorization': authStr
}
}).then(res => {
// console.log(res.data);
this.setState({
todos: this.state.todos.concat(res.data)
})
}).catch(err => {
console.log(err)
});
//RESET FIELD
e.target.reset()
};
You can use Refs to clear input text. This is the working solution.Also, follow this Reactjs link for more information.
class App extends React.Component {
constructor(props) {
super(props);
this.inputRef = React.createRef();
this.state = {
inputField: ""
};
}
keyHandler = event => {
if (event.key === "Enter") {
console.log(this.inputRef.current.value);
this.setState({ inputField: event.target.value });
this.inputRef.current.value = "";
}
};
render() {
return (
<div>
<input
type="text"
onKeyPress={this.keyHandler}
ref={this.inputRef}
/>
<p>{this.state.inputField}</p>
</div>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id='root'></div>
Allow me to tell you that this is not the react way of working generally speaking with inputs. I could also try to fix your error, but I prefer to bring you on the right path. Have a look at this doc page: https://reactjs.org/docs/forms.html
Particularly this stackoverflow answer: What are controlled components and uncontrolled components in ReactJS?
Using controlled components, to clear the input field, you just call setState emptying the content of a particular state variable. Please, have a look at the example I'm about to write:
class NameForm extends React.Component {
constructor(props) {
super(props);
this.state = {value: ''};
}
handleChange = (event) => {
this.setState({value: event.target.value});
}
handleSubmit = (event) => {
alert('A name was submitted: ' + this.state.value);
event.preventDefault();
}
emptyInput = () => {
alert('Emptying input');
this.setState({ value: '' });
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input type="text" value={this.state.value} onChange={this.handleChange} />
</label>
<input type="submit" value="Submit" />
<button onClick={emptyInput}>Empty input</button>
</form>
);
}
}
Related
I have created Dropdown which extends Component. In this I am fetching muliple dropdown values an storing it in const data. I want pass this data from Dropdown Component to another Component in the form of function.
Any help would be really great as I am new to React and facing bit challenge.
export class CascadingDropdown extends Component {
constructor(props) {
super(props)
this.state = {
...
dropdown_data: []
}
}
componentDidMount() {
axios.get('/api/fetchCategory').then(response => {
this.setState({
CategoryData: response.data
});
});
}
ChangeSubCategory = (e) => {
this.setState({
category_id: e.target.value
});
axios.get('/api/fetchSubCategory?category_id=' + e.target.value).then(response => {
// console.log(response.data);
this.setState({
SubCategoryData: response.data,
});
});
}
ChangeSubject = (e) => {
this.setState({
sub_category_id: e.target.value
});
axios.get('/api/fetchSubjects?sub_category_id=' + e.target.value).then(response => {
// console.log(response.data);
this.setState({
subject: response.data
});
});
}
storeData = (e) => {
this.setState({
subject_id: e.target.value
});
}
render() {
const dropdown_data = {
category_id: this.state.category_id,
sub_category_id: this.state.sub_category_id,
subject_id: this.state.subject_id
}
console.log(dropdown_data)
return (
<div className ="row">
. . .
</div>
)
}
}
export default CascadingDropdown
The value from dropdown_data should be passed to a function and below is the code that I have tried.
function CreateTicket() {
const [ticketInput, setTicketInput] = useState({
category_id: '',
sub_category_id: '',
subject_id: '',
other_subject: '',
file: '',
auto_message: '',
});
const handleTicketInput = (e) => {
e.persist();
setTicketInput({...ticketInput, [e.target.name]: e.target.value })
}
const submitTicket = (e) => {
e.preventDefault();
const data = {
...
}
axios.post(`/api/store-ticket`, data).then(res => {
console.log(res.data);
. . .
})
}
return (
<div className ="container">
<form onSubmit ={handleSubmit}>
<input id="emp_name" type="text" name="employee_name" className ="form-control" disabled = "disabled" onChange = {handleTicketInput} value = {empname} />
<CascadingDropdown />
<input id="form_other_subject" type="text" name="other_subject" disabled = "disabled" className ="form-control" value = {ticketInput.other_subject} onChange = {handleTicketInput} />
</form>
</div>
)
}
export default CreateTicket;
This is what i can do for nested state,
and update states, i have used single json object dropdown_data and passed down to children, its getting complex to update state of it but easy to prop down the children,
Soution 1 (OLD):
export class CascadingDropdown extends Component {
constructor(props) {
super(props)
this.state = {
dropdown_data: {
subject_id, category_id, sub_category_id
},
CategoryData,
SubCategoryData,
subject
}
}
this.ChangeSubCategory = this.ChangeSubCategory.bind(this);
this.ChangeSubject = this.ChangeSubject.bind(this);
this.storeData = this.storeData.bind(this);
componentDidMount() {
axios.get('/api/fetchCategory').then(response => {
this.setState({
...this.state,
CategoryData: response.data
});
});
}
ChangeSubCategory = (e) => {
this.setState({
...this.state,
dropdown_data: {
...this.state.dropdown_data,
category_id: e.target.value
}
});
axios.get('/api/fetchSubCategory?category_id=' + e.target.value).then(response => {
// console.log(response.data);
this.setState({
...this.state,
SubCategoryData: response.data,
});
});
}
ChangeSubject = (e) => {
this.setState({
...this.state,
dropdown_data: {
...this.state.dropdown_data,
sub_category_id: e.target.value
}
});
axios.get('/api/fetchSubjects?sub_category_id=' + e.target.value).then(response => {
// console.log(response.data);
this.setState({
...this.state,
subject: response.data
});
});
}
storeData = (e) => {
this.setState({
...this.state,
dropdown_data: {
...this.state.dropdown_data,
subject_id: e.target.value
}
});
}
render() {
console.log(this.state.dropdown_data)
return (
<div className ="row">
<CreateTicket dropdown_data={this.state.dropdown_data}/>
</div>
)
}
}
export default CascadingDropdown
you can even pass function callbacks too,
<CreateTicket dropdown_data={this.state.dropdown_data} ChangeSubCategory={ChangeSubCategory} ChangeSubject={ChangeSubject} storeData={storeData}/
this is how you can get your parent state down into functional componenet
function CreateTicket(props) {
const [dropdown_data, setDropdown_data] = useState(props.dropdown_data); // use hooks now
//const dropdown_data = this.props.dropdown_data;
}
my new edited answer as per your new question is as follows,
Soution 2 (NEW):
export class CascadingDropdown extends Component {
constructor(props) {
super(props)
this.state = {
dropdown_data: {
subject_id:this.props.subject_id, category_id:this.props.category_id, sub_category_id:this.props.sub_category_id
},
CategoryData,
SubCategoryData,
subject
}
}
// this.ChangeSubCategory = this.ChangeSubCategory.bind(this);
// this.ChangeSubject = this.ChangeSubject.bind(this);
// this.storeData = this.storeData.bind(this);
componentDidMount() {
axios.get('/api/fetchCategory').then(response => {
this.setState({
...this.state,
CategoryData: response.data
});
});
}
ChangeSubCategory = (e) => {
this.props.ChangeSubCategory(e.target.value)
this.setState({
...this.state,
dropdown_data: {
...this.state.dropdown_data,
category_id: e.target.value
}
});
axios.get('/api/fetchSubCategory?category_id=' + e.target.value).then(response => {
// console.log(response.data);
this.setState({
...this.state,
SubCategoryData: response.data,
});
});
}
ChangeSubject = (e) => {
this.props.ChangeSubject(e.target.value);
this.setState({
...this.state,
dropdown_data: {
...this.state.dropdown_data,
sub_category_id: e.target.value
}
});
axios.get('/api/fetchSubjects?sub_category_id=' + e.target.value).then(response => {
// console.log(response.data);
this.setState({
...this.state,
subject: response.data
});
});
}
storeData = (e) => {
this.props.storeData(e.target.value);
this.setState({
...this.state,
dropdown_data: {
...this.state.dropdown_data,
subject_id: e.target.value
}
});
}
render() {
console.log(this.state.dropdown_data)
return (
<div className ="row">
<CreateTicket />
</div>
)
}
}
export default CascadingDropdown
and its parent function is,
function CreateTicket(props) {
const [dropdown_data, setDropdown_data] = useState({
subject_id:"", category_id:"", sub_category_id:""
}); // use hooks now
ChangeSubCategory=(category_id)=>{
setDropdown_data({...dropdown_data,category_id})
}
ChangeSubject=(sub_category_id)=>{
setDropdown_data({...dropdown_data,sub_category_id})
}
storeData=(subject_id)=>{
setDropdown_data({...dropdown_data,subject_id})
}
return (
<div className ="container">
<form onSubmit ={handleSubmit}>
<input id="emp_name" type="text" name="employee_name" className ="form-control" disabled = "disabled" onChange = {handleTicketInput} value = {empname} />
<CascadingDropdown dropdown_data={dropdown_data} ChangeSubCategory={ChangeSubCategory} ChangeSubject={ChangeSubject} storeData={storeData}/>
<input id="form_other_subject" type="text" name="other_subject" disabled = "disabled" className ="form-control" value = {ticketInput.other_subject} onChange = {handleTicketInput} />
</form>
</div>
)
}
i hope this will work now,
I have created using reactjs stripe card section and in card section, adding card element and in the checkout form render it and in checkout form pay button is also there but I want to disable the pay button unless response gets from backend?
Here is my code:-
class CheckoutForm extends React.Component {
handleCallback = status => {
if (status === "success") {
message.success("Payment is successfull");
this.props.history.push("/main");
} else {
message.error("Some error occoured");
}
};
handleSubmit = ev => {
ev.preventDefault();
const { userDetails, user, tempPassDate } = this.props;
const { paymentId } = this.props;
this.props.stripe
.createPaymentMethod("card", { billing_details: { name: "Jenny Rosen" } })
.then(({ paymentMethod }) => {
console.log("Received Stripe PaymentMethod:", paymentMethod.id);
this.props.payment(
{
paymentMethodId: paymentMethod.id,
paymentId: paymentId,
},
);
})
.catch(err => console.log(err));
};
render() {
return (
<form onSubmit={this.handleSubmit}>
<CardSection/>
<button>
Pay
</button>
</form>
);
}
}
Manage that in state like:
class CheckoutForm extends React.Component {
constructor(props){
super(props);
this.state = {
disableBtn: false;
}
}
handleCallback = status => {
if (status === "success") {
message.success("Payment is successfull");
this.props.history.push("/main");
} else {
message.error("Some error occoured");
}
};
handleSubmit = ev => {
ev.preventDefault();
this.setState({ disableBtn: true });
const { userDetails, user, tempPassDate } = this.props;
const { paymentId } = this.props;
this.props.stripe
.createPaymentMethod("card", { billing_details: { name: "Jenny Rosen" } })
.then(({ paymentMethod }) => {
console.log("Received Stripe PaymentMethod:", paymentMethod.id);
this.props.payment(
{
paymentMethodId: paymentMethod.id,
paymentId: paymentId,
},
);
this.setState({ disableBtn: false });
})
.catch(err => console.log(err));
};
render() {
return (
<form onSubmit={this.handleSubmit}>
<CardSection/>
<button disabled={this.state.disableBtn}>
Pay
</button>
</form>
);
}
}
I'm trying to develop an app to consume the Marvel API, using React with Axios.
The problem here is that I need it to search in an determined URL when nothing was typed in the input field. But when the user types something, the app should use another URL.
The problem is that the only way I got this working, was setting the componentDidUpdate hook. But it happens to go into an infinity loop. I think this is happening because I'm updating the state directly in this point.
So, is there a best practice to do this? Like configuring Axios to understand this variation, or maybe don't mess around with componentDidUpdate, or even just update the state when the user click the button?
Here's my code:
export default class Main extends Component {
constructor(props) {
super(props);
this.state = {
heroes: [],
search: "",
query: ""
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
componentDidMount() {
this.loadHeroes();
console.log("Query state: ", this.state.query);
}
componentDidUpdate() {
console.log("Query state: ", this.state.query);
}
loadHeroes = async () => {
const PUBLIC_KEY = process.env.REACT_APP_PUBLIC;
const PRIVATE_KEY = process.env.REACT_APP_PRIVATE;
const timestamp = Number(new Date());
const hash = md5.create();
hash.update(timestamp + PRIVATE_KEY + PUBLIC_KEY);
if (this.state.query === "") {
await api
.get(`/characters?ts=${timestamp}&apikey=${PUBLIC_KEY}&hash=${hash}`)
.then(response =>
this.setState({ heroes: response.data.data.results })
);
} else {
await api
.get(
`/characters?nameStartsWith=${this.state.query}&ts=${timestamp}&apikey=${PUBLIC_KEY}&hash=${hash}`
)
.then(response =>
this.setState({ heroes: response.data.data.results })
);
}
};
handleChange(e) {
this.setState({ search: e.target.value });
console.log(e.target.value);
}
handleSubmit(e) {
console.log("Query state updated: ", this.state.search);
e.preventDefault();
this.setState({ query: e.target.value });
}
render() {
const { heroes } = this.state;
let filteredHeroes = heroes.filter(
hero => hero.name.toLowerCase().indexOf(this.state.search) !== -1
);
return (
<div>
<Navbar></Navbar>
<form onSubmit={this.handleSubmit}>
<input
onChange={this.handleChange}
type="text"
value={this.state.search}
/>
<input type="submit" value="Submit" />
</form>
<Wrapper>
{filteredHeroes.map(hero => {
return (
<Card key={hero.id} name={hero.name} thumbnail={hero.thumbnail} />
);
})}
</Wrapper>
</div>
);
}
}
Issue with this:
componentDidUpdate() {
this.loadHeroes();
}
is that loadHeroes() will change state and that will call componentDidUpdate again. Which will load heroes and change state :). Forever.
You probably want to re-loadHeroes() only and only if there are changes in state.query. To do that use componentDidUpdate's parameter prevState:
componentDidUpdate(prevProps, prevState) {
if (prevState.query != this.state.query) {
this.loadHeroes();
}
}
https://reactjs.org/docs/react-component.html#componentdidupdate
I want to know about dispatch function and mapDispatchToProps function.How they work and when to use.Any guideline for them?
I am currently working on a MERN stack project where i need to post a name on mongoose.I successfully post on database but after posting i also want to send it to redux store via dispatching an action with data.But I am getting dispatch is not a function error.Why I an geting this error.I have stated const {dispatch} = props in constructor function
Here is my about.js page code
import React, { Component } from 'react';
import fetch from 'isomorphic-unfetch'
import { connect } from 'react-redux'
import {addName} from '../Actions/actionCreators'
class about extends Component {
static async getInitialProps({ req }){
try{
const protocol = req.headers['x-forwarded-proto'] || 'http'
const baseUrl = req ? `${protocol}://${req.headers.host}` : ''
const url = `${baseUrl}/api/users`
return { apiUrl: url }
}catch{
return { error: 'Could not load configs'}
}
}
constructor(props){
super(props)
const {dispatch} = props
this.state = { name: '' }
this.addname = this.addname.bind(this)
}
addname(e){
e.preventDefault()
const {dispatch} = this.props
const name = e.target.name.value
const newName = {
name : name
}
fetch(this.props.apiUrl, {
method: 'POST',
body: JSON.stringify(newName),
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
})
.then( r =>
r.json()
)
.then( (data) => dispatch(addName(data.name)) )
.catch(err => console.error('POST error', err));
}
render() {
const markup = this.props.name.name.length > 0 ? this.props.name.name.map((elem, i) => (
<div key={i}>
{this.props.name.name[i]}
</div>
)) : <p></p>
return (
<div>
<h2> About me </h2>
{markup}
<form action="" onSubmit={this.addname}>
<br/>
<input type="text" name="name" placeholder="Your Name" />
<br/>
<input type="submit" value="Submit"/>
</form>
</div>
);
}
}
const mapDispatchToProps = dispatch => {
return{
submitform : (e) => {
e.preventDefault()
dispatch(addName(e.target.name.value))
}
}
}
const mapStateToProps = state => {
return{
name : state.name
}
}
export default connect(mapStateToProps, mapDispatchToProps)(about)
You can notice <form action="" onSubmit={this.addname}> here addName is a function which posts the name to databse.
You can also submitform in
const mapDispatchToProps = dispatch => {
return{
submitform : (e) => {
e.preventDefault()
dispatch(addName(e.target.name.value))
}
}
}
this submitform submits directly to redux-state.but i want to submit first to DB and then redux-state
Since you are using mapDispatchToProps you won't have dispatch available as prop to the component. The idea way would be to expose addName from mapDispatchToProps
class about extends Component {
static async getInitialProps({ req }){
try{
const protocol = req.headers['x-forwarded-proto'] || 'http'
const baseUrl = req ? `${protocol}://${req.headers.host}` : ''
const url = `${baseUrl}/api/users`
return { apiUrl: url }
}catch{
return { error: 'Could not load configs'}
}
}
constructor(props){
super(props)
const {dispatch} = props
this.state = { name: '' }
this.addname = this.addname.bind(this)
}
addname(e){
e.preventDefault()
const {addName} = this.props
const name = e.target.name.value
const newName = {
name : name
}
fetch(this.props.apiUrl, {
method: 'POST',
body: JSON.stringify(newName),
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
})
.then( r =>
r.json()
)
.then( (data) => addName(data.name) )
.catch(err => console.error('POST error', err));
}
render() {
const markup = this.props.name.name.length > 0 ? this.props.name.name.map((elem, i) => (
<div key={i}>
{this.props.name.name[i]}
</div>
)) : <p></p>
return (
<div>
<h2> About me </h2>
{markup}
<form action="" onSubmit={this.addname}>
<br/>
<input type="text" name="name" placeholder="Your Name" />
<br/>
<input type="submit" value="Submit"/>
</form>
</div>
);
}
}
const mapDispatchToProps = dispatch => {
return{
submitform : (e) => {
e.preventDefault()
dispatch(addName(e.target.name.value))
},
addName: (name) => {
dispatch(addName(name))
}
}
}
I try to do weather app in react, but when I add ${this.state.latitude} in my const API I replaced null.
But when I try display this.state.latitude in render() I have a value.
What is wrong?
export class TodayWeather extends React.Component {
constructor(props) {
super(props);
this.state = {
latitude: "",
longitude: "",
};
}
getMyLocation =() => {
const location = navigator.geolocation;
if (location) {
location.getCurrentPosition((position) => {
this.setState({
latitude: position.coords.latitude,
longitude: position.coords.longitude,
})
},)}
};
getWeather = () => {
this.getMyLocation();
const API = `http://api.openweathermap.org/data/2.5/forecast?lat=${this.state.latitude}&lon=139&appid=${apiKey}`;
fetch(API)
.then(response => {
if (response.ok) {
return response
}
throw Error("")
})
.then(response => response.json())
.then(data => {
const time = new Date().toLocaleString();
this.setState({
})
})})
};
componentDidMount() {
this.getWeather();
}
render(){
return (
<div className="App">
<Result className="result" weather={this.state}/>
<p> {this.state.latitude} </p>
</div>
);
}
}
The expected order of execution is:
this.getMyLocation() which sets the latitude and longitude to state.
this.getWeather() which uses the state variable to make a xhr request (which is again async).
this.setState is also asynchronous. So by the time the state variables are set, this.getWeather() already starts executing, so it comes back null and the fetch request fails. So when the state variable is set, it triggers a rerender, which is why it does come in the render.
The solution to this is using a callback in the setState. I have made some minor modifications.
I called this.getMyLocation() on componentDidMount:
componentDidMount() {
this.getMyLocation();
}
In which I make use of the callback and invoke the modified this.getWeather:
this.setState(
{
latitude: position.coords.latitude,
longitude: position.coords.longitude
},
this.getWeather
);
Where it no longer invokes this.getMyLocation() at its start.
Besides this, one obvious flaw is that you are not passing anything to the setState after the fetch is done, presumably the json data you obtain.
.then((data) => {
const time = new Date().toLocaleString();
this.setState({
// Something needs to come here, possibly:
data
});
});
The full code:
export default class TodayWeather extends Component {
constructor(props) {
super(props);
this.state = {
latitude: '',
longitude: ''
};
}
getMyLocation = () => {
const location = navigator.geolocation;
if (location) {
location.getCurrentPosition((position) => {
this.setState(
{
latitude: position.coords.latitude,
longitude: position.coords.longitude
},
this.getWeather
);
});
}
};
getWeather = () => {
const API = `http://api.openweathermap.org/data/2.5/forecast?lat=${
this.state.latitude
}&lon=139&appid=${apiKey}`;
fetch(API)
.then((response) => {
if (response.ok) {
return response;
}
throw Error('');
})
.then((response) => response.json())
.then((data) => {
const time = new Date().toLocaleString();
this.setState({
// Something needs to come here
data
});
});
};
componentDidMount() {
this.getMyLocation();
}
render() {
return (
<div className="App">
<Result className="result" weather={this.state} />
<p> {this.state.latitude} </p>
</div>
);
}
}
try this.. but the code looks very messy
export default class TodayWeather extends React.Component {
constructor(props) {
super(props);
this.state = {
latitude: '',
longitude: ''
};
}
getMyLocation = (getData) => {
const location = navigator.geolocation;
if (location) {
location.getCurrentPosition((position) => {
getData(position);
});
}
};
getWeather = () => {
const getData = (position) => {
this.setState({
latitude: position.coords.latitude,
longitude: position.coords.longitude
});
const API = `http://api.openweathermap.org/data/2.5/forecast?lat=${
position.coords.latitude
}&lon=139&appid=${apiKey}`;
fetch(API)
.then((response) => {
if (response.ok) {
return response;
}
throw Error('');
})
.then((response) => response.json())
.then((data) => {
const time = new Date().toLocaleString();
this.setState({ time });
});
};
this.getMyLocation(getData);
};
componentDidMount() {
this.getWeather();
}
render() {
return (
<div className="App">
<Result className="result" weather={this.state} />
<p> {this.state.latitude} </p>
</div>
);
}
}