Login Screen Implementation

We will look into the login screen implementation.

As described in the previous topic, the login screen is defined within a <div> element in the index.html file and configured with IDs and JavaScript functions. See the below figure.

The performLogIn() function and the performSignUp() function are implemented in the login-page-callback.js file.

Creating a user

We will start with the user creation. When the "Sign Up" button is clicked, the performSignUp() function is executed. The following sample code is an excerpt from this function:

function performSignUp() {
  // Get the username and password from the UI.
  var username = document.getElementById("username-field").value;
  var password = document.getElementById("password-field").value;

  // Create a KiiUser object.
  var user = KiiUser.userWithUsername(username, password);
  // Register the user asynchronously.
  user.register({
    // If the user was registered
    success: function(theUser) {
      console.log("User registered: " + JSON.stringify(theUser));

      // Go to the main screen.
      openListPage();
    },
    // If the user was not registered
    failure: function(theUser, errorString) {
      alert("Unable to register user: " + errorString);
      console.log("Unable to register user: " + errorString);
    }
  });
}
  1. The username and password are fetched from the screen using DOM. They are set in username and password, respectively.

  2. username and password are passed to the userWithUsername() method to create a user.

  3. The register() method is called. The SDK sends a request to Kii Cloud to create the specified user.

Non-blocking API

The API that communicates with the server, like the register() method, is implemented as a non-blocking API. Only one thread is available for processing in JavaScript. The whole mobile app will freeze if this thread starts waiting for network communication to finish. The non-blocking API is designed to solve this problem by not waiting for the network communication to finish.

The blocking API, on the other hand, will wait for API execution to finish. But the Kii Cloud SDK for JavaScript does not support the blocking API. The Kii Cloud SDKs for Android and iOS support the blocking API to allow the user program to create worker threads.

The following sequence diagram illustrates how the non-blocking API works.

When the JavaScript thread calls the register() method, the JavaScript engine inside the SDK creates an internal process and the method instantly returns control. The user can operate the screen while the network access process is ongoing, because the network call is made within the internal process.

This type of processing is also called asynchronous processing because the network call process is independent from the caller.

When the network call is finished and the next cycle of processing starts, the JavaScript thread calls the callback function. The caller has specified the function to execute after a successful network call in the success block and the function to execute after a failed network call in the failure block. Either of the functions is called depending on the success/failure status of the network call in the SDK.

user.register({
  success: function(theUser) {
    ......
  },
  failure: function(theUser, errorString) {
    ......
  }
});

Execution sequence

Be careful about the execution sequence.

// Step 1
user.register({
  success: function(theUser) {
    // Step 3-1
  },
  failure: function(theUser, errorString) {
    // Step 3-2
  }
});
// Step 2

In the above sample code, the place labeled as Step 3-1 is where you should write logic to be executed after the register() method is executed. The place labeled as Step 3-2 is the position for error handling. The register() method is not yet complete when the place labeled as Step 2 is reached. If you write logic to be executed after the user registration in Step 2 by mistake, you will most likely encounter an error because the user registration process has just started.

When you are executing multiple APIs sequentially, you will need to write logic inside callback functions. This will make deeply nested code and make the code hard to read. To ensure code readability, you can use promises. Implementation with promises is explained later in the tutorial.

Execution result

You write logic inside callback functions to handle execution results.

The sample code in the programming guide shows how to write the code in detail, for example, with arguments in callback functions. Check the sample case below to learn how to implement the logic.

Once again, here is an excerpt of the user registration logic:

user.register({
  // If the user was registered
  success: function(theUser) {
    console.log("User registered: " + JSON.stringify(theUser));

    // Go to the main screen.
    openListPage();
  },
  // If the user was not registered
  failure: function(theUser, errorString) {
    alert("Unable to register user: " + errorString);
    console.log("Unable to register user: " + errorString);
  }
});

The callback functions for success and failure are defined at the API call. Non-blocking API execution will trigger network communication, so there is always a chance of error, such as a network error, to be caused. This applies to all non-blocking APIs, not only to the register() method.

In Hello Kii, we handle the result as follows:

  • When the execution succeeded

    The user at the completion of user registration is output to the console.

    In this example, the JSON.stringify() method outputs a sting as blow: These are the values internally used in the SDK and output as they are. Just take a quick look at the contents.

    User registered: {"_customInfo":{"internalUserID":594865163769747500},"_uuid":"03c0faa00022-ad8a-5e11-16ae-0343ca2a","_username":"aaa","_password":null,"_accessToken":"McT3fVbjkekjKCuyzsBdQBtMhAJfZbcPy8hAXDowwpg","_expiresAt":"2084-04-02T07:09:13.133Z","_thirdPartyAccounts":{},"_disabled":false}
    

    The openListPage() function is called to bring the data listing screen up. This function will be detailed in the topic for the data listing screen.

    The state of the logged-in user is stored in a static variable within the SDK. You can use this variable in the data listing screen.

  • When the execution failed

    When the API execution fails, the callback function is called with errorString containing an error message. In this example, the error information is output to the screen and the console.

Login

The implementation of the login process is almost the same as that of the user registration.

When the "Log In" button is clicked, the performLogIn() function is executed. The following sample code is an excerpt from this function (note that the excerpt is simplified):

function performLogIn() {
  // Get the username and password from the UI.
  var username = document.getElementById("username-field").value;
  var password = document.getElementById("password-field").value;

  // Authenticate the user asynchronously.
  KiiUser.authenticate(username, password, {
    // If the user was authenticated
    success: function(theUser) {
      console.log("User authenticated: " + JSON.stringify(theUser));

      // Go to the main screen.
      openListPage();
    },
    // If the user was not authenticated
    failure: function(theUser, errorString) {
      console.log("Unable to authenticate user: " + errorString);
      alert("Unable to authenticate user: " + errorString);
    }
  });
}

Just like the user registration logic, we get the username and password from the screen using DOM.

Then, we pass these values to the authenticate() method and start the login process. If the username and password are valid, the mobile app will be in the logged in state.

The authenticate() method is a non-blocking API that causes network communication, so we write logic to process the result in the callback functions.

  • When the execution succeeded

    Just like the user registration logic, the user at the completion of user registration is logged and then the openListPage() function is called to move to the data listing screen.

    The state of the logged-in user is stored in a static variable within the SDK. You can use this variable in the data listing screen.

  • When the execution failed

    As with the failure of user registration, an error message is displayed.

Current user

As already mentioned, once the user is logged in or successfully registered, the login state of this user will be kept in the SDK as the "current user". You can get the current user as follows:

var user = KiiUser.getCurrentUser();

This user is the one that you get as the argument theUser of the callback function in the authenticate() method.

Once you have the user, you can make various operations like accessing buckets of this user's scope.

The login state is kept inside the SDK because this HTML5 app is created as a single page application. The login state will be lost and the getCurrentUser() method will return null if page transition is performed, for example, by using the <a> tag.


What's next?

We will explore how the data listing screen is implemented. We will check how the data registration and retrieval are handled.

Go to Data Listing Screen Implementation.

If you want to learn more...