-2

I have an Ooth authentication server with PassportJS, a GraphQL API and a Gatsby client, I want to get my error messages in a bootstrap alert when my handleLogin function returns the catch, how can I do that?

auth.js

export const handleLogin = async ({ email, password }) => {
    const user = await ooth.authenticate('local', 'login', {
        username: email,
        password: password,
    }).catch(e => { 
        console.log(e)
     });
    await navigate(`/app/profile`);
    if (user) {
        return setUser({
            id: user._id,
            username: `jovaan`,
            name: `Jovan`,
            email: user.local.email,
            avatar: `3`,
            telephone: `0788962157`,
            bio: `I'm a front-end dev`
        })
    }
    return false
}

Alert.js

import React from "react";
import { Alert } from "shards-react";

export default class DismissibleAlert extends React.Component {
  constructor(props) {
    super(props);
    this.dismiss = this.dismiss.bind(this);
    this.state = { visible: true, message: "Message par défaut" };

  }

  render() {
    return (
      <Alert dismissible={this.dismiss} open={this.state.visible} theme="success">
        {this.message()}
      </Alert>
    );
  }

  dismiss() {
    this.setState({ visible: false });
  }

  message() {
      return this.state.message
  }
}
Jovan
  • 51
  • 1
  • 4

2 Answers2

1

In your api, you can send a return a response with a 401 status code along with a JSON string. In express:

.catch(e => {
  res.status(401).json({ message: 'Login Failed!' /*or e if you want that*/ });
})

Now from your react application, you can set the message state in the catch block of your api request.

Rohit Kashyap
  • 1,553
  • 1
  • 10
  • 16
  • In fact, I can get my errors in console.log(e.message) but I want to get them back in my Alert component to display it on my Login page – Jovan Jul 02 '19 at 12:24
  • In your catch blog inside the handleLogin function inside your component, you can set your state to e.message or whatever you are sending through the api. – Rohit Kashyap Jul 02 '19 at 12:30
  • My mistake, I assumed the login function was inside the the same file as the component. You still need to send the response from your backend and pass it as a prop to your Alert component. After that use a lifecycle method to determine if the alert should be displayed or not as suggested by @Medunoye's answer. – Rohit Kashyap Jul 02 '19 at 13:23
1

Why not send a prop to the Alert component?

In your auth.js error handler,

<DismissibleAlert visible={true} />

in your Alert.js add

componentWillReceiveProps(nextProps) {
  // You don't have to do this check first, but it can help prevent an unnecessary render
  if (nextProps.visible !== this.state.visible) {
    this.setState({ visible: nextProps.visible });
  }
}

There are a lot you can do to optimise your code. You can read the article below.

https://medium.com/@ruthmpardee/passing-data-between-react-components-103ad82ebd17

** Update

After looking at your code, Im just going to focus on showing the alert.

first, remove await navigate(/app/profile); from your auth.js.

then in your login.js do this

handleSubmit = event => {
    event.preventDefault()
    if(!handleLogin(this.state)){
       this.setState({showErrorModal: true, modalMessage: "unable to login"});
    }
    /* rest of code, like navigating the user out */ 
}

DismissibleAlert in your render() would be <DismissibleAlert visible={this.state.showErrorModal} message={this.state.modalMessage} />.

the rest would be as stated above.

to help: your alert.js

export default class DismissibleAlert extends React.Component {
  ...

  componentWillReceiveProps(nextProps) {
    // You don't have to do this check first, but it can help prevent an unnecessary render
    if (nextProps.visible !== this.state.visible) {
      this.setState({ visible: nextProps.visible });
    }
  }
}

I suggest you read this too React component initialize state from props

  • visible it's okay, but I want receive error message from auth.js to Alert component... – Jovan Jul 02 '19 at 14:29
  • first of, is that all of auth.js? second, since you are using async/await, wrap it in a try catch block try{/*body*/}catch(e){ console.log(e); /* call dismissable alert */ } – Medunoye Laxus Gbenga Jul 02 '19 at 14:43