Problem with fetching API with user input - reactjs

I'm building a search form where you can search for a city/country. I'm getting a response, but it adds localhost to the url
http://localhost:3000/api.geonames.org/searchJSON?q=london&username=username
Which it shouldn't do... What I'm I doing wrong?
state = {
text: ""
}
handleChange = (e) => {
this.setState({
[e.target.name]: e.target.value
})
}
componentDidMount() {
const endpoint = `${api}q=${this.state.text}&username=${userName}`
console.log(endpoint)
fetch(endpoint)
.then(res => {
console.log(res)
})
}
handleSubmit = (e) => {
e.preventDefault()
this.setState({text: ""})
this.componentDidMount()
}
render() {
return (
<div>
<h1>CityPop</h1>
<form onSubmit={this.handleSubmit}>
<h3>Search by city</h3>
<input
type="search"
name="text"
value={this.state.text}
onChange={this.handleChange}
/>
<button>Search city</button>
</form>
</div>
)
}

Just add http/https protocol before the link:
const endpoint = `https://${api}q=${this.state.text}&username=${userName}`;

Related

Form automatically submitting, why is preventDefault() not working

I recently created a link shortening application in react. I have a problem with the form automatically submitting when I enter a link, I have preventDefault() as you can see in the code and onSubmit in the form element.
const onSubmit = (e) => {
e.preventDefault();
return false;
}
if (!text){
} else {
const shortenLink = async () => {
const res = await fetch(`https://api.shrtco.de/v2/shorten?url=${text}`)
const data = await res.json()
console.log(data.result);
setLinks(data.result)
setText('')
}
shortenLink()
}
const copy = () => {
navigator.clipboard.writeText(links.full_short_link)
setButtonText('Copied!')
}
return (
<>
<Container>
<StyledInput onSubmit={onSubmit}>
<InputContainer>
<Input type="url" value={text} onChange={(e) => setText(e.target.value)} placeholder="Shorten link here..." required />
<ButtonTwo onClick={onSubmit} type="submit" bg="#666AF6" color="#fff">Shorten It!</ButtonTwo>
</InputContainer>
</StyledInput>

400 bad request during axios call

Not sure why but the POST request is coming back 400. Postman says my django backend is doing fine. It all happens at the post_flashcards method any help would be great and I am willing to show any other code as requested. although there shouldnt be the need to since this component acts mostly on its own.
class CreateFlashCard extends Component {
constructor(props) {
super(props);
this.state = {
title: '',
collection_id: '',
term: '',
definition: '',
}
this.handleSubmit = this.handleSubmit.bind(this)
}
onChange = (e) => {
this.setState({[e.target.name]: e.target.value});
}
handleSubmit(e) {
e.preventDefault();
this.post_flashcard()
}
async post_flashcard() {
const card = this.state;
const col_id = parseInt(this.state.collection_id)
try{
await axios.post(`http://127.0.0.1:8000/flashcardsapp/${col_id}`, card)
.then(response => console.log(response.status))
}catch(er){
console.log('ERROR in post_flashcard', er)
}
}
render() {
const {title, collection_id, term, definition} = this.state
return (
<form onSubmit={this.handleSubmit}>
<h2>Create a Card</h2>
<label for="title">Enter Collection Title</label>
<input type="text" name="title" value={title} onChange={this.onChange} ></input>
<label for="collection_id">Enter Collection ID</label>
<input type="number" name="collection_id" value={collection_id} onChange={this.onChange} ></input>
<label for="term">Enter Term</label>
<input type="text" name="term" value={term} onChange={this.onChange} ></input>
<label for="definition">Enter Definition</label>
<input type="text" name="definition" value={definition} onChange={this.onChange} ></input>
<input type="submit"></input>
</form>
);
}
}
export default CreateFlashCard;
If you are doing post processing, you can convert the Data to Json format and send it.
var post_data = {
your_post_name: this.state
};
axios
.post(url, JSON.stringify(post_data))
.then((response) => {
console.log(response);
})
.catch((error) => {
console.log(error);
});
or
axios
.post(url,JSON.stringify({your_post_name:this.state}))
.then((response) => {
console.log(response);
})
.catch((error) => {
console.log(error);
});
I solved the issue state had typo in title needed to be collection_title.

How to stop the page from refreshing and from loosing the users input on an unssucceful post request

I am working on a Merin Stack where a user can make a comment on a Program, and i am also using Google-react-Recaptcha to prevent spamming.
Everything is working well, except when a user forgets to declare that they are not a robot(to check the Recaptcha box) and the post request becomes unsuccessful. what happens is that the input that the user typed clears and it seems that the page is refreshing on a failed post request.
How do I make the user's inputs not clear from the field on a failed post request?
Here is my onSubmit function
const [error, setError] = useState("");
const [token, setToken] = useState("");
const reCaptcha = useRef();
const onSubmit = useCallback((e) => {
if (!token) {
alert("Yoou must verify the captcha");
setError("Yoou must verify the captcha");
}
setError("");
e.preventDefault();
setName("");
setDescription("");
axios
.post(
"http://localhost:9000/programs/" +
props.match.params.id +
"/programcomment",
{ name: name, description: eventDescription, token }
)
.then(function (response) {
onPageLoad();
alert("Submitted Succefully");
})
.catch(function (err) {
setError(err);
console.log(err);
})
.finally(() => {
reCaptcha.current.reset();
setToken("");
});
});
and my form inputs
<div className="container">
<div className="row " />
<div className="col-sm-2"></div>
<div className="col-sm-10"></div>
<div className="row">
<div className="col-sm-2" />
<div className="col-sm-10">
<form className="form" onSubmit={onSubmit}>
<div className="form-group">
<label htmlFor="name">Name:</label>
<input
type="text"
className="form-control"
id="name"
value={name}
required
onChange={handleChange("name")}
/>
<br />
<label htmlFor="comment">Comment:</label>
<textarea
className="form-control"
rows={5}
id="comment"
required
defaultValue={""}
value={eventDescription}
onChange={handleChange("description")}
/>
<br />
</div>
<ReCAPTCHA
ref={reCaptcha}
sitekey="6LecT-sZgfgrrtrtrtrtqQuMSJnMbxrif0ArqJqk2"
onChange={(token) => setToken(token)}
onExpired={(e) => setToken("")}
/>
<button
type="submit"
id="myBtn"
class="btn btn-success"
// onClick={handleSubscribe}
>
Submit
</button>
</form>
<p id="warning" />
</div>
</div>
Use an else section and move preventdefault to beginning.
const onSubmit = useCallback((e) => {
e.preventDefault();
if (!token) {
alert("Yoou must verify the captcha");
setError("Yoou must verify the captcha");
}
else{
setError("");
setName("");
setDescription("");
axios
.post(
"http://localhost:9000/programs/" +
props.match.params.id +
"/programcomment",
{ name: name, description: eventDescription, token }
)
.then(function (response) {
onPageLoad();
alert("Submitted Succefully");
})
.catch(function (err) {
setError(err);
console.log(err);
})
.finally(() => {
reCaptcha.current.reset();
setToken("");
});
}
});
Add e.preventDefault(); to your onSubmit callback and wrap to else block code which is invoked after checking token:
const onSubmit = useCallback((e) => {
e.preventDefault();
if (!token) {
alert("Yoou must verify the captcha");
setError("Yoou must verify the captcha");
} else {
setError("");
e.preventDefault();
setName("");
setDescription("");
axios
.post(
"http://localhost:9000/programs/" +
props.match.params.id +
"/programcomment",
{ name: name, description: eventDescription, token }
)
.then(function (response) {
onPageLoad();
alert("Submitted Succefully");
})
.catch(function (err) {
setError(err);
console.log(err);
})
.finally(() => {
reCaptcha.current.reset();
setToken("");
});
}
});
Use e.preventDefault at the beginning of your onSubmit function maybe ?
const onSubmit = useCallback((e) => {
e.preventDefault();

Redirection to dashboard after login in react

I have a login page, and I want to redirect users to dashboard after the details are filled.
I have tried using history.push and redirect components but I couldn't redirect.
Login Page
class Login extends React.Component {
state = {
email: '',
password: '',
errors: {},
redirect: false
}
validateForm = () => {
let errors = {};
let formIsValid = true;
if(!this.state.email) {
formIsValid = false;
errors['email'] = 'Please enter email to continue';
}
if(!this.state.password) {
formIsValid = false;
errors['password'] = 'Please enter password to continue';
}
this.setState({
errors: errors
})
return formIsValid;
}
handleChange = (event) => {
this.setState({
[event.target.id]: event.target.value
});
}
handleSubmit = (event) => {
event.preventDefault();
// console.log(this.state);
if(this.validateForm()) {
const loginData = {
email: this.state.email,
password: this.state.password
}
axios
.post('/users.json', loginData)
.then(response => {
console.log(response.data);
})
.catch(error => {
console.log(error);
})
}
}
render() {
return (
<div className="container">
<form onSubmit={this.handleSubmit} className="white">
<h5 className="grey-text text-darken-3">Login</h5>
<div className="input-field">
<label htmlFor="email">Email</label>
<input type="email" id="email" onChange={this.handleChange} />
<p>{this.state.errors.email}</p>
</div>
<div className="input-field">
<label htmlFor="password">Password</label>
<input type="password" id="password" onChange={this.handleChange} />
<p>{this.state.errors.password}</p>
</div>
<div className="input-field">
<button onClick={this.redirectHandler} className="btn btn-primary">Login</button>
</div>
</form>
</div>
)
}
}
export default Login;
I want to redirect to other page once the form is submitted with the email and password.
I've been trying this for days but I couldn't find a solution.
import { withRouter } from 'react-router';
class Login extends React.Component {
state = {
email: '',
password: '',
errors: {},
redirect: false
}
validateForm = () => {
let errors = {};
let formIsValid = true;
if(!this.state.email) {
formIsValid = false;
errors['email'] = 'Please enter email to continue';
}
if(!this.state.password) {
formIsValid = false;
errors['password'] = 'Please enter password to continue';
}
this.setState({
errors: errors
})
return formIsValid;
}
handleChange = (event) => {
this.setState({
[event.target.id]: event.target.value
});
}
handleSubmit = (event) => {
event.preventDefault();
// console.log(this.state);
if(this.validateForm()) {
const loginData = {
email: this.state.email,
password: this.state.password
}
axios
.post('/users.json', loginData)
.then(response => {
this.props.history.push("/dashboard");
console.log(response.data);
})
.catch(error => {
console.log(error);
})
}
}
render() {
return (
<div className="container">
<form onSubmit={this.handleSubmit} className="white">
<h5 className="grey-text text-darken-3">Login</h5>
<div className="input-field">
<label htmlFor="email">Email</label>
<input type="email" id="email" onChange={this.handleChange} />
<p>{this.state.errors.email}</p>
</div>
<div className="input-field">
<label htmlFor="password">Password</label>
<input type="password" id="password" onChange={this.handleChange} />
<p>{this.state.errors.password}</p>
</div>
<div className="input-field">
<button onClick={this.redirectHandler} className="btn btn-primary">Login</button>
</div>
</form>
</div>
)
}
}
export default withRouter(Login);
have some complain about your code.
first: for form validation and handling you dont need to use state,
there is a library called Formik which will help you a lot with
this.
second: if you are using redux to check user is logged in or
not you need to create a private route for routes which cannot be
accessible for public like here dashboard component.
third: to use history you need to wrap your
component inside withRouter HOC which will pass route props to your
component so you can use history or if your are using functional component you can use useHistory() hook.

Form data being deleted after React-Recaptcha is clicked

I am using react-recaptcha on a form on my site. Everything works fine, but when I click the recaptcha, when it returns success, all the form data is deleted. I can of course re-enter it, but that's a terrible UI. Why is it being deleted, and how can I prevent it? Thanks.
Script tag in my index.html file:
<script src="https://www.google.com/recaptcha/api.js?render=explicit" async defer></script>
Component
const RequestADemo = () => {
const [values, setValues] = useState({
recaptcha_verified: false
});
const handleSubmit = (e) => {
if (e) { e.preventDefault() };
if (values.recaptcha_verified) {
requestdemo();
}
};
const handleChange = (e) => {
e.persist();
setValues((values) => ({ ...values, [e.target.name]: e.target.value }));
};
const requestdemo = () => {
let firstname = values.firstname;
fetch("/requestdemo", {
method: "POST",
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({ firstname })
})
.then((res) => res.json())
.then((json) => {
console.log("success");
})
.catch((err) => { console.log("err : ", err) });
}
const recaptchaVerified = (response) => {
setValues({...values, recaptcha_verified: true });
}
return (
<div>
<form onSubmit={ handleSubmit }>
<div className="field">
<label className="label">First Name</label>
<div className="control">
<Input className="input" type="text" name="firstname" onChange={ handleChange } value={ values.firstname || "" } required />
</div>
</div>
<Recaptcha
sitekey="6Lxxxxxxxxxxxxxx"
render="explicit"
verifyCallback={recaptchaVerified}
/>
<button type="submit" className="button is-block is-info is-fullwidth">Submit</button>
</form>
</div>
);
};
export default RequestADemo;

Resources