Logout capability

As the user has the option to log in to the application, the user can also log out from it. Inside the Header class, we have already declared the logout button. The only thing pending is to implement the listener inside MainController.

As the MainController class was created by Sencha Cmd, we are reusing it. The file already has some code in it. Let's remove any listener created by Sencha. MainController will look like this:

Ext.define('Packt.view.main.MainController', {
    extend: 'Ext.app.ViewController',

    requires: [
        'Ext.MessageBox'
    ],

    alias: 'controller.main',

    //we will insert code here
});

In the Header class, we declared the logout button, its reference, and its listener. So we need to implement the onLogout function, as follows:

onLogout: function(button, e, options){

    var me = this;      //#1
    Ext.Ajax.request({
        url: 'php/security/logout.php', //#2
        scope: me,                      //#3
        success: 'onLogoutSuccess',     //#4
        failure: 'onLogoutFailure'      //#5
    });
},

The me (#1) variable makes a reference to this, which is the MainController class. We will make an Ajax call (#2) to php/security/logout.php (we will create this file soon). We will handle the success (#4) and failure (#5) callbacks in separate functions that are declared inside the MainController class as well. That is why the scope is set to the MainController class (#3) itself.

Tip

We could declare the success and failure callbacks directly inside the Ajax request. But then, our code will be very long, which would decrease its readability. This way, the code stays organized and easier to read. This is always a best practice to be followed.

Handling the logout on the server

To handle the logout capability on the server, we will create a new PHP page named logout.php under the php/security folder. The code is very simple:

<?php

session_start(); // #1

$_SESSION = array(); // #2

session_destroy(); // #3

$result = array(); // #4

$result['success'] = true;
$result['msg'] = 'logout';

echo json_encode($result); // #5

First, we need to resume the current session (#1), then we need to unset all of the session variables (#2), and next we need to destroy the session (#3). Lastly, we need to send the information back to Ext JS that the session has been destroyed (#4 and #5).

Ajax request success versus failure

We have already taken care of the server-side code. Now, we need to go back to the Ext JS code and handle the response from the server. But first, we need to understand a very important concept that usually confuses most Ext JS developers.

In Chapter 3, The Login Page, we mentioned that the ways that the form submit and Ajax requests in Ext JS handle the success x failure are a little different, and this is what confuses most developers.

The Ext.Ajax class is responsible for Ajax requests done by Ext JS. If we look at the documentation, this class has three events: beforerequest, requestcomplete, and requestexception, which are explained as follows:

  • The event beforerequest is fired before the request
  • The event requestcomplete is fired when Ext JS is able to get a response from the server
  • The requestexception event is fired when an HTTP error status is returned from the server

Now, let's go back to the Ext.Ajax.request call. We can pass some options to the request, including the url property we want to connect to, parameters, and other options including the success and failure functions. Now, this is where the misunderstanding begins. Some developers understand that if the action happened successfully on the server, we usually return success = true from the server. If something goes wrong, we return success = false. Then, on the success function, success = true is handled, and on the failure function, success = false is handled. This is wrong, and it is not how Ext JS Ajax requests work; however, that is exactly how form requests work (as we learned in Chapter 3, The Login Page). See how it gets confusing?

For Ext JS Ajax requests, success is when the server returns a response (success true or false; it does not matter), and failure is when the server returns an HTTP error status. This means that if the server was able to return a response, we will handle this response on the success function (and we will need to handle it whether the success information is true or false), and on the failure message, we need to inform the user that something went wrong and the user should contact the system administrator.

We will implement the failure callback function first. So, inside the ViewController class, we will add the following code:

onLogoutFailure: function(conn, response, options, eOpts){
    Packt.util.Util.showErrorMsg(conn.responseText);
},

What we are going to do is display an alert to the user with an error icon and an OK button with the HTTP status error information.

To reproduce an error so the requestexception event can be fired, we can rename the logout.php file to something else (for example, logout_.php) only for testing purposes. And then, we can execute the code, and we will have the following output:

Ajax request success versus failure

And this is all we need for the failure function. Note that we are reusing the Packt.util.Util class that we developed in Chapter 3, The Login Page, in this chapter again! See how it is nice to reuse code?

Note

We are reusing code and saving some lines of duplicated code. We are also creating a pattern of how to handle a few things in our project. This is very important when working in a project, especially when working in a team. This way, the project will look like a single person and not that multiple people developed it, which is really good. This is also a best practice to be followed. Reusing code is also part of what is called minimizing the payload size, which is one of the best practices while developing with JavaScript and also a concern of web development. To learn more about this, please visit https://developers.google.com/speed/docs/best-practices/payload.

To make the code work, remove the following code from the MainController class:

requires: [
    'Ext.MessageBox'
],

Write the following code in the preceding code's position:

requires: [
    'Packt.util.Util'
],

Now, let's focus on the success callback function:

onLogoutSuccess: function(conn, response, options, eOpts){
   //#1
    var result = Packt.util.Util.decodeJSON(conn.responseText);

    if (result.success) { //#2
        this.getView().destroy(); //#3
        window.location.reload(); //#4
    } else {

        Packt.util.Util.showErrorMsg(result.msg); //#5
    }
}

The first thing we need to do is decode the JSON message (#1) that we received from the server. If we log the conn parameter sent to the success function (console.log(conn)), this will be the output we will get on the console:

Ajax request success versus failure

The conn.responseText property is where the information we want to retrieve is present, the success and msg values. Recall that in Chapter 3, The Login Page, we discussed the possibility of responseText containing an exception other than the JSON we are expecting. So, for this reason, we are going to reuse the decodeJSON function we created (#1) so that we can properly handle any results.

In the case of success (#2), we are going to destroy the Main class (#3), which is our Viewport (this is good to release the browser's memory and make the objects available for the JavaScript garbage collector). As the Viewport contains all the other components of our application, it is going to destroy them as well. Then, we will reload the application displaying the Login screen again (#4).

If success is false (or any error occurred), we will display an error alert with the error message (#5).

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.188.200.118