# 15th July Report ## Progress Time: **09:05** Event: Entering the lab --- ### Giving documentation with comment on Preference Manager service Time: **10:24** - In order to use the service with ease, a simple comment line about what is it and how to use it is given for every function. - Update for Preference Manager service, now with comment: ```typescript= /** * AUTHOR'S NOTES: * * This service is to store and retrieve data from preference in * client side. It stick with the memory in the client browser * rather than database from the server. This preference only * takes small amount of memory, up to 5 Megabytes, to store certain * of data. * * The data itself are stored using the key pair. Key is the value * that identify which location that the data are stored. For example * a single string is stored under key named "myString". In memory we * can call the value by refering "myString" as the key pair. * * For personal computer (PC) version browser, it doesn't has to * create a empty value with key pair to check if the data is present * or not. This dependency only occur on mobile device version browser * where if there is no key stored then any kind of GET data from it * will return nothing and this can break logic of your code. */ import { Injectable } from '@angular/core'; import { Storage } from '@ionic/storage'; @Injectable({ providedIn: 'root' }) export class PreferenceManagerService { constructor( private storage: Storage ) { } /** * This function is to get the data from the preference. It will * return the data from the key pair given if present and will * return null if not present. * * @param key Key to check if data is present * * @returns value Return the value if present, null if not */ async getData (key: string) { return await this.storage.get(key).then((result) => { return result; }, () => { console.error("Promise rejected: unable to get value from: " + key + "!"); return null; }) .catch((e) => { console.error("Function error: on getData => " + e); return null; }); } /** * This function is to save or store the data to preference with * the key pair. It check promise and return boolean value as true * if success and false if failed. * * @param key Key to save the data to preference * @param data Data will be stored in preference * * @returns boolean Return true if success, false if failed */ async saveData (key: string, data) { return await this.storage.set(key, data).then(() => { return true; }, () => { console.error("Promise rejected: unable to save value to: " + key + "!"); return false; }) .catch((e) => { console.error("Function error: on saveData => " + e); return false; }); } /** * This function is to check data from the one stored in the * preference with one being passed from function. It will return * boolean value as true if is it same data and false if not and * also if the data is not present inside preference. * * @param key Key to check if data is present * @param compareData Another data to be compared with the stored one * * @returns boolean Return true if same data, false if not or failed */ async checkData (key: string, compareData) { return await this.storage.get(key).then((result) => { if (result === compareData) return true; else return false; }, () => { console.error("Promise rejected: unable to check value under key: " + key + "!"); return false; }) .catch((e) => { console.error("Function error: on checkData => " + e); return false; }); } /** * This function is to remove data from preference under the key * pair. BEWARE that this function also remove the key pair from * preference with the data. It will return boolean value as true * if success removing key and value and false if failed. * * @param key Key to be deleted with the value stored * * @returns boolean Return true if success, false if failed */ async removeData (key: string) { return await this.storage.remove(key).then(() => { return true; }, () => { console.error("Promise rejected: unable to remove key and value under key: " + key + "!"); return false; }) .catch((e) => { console.error("Function error: on removeData => " + e); return false; }); } } ``` - Add new function to remove only the value of the key pair inside the preference, this help the `removeData()` function where it remove the key too. - Typescript code: ```typescript= /** * This function is to remove the value ONLY from the preference * under the key pair. It will change the value present in the * preference with "" or empty string value. It will return boolean * value as true if success and false if failed. * * @param key Key pair that value will be deleted * * @returns boolean Return true if success, false if failed */ async deleteValueOnly (key: string) { let checkValue = await this.getData(key); if (checkValue !== null) { return await this.saveData(key, "").then((result) => { return result; }, () => { console.error("Promise rejected: unable to perform delete value only under key: " + key + "!"); return false; }) .catch((e) => { console.error("Function error: on deleteValueOnly => " + e); return false; }); } } ``` - Testing with the new function ```typescript= console.log("This is for test only"); let key = "key"; let value = "Hello World!"; console.log("Save: " + value + ", under key: " + key); let returnValue = await this.pref.saveData(key, value); console.log("Return from saveData: " + returnValue); console.log("Check if data present"); returnValue = await this.pref.getData(key); console.log("Return from getData: " + returnValue); console.log("Delete value under key: " + key); returnValue = await this.pref.removeData(key); console.log("Return from removeData: " + returnValue); console.log("Check if data present"); returnValue = await this.pref.getData(key); console.log("Return from getData: " + returnValue); console.log("Done!"); ``` - Testing result - From console <center> <img src="https://raw.githubusercontent.com/aru1702/images/master/ntust-documentation/26-01.JPG" style="max-height: 400px" /> </center> <br> - Seeing through the preference in browser to know if the key is removed <center> <img src="https://raw.githubusercontent.com/aru1702/images/master/ntust-documentation/26-02.JPG" style="max-height: 400px" /> </center> <br> - From the testing above it is success and the key still remain with "" or empty string value. --- ### Testing the Report Problem API using service Time: **11:02** - Helping Thariq to use Dispenser service API: - Report problem - Want to track - Result after use Report problem with email `johnny258147@gmail.com` and device id `MA_B1_01` in database <center> <img src="https://raw.githubusercontent.com/aru1702/images/master/ntust-documentation/26-04.jpg" style="max-height: 200px" /> </center> <br> - The data is stored in database successfullly. - From left to right row: - Object or picture uploaded, the pictures that uploaded for reporting dispenser problem. - Device id, the dispenser's id. - Email, the user's email address. - Error status, user choice the error status to be reported. - Description, user input the description when error status is equal to 5 (other). - Status, the status if data is success stored. - Upload time, time when the data is stored - Based on the upload time we can see that testing the service on July 15th is success. - Result after use Want to Track with email `AAAAA@gmail.com` and device id `MA_B1_01` in database <center> <img src="https://raw.githubusercontent.com/aru1702/images/master/ntust-documentation/26-03.jpg" style="max-height: 200px" /> </center> <br> - We can see that data is stored in database, means that the function in service is works properly. --- ### Prompt login in dashboard page Time: **14:07** - On dashboard page in order to track the dispenser or giving a report problem, the user must login first. - Implementing login system in the dashboard also store if user wants to track into database. - Check login using Alert Controller with two options: **Login** or **Cancel** - The workflow would be: User press the button, has logged in? - Yes, go to report problem/track dispenser - No, perform login first. ```typescript= async checkLogin () { // check if there any session ID let checkData = await this.pref.getData(StaticVariable.KEY__SESSION_ID); let returnValue = false; // if the data is not present or empty if (checkData === "" || checkData === null || checkData === undefined) { // create alert to choose login or not let loginAlert = await this.alertCtrl.create({ mode: 'ios', header: 'Log In Required', message: 'You need to login first in order to report a problem or track dispenser status, please click the Log In button below.', buttons: [ { text: 'Cancel', role: 'cancel', handler: () => { console.log('Cancel clicked'); } }, { text: 'Log In', handler: () => { // direct the user to login page this.navCtrl.navigateForward(['login']); console.log('Log In clicked'); } } ] }); // display the alert controller loginAlert.present(); } else { // return true if login process is done returnValue = true; } return returnValue; } ``` - Explanation: - This only occur when user press the "Star" button, which wants to track the dispenser, or "Report Problem". - Check if `session_id` is already stored in preference or not, as identify has logged in or not. - Prompt an Alert Controller to perform user to choose login or not when there is no `session_id`. - In order to identify from the other two function, which click the "Star" or "Report Problem" button, a return value should be **true** if user already login and **false** if not and trigger the login system. - This is the function for "Star" or "Report Problem" button: ```typescript= async trackButton(){ // check login first, return true if login is true if (await this.checkLogin()) { // act the active to if(!this.trackIsActive) this.trackIsActive = true; else this.trackIsActive = false; let email = await this.pref.getData(StaticVariable.KEY__SESSION_ID); await this.api.wantUpdateTrack(this.device_id, email, this.trackIsActive); } } async goToReportProblem(){ // check login first, return true if login is true if (await this.checkLogin()) { this.router.navigate(['report-problem']); } } ``` - Explanation: - On `trackButton()` function, it call the `checkLogin()` function to get return value (**true** if already login, and vice versa). - This also added into `goToReportProblem()` function. - On `trackButton()` function, it also perform want to track, giving true status when "Star" is active and false status for deactive. - A screenshot when user prompt to login first: <center> <img src="https://raw.githubusercontent.com/aru1702/images/master/ntust-documentation/26-05.JPG" style="max-height: 500px" /> </center> <br> --- ## Conclusion - Preference manager service now has documentation for use of functions in order to use them with ease. - Add deleteValueOnly function into it to replace the value with empty string value instead remove with the key as well. - Helping with the report problem page to use ReportProblem and WantToTrack functions in Dispenser API service. - Create the login system in Dashboard page when user wants to track dispenser (press the "Star button") or report a problem. --- Time: **18:15** Event: Leaving the lab ###### tags: `on-intern`