# 8th July Report ## Progress **08:50** Entering the lab --- ### Make service to create functions - Service is a single file in typescript that can contains lot of functions which is can be used in many other pages in one project. - For example: - I would like to have a function that calling the API to get the list of all dispensers. - This function must be in two pages, the Nearby Dispenser page and Maintenance Progress page. - I will make a **SERVICE** and create a function which use the API to get the list of all dispensers. - In both pages, I can call the **SERVICE** by import as library, use in the constructor, and call the function in the main body. - In short, functions that call or have same purpose in multiple pages of same project can be implement in single service. - Be sure that functions in same service has same level, like not mixing the get function for the list of dispensers with timer counter function which both don't have the same correlation (it would messing up the code). --- - **09:46** Create a service for save data, get data, check if the data exists, and remove the data from preferences, called `PreferenceManager`. - Create new service ``` ionic generate service services/PreferenceManager ``` - services\preference-manager.service.ts ```typescript= import { Injectable } from '@angular/core'; import { Storage } from '@ionic/storage'; @Injectable({ providedIn: 'root' }) export class PreferenceManagerService { constructor( private storage: Storage ) { } async getData (key: string) { return await this.storage.get(key).then((result) => { return result; }, () => { return null; }); } async saveData (key: string, data) { return await this.storage.set(key, data).then(() => { return true; }, () => { return false; }); } async checkData (key: string, compareData) { return await this.storage.get(key).then((result) => { if (result === compareData) return true; else return false; }, () => { return false; }); } async removeData (key: string) { return await this.storage.remove(key).then(() => { return true; }, () => { return false; }); } } ``` - Testing on test-storage.ts (we can use any page to test with log the results) ```typescript= let key = "myKey"; let data = "Hello World" let data2 = "HelloWorld"; console.log("Save into preference service"); await this.srvPref.saveData(key, data).then((onSuccess) => { console.log("Success! " + onSuccess); }, (onFailed) => { console.error("Failed! " + onFailed); }); console.log("Get data from preference service"); await this.srvPref.getData(key).then((onSuccess) => { console.log(onSuccess); }, (onFailed) => { console.error(onFailed); }); console.log("Check if data is same with " + data); await this.srvPref.checkData(key, data).then((onSuccess) => { console.log(onSuccess); }, (onFailed) => { console.error(onFailed); }); console.log("Check if data is same with " + data2); await this.srvPref.checkData(key, data2).then((onSuccess) => { console.log(onSuccess); }, (onFailed) => { console.error(onFailed); }); console.log("Remove value from preference service"); await this.srvPref.removeData(key).then((onSuccess) => { console.log(onSuccess); }, (onFailed) => { console.error(onFailed); }); console.log("Get data after remove"); await this.srvPref.getData(key).then((onSuccess) => { console.log(onSuccess); }, (onFailed) => { console.error(onFailed); }); ``` - Result in log <center> <img src="https://raw.githubusercontent.com/aru1702/images/master/ntust-documentation/21-01.JPG" style="max-height:300px" /> </center> <br> - **11:07** On result above I showed to you how to use service in a page, next below I will use the service to create session ID system --- ### Use Preference Manager to create session system for login page - The work flow for session system <center> <a href="https://raw.githubusercontent.com/aru1702/images/master/ntust-documentation/21-02.jpg" target="_blank"> <img src="https://raw.githubusercontent.com/aru1702/images/master/ntust-documentation/21-02.jpg" style="max-height:600px" /> </a> </center> - Click the image to get full version. - Description is described in last report [here](https://hackmd.io/@muhamadaldy/HJp0hMhxr) <br> --- - **15:34** Using the preference and key to check if the session ID is present and the time saved is under the `TIMEOUT` limit. - I also add new class named **StaticVariables** to store `public static` variable to get the key name and the limit of session time. - Public static is the way in object-oriented programming to use a variables, methods (functions), or classes in different class under the same projec. - With this way, some function or value that globally need to be the same value can be called directly without need to create an object first. - Create new class `ionic generate class classes/StaticVariables` - This new class is to store static variable ```typescript= export class StaticVariable { public static KEY__SESSION_ID = "session_id"; public static KEY__LAST_DATE = "last_date"; public static KEY__CURRENT_DATE = "current_date"; public static KEY__LAST_PAGE = "last_page"; public static KEY__NEARBY_DISPENSER__DEVICE_ID = "nD_deviceId"; public static KEY__MAINTENANCE_PROGRESS__DEVICE_ID = "mP_deviceId"; // 10000 = 10 seconds public static SESSION_TIMEOUT = 10000; } ``` - *Example*: Besides of using `let newValue = new StaticVariable();` and create method to get the value, we can get it by: `let newValue = StaticVariable.KEY__SESSION_ID` - In the **Login Page** we add preference service and StaticVariables to import section, also create a function to save session ID and the current date into preference, then route into the page we need. - In here it still direct the user to Home Page - Functions added ```typescript= async login() { const { email, password } = this; let postData = { "Email" : email, "Password" : password } this.resultData = await this.http.post("https://smartcampus.et.ntust.edu.tw:5425/UserLogin", postData).toPromise(); console.log(this.resultData); if (this.resultData['code'] == 200) { // go to dashboard console.log("Login successed!") this.saveSession(email); let nowDate = new Date(); this.saveLastDate(nowDate); this.router.navigate(['home']); } else { console.log("Login failed!") } } async saveSession(id) { await this.pref.saveData(StaticVariable.KEY__SESSION_ID, id); } async saveLastDate(date) { await this.pref.saveData(StaticVariable.KEY__LAST_DATE, date); } ``` - In the **Home Page** add the preference service and StaticVariables too to import section and use in main function to validate - This is in the main function ```typescript= async main () { // check session ID and date let nowDate = new Date(); let lastDate = await this.pref.getData(StaticVariable.KEY__LAST_DATE) let difDate = nowDate.getTime() - lastDate.getTime(); console.log(nowDate); console.log(lastDate); console.log(difDate); console.log(await this.pref.getData(StaticVariable.KEY__SESSION_ID)); if (await this.pref.checkData(StaticVariable.KEY__SESSION_ID, null)) { // direct the user to login page this.router.navigate(['login']); } else if (difDate > StaticVariable.SESSION_TIMEOUT) { // direct the user to login page this.router.navigate(['login']); // remove the session ID from preference this.pref.removeData(StaticVariable.KEY__SESSION_ID); // save the name of page this.pref.saveData(StaticVariable.KEY__LAST_PAGE, 'home'); } else { // save new Date this.pref.saveData(StaticVariable.KEY__LAST_DATE, nowDate); } } ``` - This will trigger two conditions: - If the session ID is null, or removed, then it will direct the user to Login Page - If the session login reach the timeout, the time difference in `difTime` is more than the value in `SESSION_TIMEOUT`, then it will re-direct the user to Login Page. - Otherwise, it will update the `LAST_DATE` to refresh the session time. - For all pages, this function is necessary. - The result with `SESSION_TIMEOUT` = 10000 - Before login <center> <img src="https://raw.githubusercontent.com/aru1702/images/master/ntust-documentation/21-03.JPG" style="max-height:400px" /> </center> <br> - After login, recorded **difTime = 4.076 seconds**. <center> <img src="https://raw.githubusercontent.com/aru1702/images/master/ntust-documentation/21-04.JPG" style="max-height:400px" /> </center> <br> - Still login, recorded **difTime = 9.033 seconds**. <center> <img src="https://raw.githubusercontent.com/aru1702/images/master/ntust-documentation/21-05.JPG" style="max-height:400px" /> </center> <br> - Session timeout, recorded **difTime = 28.5 seconds**. <center> <img src="https://raw.githubusercontent.com/aru1702/images/master/ntust-documentation/21-06.JPG" style="max-height:400px" /> </center> <br> - With this approach, it create session for login using email as ID and compare last and current time. - I also remove the session ID when user got timed out and do the log out as well. - When timed out, page also saved the current page to preference in order the user can re-direct once after re-login. - This system triggered when: - User go to the page itself. - User do refresh the page itself. - Doing any activity, even refresh the page, when the difTime still under the `SESSION_TIMEOUT` value will not consider as timeout. When this occur, the `lastDate` in preference will updated with the current Date, means that user has refresh the session time period. --- **TIME** Leaving the lab ###### tags: `on-intern`