Is there a way to retrieve url parameters passed on pages of project built on GatsbyJS? I'm trying to implement a password reset function on my page using AWS, but they can only send the parameters through a link sent to the user's email.
So the flow would be like this :
User triggers Forgot Password -> AWS sends email to user with link -> Link directs to my page with the parameters -> Reset password form automatically populates fields with the parameters passed
Update
Here's my App.js code :
import { Router } from "@reach/router"
const App = () => (
<Layout>
<Router>
<Login path="signin" exact component={Login} />
<Resources path="api/resources" exact component={Resources} />
<Verify path="verify" exact component={Verify} />
<Forgot path="forgot" exact component={Forgot} />
<Reset path="account/reset/:code" exact component={Reset}/>
</Router>
</Layout>
)
export default App;
Reset.js :
export default class ResetForm extends Component {
constructor(props) {
super(props);
this.state = {
password: "",
confirmPassword: "",
vercode: "",
email: "",
emailValid: false,
passValid: false,
confirmValid: false,
codeValid: false,
formValid: true,
formErrors : {
email: false,
password: false,
confirmPassword: false,
vercode: false,
},
respErrors : {
email: {
isValid : true,
message : ""
},
password: {
isValid : true,
message : ""
},
code : {
isValid : true,
message : ""
}
}
};
}
validateField(field, value) {
let password = this.state.password
let fieldValidationErrors = this.state.formErrors;
let emailValid = this.state.emailValid
let passValid = this.state.passValid
let confirmValid = this.state.confirmValid
let codeValid = this.state.vercode
let fieldValidationMessages = this.state.respErrors;
switch(field){
case 'email' :
emailValid = validator.isEmail(value);
fieldValidationErrors.email = emailValid ? false : true;
fieldValidationMessages.email.isValid = true;
fieldValidationMessages.email.message = "Invalid E-Mail Address";
break;
case 'password' :
passValid = validator.matches(value, RegExp('^(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%^&*])(?=.{8,})'));
fieldValidationMessages.password.message = passValid ? '' : undefined;
if(!validator.matches(value,RegExp('^(?=.*[a-z])(?=.*[A-Z])'))){
fieldValidationMessages.password.message = "At least 1 Upper case character is required";
}
if(!validator.matches(value,RegExp('^(?=.*[!@#$%^&*])'))){
fieldValidationMessages.password.message = "At least 1 Symbol is required";
}
if(!validator.matches(value,RegExp('^(?=.{8,})'))){
fieldValidationMessages.password.message = "Password must have at least 8 characters";
}
fieldValidationErrors.password = passValid ? false : true;
break;
case 'confirmPassword' :
confirmValid = validator.equals(value, password);
fieldValidationErrors.confirmPassword = confirmValid ? false : true;
break;
case 'vercode' :
codeValid = !validator.isEmpty(value);
fieldValidationErrors.vercode = codeValid ? false : true;
break;
default :
break
}
this.setState({
formErrors: fieldValidationErrors,
emailValid: emailValid,
passValid: passValid,
confirmValid: confirmValid,
codeValid: codeValid,
}, this.validateForm())
}
validateForm(){
this.setState({
formValid:
this.state.emailValid && this.state.confirmValid && this.state.codeValid && this.state.passValid
})
}
handleChange = event => {
const name = event.target.id;
const value = event.target.value;
this.setState({
[name]: value
},
() => {
this.validateField(name, value)
}
);
}
handleSubmit = async (event) => {
event.preventDefault()
const state = this.state
await handleReset(state)
.then(async (data) => {
if(data.isValid){
await handleLogin(state)
.then(() => {
navigate('/')
})
.catch(err => console.log(err))
} else {
switch (data.code) {
case CODE_RESET.RESET_EXPIRED:
data.message = "The verification code you have submitted is already expired."
break
case CODE_RESET.RESET_MISMATCH:
data.message = "The verification code you have submitted is invalid."
break
default:
data.message = "Something went wrong."
break;
}
this.setState({
[state.respErrors.code.isValid] : data.isValid,
[state.respErrors.code.message] : data.message
})
}
})
.catch(async(err) => {
console.log(err)
})
}
render() {
if(isLoggedIn()) {
navigate(`/`)
}
return (
<Row className={[formStyles.formContainer, "row"].join(' ')} >
<Col sm={{
size:12
}}
md={{
size: 8,
offset: 2
}}
>
<Form
onSubmit={this.handleSubmit}
>
<h3 style={{
fontWeight: 'bolder'
}}>
Reset Password
</h3>
<FormGroup>
<Label for="email">Email</Label>
<Input
id="email"
autoFocus
type="email"
name="email"
value={this.state.email.value}
onChange={this.handleChange}
className={formStyles.signUp}
valid={this.state.emailValid}
invalid={(this.state.formErrors.email || !this.state.respErrors.email.isValid ) ? true : undefined}
/>
<FormFeedback invalid={this.state.respErrors.email.isValid ? '' : undefined}>
{this.state.respErrors.email.message}
</FormFeedback>
</FormGroup>
<FormGroup>
<Label for="password">New Password</Label>
<Input
id="password"
type="password"
name="password"
value={this.state.password.value}
onChange={this.handleChange}
className={formStyles.signUp}
valid={this.state.passValid }
invalid={this.state.formErrors.password ? true : undefined}
/>
<FormText invalid={this.state.respErrors.password.isValid ? '' : undefined}>
{this.state.respErrors.password.message}
</FormText>
</FormGroup>
<FormGroup>
<Label for="confirmPassword">Confirm Password</Label>
<Input
id="confirmPassword"
type="password"
name="confirmPassword"
value={this.state.confirmPassword.value}
onChange={this.handleChange}
className={formStyles.signUp}
valid={this.state.confirmValid }
invalid={this.state.formErrors.confirmPassword ? true : undefined}
/>
<FormFeedback
invalid={this.state.formErrors.confirmPassword ? '' : undefined}
>
Password does not match
</FormFeedback>
</FormGroup>
<FormGroup>
<Label for="vercode">Verification Code</Label>
<Input
id="vercode"
type="text"
name="vercode"
maxLength={6}
value={this.state.vercode.value}
onChange={this.handleChange}
className={formStyles.signUp}
valid={this.state.codeValid.value }
invalid={this.state.formErrors.vercode || !this.state.respErrors.code.isValid ? true : undefined}
/>
<FormFeedback invalid={this.state.respErrors.code.isValid ? '' : undefined} >
{this.state.respErrors.code.message}
</FormFeedback>
</FormGroup>
<Button
color="primary"
disabled={!this.state.formValid}
>
Submit
</Button>
</Form>
</Col>
</Row>
)
}
}
Now in order to get access to the url query parameters, you need react-router-dom package and a gatsby specific plugin by the name of gatsby-plugin-use-query-params. Great now always remember whenever you install a plugin and intend to use it, you always have to add it to the plugins array in gatsby-config.
For getting the URL parameters, there are 2 ways: By using the URLSearchParams Object. By using Separating and accessing each parameter pair.
The short answer is yes Javascript can parse URL parameter values. You can do this by leveraging URL Parameters to: Pass values from one page to another using the Javascript Get Method. Pass custom values to Google Analytics using the Google Tag Manager URL Variable which works the same as using a Javascript function.
Use props.location
, introduced in Gatsby v2. It's made available by @reach/router to all components via props
.
function Component(props) {
// use props.location...
return ...
}
Use URLSearchParams.get()
as described on MDN:
// Get the location object that is implicitly passed as props
// for every page in the `pages` folder
const Index = ({ location }) => {
console.log(location); // inspect location for yourself
// the parameter to return for URL. Example:
// https://localhost:8000/?parameter1=firstParam¶meter2=secondParam
const params = new URLSearchParams(location.search);
const parameter1 = params.get("parameter1");
const parameter2 = params.get("parameter2");
console.log(parameter1); // -> "firstParam"
console.log(parameter2); // -> "secondParam"
// ...
Alternative: package query-string
yarn add query-string
or npm i --save query-string
import * as queryString from "query-string";
// Get the location object that is implicitly passed as props
// for every page in the `pages` folder
const Index = ({ location }) => {
console.log(location); // inspect location for yourself
// query-string parses the parameters that are contained in the location object
const { parameter1, parameter2 } = queryString.parse(location.search);
console.log(parameter1);
console.log(parameter2);
// ...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With