# 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`