# 9th July Report
## Progress
**08:48** Entering the lab
---
### Create function to check session login
- To implement the session login system, from the last report we have created using preference by storing the email as `session_id` and the login or access page (when accessing a page) time as `last_date`
- **13:38** Below here is the function which I will implement to all page to check if there any `session_id` and is the time still under the `SESSION_TIMEOUT` value.
```typescript=
async checkSession() {
// 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();
// check if there any session ID
let checkData = await this.pref.checkData(StaticVariable.KEY__SESSION_ID, null);
// set the currentPage string
let currentPage = "home";
if (checkData) {
// direct the user to login page
this.navCtrl.navigateForward(['login']);
} else if (difDate > StaticVariable.SESSION_TIMEOUT) {
// direct the user to login page
this.navCtrl.navigateForward(['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, currentPage);
} else if (!checkData && difDate <= StaticVariable.SESSION_TIMEOUT) {
// save new Date
this.pref.saveData(StaticVariable.KEY__LAST_DATE, nowDate);
}
}
```
- On above in **line 12** we have set the last page as `"home"`, on every page it will be changed to their page name.
- **Explaination:**
- Variable `nowDate` store the date when the page is accessed, `lastDate` store the last date when user has accessed the page, and `difDate` is the difference of last and now time in number, thanks to **getTime()** method inside the Date class that converts the Date into miliseconds number.
- On `checkData` it calling the function to check whether there is data about the session ID or not with boolean as return value.
- On `currentPage` store the name of the current page, it's static and pre-defined.
- The workflow would be if there is no `SESSION_ID` then go to Login Page, this is as well when `difDate` is bigger than the `SESSION_TIME`.
- If two condition above not then the user can continue to use the PWA.
---
### Implement the function into all pages
- **16:23** To implement the session login system above, several things should be done:
- The `checkSession()` function should be put inside the main class.
```typescript
export class MyPage {
// function goes here
async checkSession() {
...
}
}
```
- Import `Prefererrence Manager` and `Static Variable` library. Call only the preference inside the constructor, the static variable class not necessary.
```typescript
import { PreferenceManagerService } from '../services/preference-manager.service';
import { StaticVariable } from '../classes/static-variable';
constructor (
private pref: PreferenceManagerService
) { }
```
- In login page, we should add system to store into preference (login.page.ts):
```typescript=
async login() {
const { email, password } = this;
let resultData = await this.loginUser(email, password);
console.log(resultData);
if (resultData === true) {
// save the email into session_id
await this.pref.saveData(StaticVariable.KEY__SESSION_ID, email);
// save the date into last_date
let nowDate = new Date();
await this.pref.saveData(StaticVariable.KEY__LAST_DATE, nowDate);
// get last page if exists
let lastPage = await this.pref.getData(StaticVariable.KEY__LAST_PAGE);
// console.log(lastPage);
if (lastPage === null) {
// if null route to home
this.router.navigate(['home']);
} else {
// delete last_page from preference
await this.pref.removeData(StaticVariable.KEY__LAST_PAGE);
// console.log("Go to: " + lastPage);
// this.router.navigate([lastPage]);
this.navCtrl.back();
}
console.log("Login successed!");
} else {
console.log("The email or password is incorrect!");
}
}
async loginUser (email, password) {
let url = this.urlUserLogin;
let respond = false;
const postBody = {
"Email": email,
"Password": password
};
let value = await this.http.post(url, postBody).toPromise();
if (value['code'] === 200) {
respond = true;
}
return respond;
}
```
- Above is the code from Login Page with added the function to store into preference on **line 10** and **line 14**.
- On **line 17-19** is checking is there any `lastPage` exists, means that Login Page is accessed from re-direct function after timed out on session login system. If exists then go to that page, otherwise it will direct the user to default value = Home Page.
---
- Testing on Nearby Page:
<center>
<img src="https://raw.githubusercontent.com/aru1702/images/master/ntust-documentation/22-01.JPG" style="max-height:600px" />
</center>
<br>
- On log above, the user go to Nearby Dispenser Page after login, means that before he has timed out.
- The system records the time difference, currently **48**.
- The user choose to see device with ID **MA_05_01** and go to Nearby Dispenser Page.
- On that page, system has checked again whether the session ID is exists and the time between the `lastDate` and `nowDate` still under the `SESSION_TIMEOUT`.
- When the page refreshed the `difTime` is **14029**, this is above of the timeout limit.
- The page is directed to Login Page, in this state user should re-login using his account.
- After re-login user back to Nearby Dispenser Page, store again the `sessionId` and `lastDate`, and load the `device_id` to generate the data from API.
---
- On below is the video which from Home Page to Nearby Dispenser Page
{%youtube n4_a5BYNMQE %}
---
### Dispenser API into service
**17:42** Because of more than one page using the same, all of the API should be declare in one file named service. In this service I declare all the function that can be called to process the API and return the value needed. For example if need to get list of all dispenser from the API, the function would be like this:
```typescript=
private urlDispenserList: string = 'https://smartcampus.et.ntust.edu.tw:5425/Dispenser/List';
async getDispenserList () {
let url = this.urlDispenserList;
let value = await this.http.get(url).toPromise();
return value['Data'];
}
```
From the code above:
- The function can be called once being imported and declare in constructor with `this.theVarNameChosen.getDispenserList()`, after this can be store to variable or return Promise with `then((result) => { }`.
- The function will return the value inside the Json Object under name `Data`.
---
This is the code for **dispenser-api.service.ts**:
```typescript=
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
@Injectable({
providedIn: 'root'
})
export class DispenserAPIService {
// domain used
private domain: string = 'https://smartcampus.et.ntust.edu.tw:5425/';
// constant url List
/* 01 */ private urlGetToken: string = this.domain + 'Login';
/* 02 */ private urlCreateUser: string = this.domain + 'CreateUser';
/* 03 */ private urlUserLogin: string = this.domain + 'UserLogin';
/* 04 */ private urlDispenserList: string = this.domain + 'Dispenser/List';
/* 05 */ private urlNearbyDispenser: string = this.domain + 'Dispenser/Nearby?Device_ID=';
/* 06 */ private urlDispenserPicture: string = this.domain + 'Dispenser/Image?Device_ID=';
/* 07 */ private urlDispenserDetail: string = this.domain + 'Dispenser/Detail?Device_ID=';
/* 08 */ private urlDispenserMaintenance: string = this.domain + 'Dispenser/Maintenance?Device_ID=';
/* 09 */ private urlDispenserRawData: string = this.domain + 'Dispenser/Rawdata?Device_ID=';
/* 10 */ private urlDispenserRepairCondition: string = this.domain + 'Dispenser/Repair?Device_ID=';
/* 11 */ private urlReportDispenserProblem: string = this.domain + 'Dispenser/Report';
/* 12 */ private urlUpdateTrack: string = this.domain + 'Dispenser/Track';
/* 13 */ private urlCheckTrackStatus: string = this.domain + 'Dispenser/Track';
/* 14 */ private urlRepairConditionThingworx: string = this.domain + 'Thingworx/Dispenser/Repair?Status=';
constructor(private http: HttpClient) { }
async getToken () {
let url = this.urlGetToken;
const postDataToken = {
"UserName": "pwa_user001",
"Password": "password"
};
let getToken = await this.http.post(url, postDataToken).toPromise();
return getToken['token'];
}
async registerNewUser (email, password, repassword) {
let url = this.urlCreateUser;
let returnValue = false;
let token = await this.getToken();
const postDataRegister = {
"Email" : email,
"Password" : password
}
if (password != repassword) {
console.log("Password not match!");
} else {
let httpOption = await {
headers: new HttpHeaders({
'Content-Type': 'application/json',
'Authorization': token
})
};
console.log(httpOption);
return await this.http.post(url, postDataRegister, httpOption).subscribe(() => {
return true;
}, error => {
return false
});
}
}
async loginUser (email, password) {
let url = this.urlUserLogin;
let respond = false;
const postBody = {
"Email": email,
"Password": password
};
let value = await this.http.post(url, postBody).toPromise();
if (value['code'] === 200) {
respond = true;
}
return respond;
}
async getDispenserList () {
let url = this.urlDispenserList;
let value = await this.http.get(url).toPromise();
return value['Data'];
}
async getNearbyDispenser (device_id) {
let url = this.urlNearbyDispenser + device_id;
let value = await this.http.get(url).toPromise();
return value['Data'];
}
async getDispenserPicture (device_id) {
let url = this.urlDispenserPicture + device_id;
let value = await this.http.get(url).toPromise();
return value;
}
async getDispenserPictureUrlOnly (device_id) {
return this.urlDispenserPicture + device_id;
}
async getDispenserDetail (device_id) {
let url = this.urlDispenserDetail + device_id;
let value = await this.http.get(url).toPromise();
return value['Data'];
}
async getDispenserMaintenance (device_id) {
let url = this.urlDispenserMaintenance + device_id;
let value = await this.http.get(url).toPromise();
return value['Data'];
}
async getDispenserRawData (device_id) {
let url = this.urlDispenserRawData + device_id;
let myJson;
await this.http.get(url).toPromise().then((success) => {
console.log("Success");
myJson = success['Data'];
}).catch((failed) => {
myJson = {
"Device_ID": device_id,
"UploadTime": "No Data",
"Status": 0,
"HotTemp": 0,
"WarmTemp": 0,
"ColdTemp": 0
}
});
return myJson;
}
async getDispenserRepairCondition (device_id) {
let url = this.urlDispenserRepairCondition + device_id;
let value = await this.http.get(url).toPromise();
return value['Data'];
}
async reportProblem (file, device_id, email, errorType, description) {
let url = this.urlReportDispenserProblem;
// still under progress
}
async wantUpdateTrack (device_id, email, status) {
let url = this.urlUpdateTrack;
const postBody = {
"Email": email,
"Device_ID": device_id,
"Status": status
}
await this.http.post(url, postBody).toPromise()
.then(() => {
return true;
})
.catch(() => {
return false;
});
}
async checkTrackStatus (device_id, email) {
let url = this.urlCheckTrackStatus + "?Device_ID=" + device_id + "&Email=" + email;
let value = await this.http.get(url).toPromise();
return value['Data'];
}
async getRepairThingworx (device_id) {
let url = this.urlRepairConditionThingworx + device_id;
let value = await this.http.get(url).toPromise();
return value['Data'];
}
}
```
---
**18:00** Leaving the lab
###### tags: `on-intern`