2

This is my component that represents the Login page

import { HttpService } from 'src/assets/js/httpservice';
// ** omissis other imports **

export default class PrivatePage extends React.Component {
    constructor(props) {
        super(props);
    }

    public render() {
        return (
            <div>
                <ul>
                    <li>
                        <InputText name="Text" id="Text" />
                    </li>
                    <li>
                        <InputText name="Email" id="Email" />
                    </li>
                    <li>
                        <Button onClick={this.send} label="Send ticket" />
                    </li>
                </ul>
            </div>
        )
    }

    private send() {
        HttpService.post(PATH.sendTicket, this.state.ticketModel).then(data => {
            if (data.ErrorCode === 0) {
                this.setState({
                    sentSuccessfull: true
                });
            }
            else {
                // show an error popup
            }
        });
    }
}

When the "Send ticket" button is pressed, it calls the HttpService.post method to make an API call to send a ticket to the system. As you can see in the import section, the HttpService is hosted on an external JS file. This is the code of the HttpService.post method.

public static async post(path, body) {

    return window.fetch(path, {
        body: JSON.stringify(body),
        cache: "no-cache",
        method: "post"
    })
        .then(data => {
            // call successfull
        })
        .catch(data => {
            if (data.status === 401) {
                // REDIRECT HERE
            }
            else {
                return data.json();
            }
        });
}

Now, if the API call fails because the user is not authenticated (HTTP status 401 is returned), I need to redirect the user to the Login page. I would avoid to handle the 401 HTTP status in every component, so I prefer that the redirect is made directly inside the HttpService.post method.

Matteo
  • 233
  • 3
  • 18
  • Is it duplicate of https://stackoverflow.com/questions/2604530/a-good-way-to-redirect-with-a-post-request? – unknown_boundaries Dec 05 '18 at 17:43
  • No, the question in the linked post is completely different from my question. – Matteo Dec 05 '18 at 21:12
  • is there a reason why you wont redirect on the client side in the private send functions else block? where you would be showing an error popup. You could have a close button on the error popup that fired a redirect for example. – Lloyd Dec 06 '18 at 07:46
  • @Lloyd I prefer that the redirect is made programmatically without any user interaction. – Matteo Dec 06 '18 at 09:24
  • well you can still redirect programmatically on the client side, if you throw an error inside your catch block server side, then add a catch block client side with redirect. Before i answer just wanted to make sure if there was some other reason you didn't want it on the client side, as the end result is the same – Lloyd Dec 06 '18 at 09:32

1 Answers1

0

try the below and let me know if it works for you, change the server side like so:

public static async post(path, body) {

    return window.fetch(path, {
        body: JSON.stringify(body),
        cache: "no-cache",
        method: "post"
        })
        .then(data => {
            // call successfull
        })
        .catch(data => {
            // server side redirect below:
            if (data.status === 401) {
              data.redirect(url, 401)
            }
            else {
            return data.json();
            }
        });
}

And then client side do the following:

     private send() {
     const { history } = this.props 
        HttpService.post(PATH.sendTicket, this.state.ticketModel).then(data => {
            if (data.ErrorCode === 0) {
                this.setState({
                    sentSuccessfull: true
                });
            }
        }).catch(err => {
          hirstory.push('/your-route-here')
        })
      }

Alternatively if you are not using react-router, instead of using history.push you can use

location.href = '/your-route-here'

Or something to that effect, however using location.href method will clear your app state, effectively behaving as if you refreshed the page.

Let me know if this helps

Lloyd

Lloyd
  • 256
  • 1
  • 8
  • I've thought your same solution as a possible solution but if I put it in practice it would mean that I have to handle the 401 HTTP status in every React component doing a redirect. I would instead handle the 401 status globally only one time directly in the `post` method in the httpservice.js file. – Matteo Dec 06 '18 at 10:23
  • ok i will edit with server side solution above, see the catch block in the server side promise. – Lloyd Dec 06 '18 at 11:04