Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting URL Parameters on GatsbyJS

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>
    )
  }
}
like image 614
Lex Avatar asked Dec 16 '18 07:12

Lex


People also ask

How do you get params from URL in Great Gatsby?

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.

How do I find the parameter of a URL?

For getting the URL parameters, there are 2 ways: By using the URLSearchParams Object. By using Separating and accessing each parameter pair.

Can you use Javascript to get URL parameter values?

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.


2 Answers

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 ...
}
like image 151
pungggi Avatar answered Oct 23 '22 10:10

pungggi


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&parameter2=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);
  // ...
like image 20
EliteRaceElephant Avatar answered Oct 23 '22 10:10

EliteRaceElephant