Bitwise Operators Part 4

Let’s start to organise and code the POC! Remember: your code must be legible and understandable for other devs, so, follow a pattern is a good thing to do. There are a lot of strategies to do this, mine is “The simpler, the better”.

We’ll organise the code with these folders:

  • ViewModels;
  • DataAccess;
  • Repositories;
  • BusinessLogic.

After creating these folders, we should make our first change: move the index.js to the viewModels folder. Don’t forget to change the src attribute on index.html.

Organising

The Local State Repository

To keep it simple, let’s use the browser local storage, this way you won’t need to deal with databases.

Into the repositories folder, create a file named: stateRespository.js, and let’s create the class LocalStateRepository.

This class should have the methods we’ll use to manage the state, the rules and the checks of our POC.

It can be:

export class LocalStateRepository {
  createState(stateName, stateId) {}

  getStates() {}

  createBitwiseOrRule(ruleName, stateArray) {}

  getRules() {}

  clearAllData() {}
}

As you can read, it’s pretty simple! Create, Retrieve and delete all data. We won’t need to get a specific state or rule and delete a particular state and rule for this POC.

State Manager

Inside the folder businessLogic, create a file stateManager.js and let’s create a StateManager class:

export class StateManager {
  set currentState(stateName) {}

  get currentState() {}

  createState(stateName) {}

  createBitwiseOrRule(ruleName, stateArray) {}

  getRules() {}

  clearAllData() {}

  checkRule(ruleName) {}
}

Our logic is pretty simple and encapsulates some implementation details, for example, when you want to create a new state the page won’t need to pass the new ID, which will be calculated in a private function and passed to the createState on the repository, and the current state is exposed as a property.

Data Access Layer

Now, let’s create the layer which it’ll be responsible for the data persistence!

In the dataAccess folder, create a file named localStoreManager.js and create a class named LocalStoreManager.

export class LocalStoreManager {
  saveObject(key, value) {}

  getObject() {}

  getObjectByKey(key) {}

  removeObject(key) {}

  getKeys() {}

  clearData() {}
}

About the Local Storage:

The read-only localStorage property allows you to access a Storage object for the Document‘s origin; the stored data is saved across browser sessions. localStorage is similar to sessionStorage, except that while data stored in localStorage has no expiration time, data stored in sessionStorage gets cleared when the page session ends — that is, when the page is closed.

https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage

As it’s a read-only storage object, you can note we don’t have the Update methods.

This is an example of how you can see the data saved in the localStorage:

localStorage Data

The code in ths LocalStoreManager is simple!

Saving: get the keys, check if is already taken, and then, store the data on it. Note that the exposed method calls a private function.

function saveLocalStoreObject(key, value) {
  const keys = getLocalStoreKeys();

  if (keys.indexOf(key) > -1) {
    throw new Error(`The key ${key} is already taken.`);
  }

  localStorage.setItem(key, value);
}

export class LocalStoreManager {
  saveObject(key, value) {
    saveLocalStoreObject(key, value);
    console.log('Object saved on Local Store', getLocalStoreObject());
  }
}

Retrieving the localStore Object:

function getLocalStoreObject() {
  return { ...localStorage };
}

export class LocalStoreManager {
  getObject() {
    return getLocalStoreObject();
  }
}

Retrieving an object by its key:

function getLocalStoreObject() {
  return { ...localStorage };
}

function getLocalStoreObjectByKey(key) {
  return getLocalStoreObject()[key];
}

export class LocalStoreManager {
  getObjectByKey(key) {
    const returnedObj = getLocalStoreObjectByKey(key);
    console.log('Object found', returnedObj);
    return returnedObj;
  }
}

Deleting an object by its key:

function getLocalStoreObject() {
  return { ...localStorage };
}

function removeLocalStorageObjectByKey(key) {
  localStorage.removeItem(key);
}

export class LocalStoreManager {
  removeObject(key) {
    removeLocalStorageObjectByKey(key);
    console.log('Object removed', getLocalStoreObject());
  }
}

Retrieving all Object keys

function getLocalStoreKeys() {
  return Object.keys(localStorage);
}

export class LocalStoreManager {
  getKeys() {
    return getLocalStoreKeys();
  }
}

And, finally, delete all data!

function getLocalStoreKeys() {
  return Object.keys(localStorage);
}

function clearLocalStoreData() {
  let keys = getLocalStoreKeys();
  let i = keys.length;
  while (i--) {
    localStorage.removeItem(keys[i]);
  }
  keys = getLocalStoreKeys();
  console.log('All clear?', keys.length === 0);
}

export class LocalStoreManager {
  clearData() {
    clearLocalStoreData();
    console.log('Object cleared', getLocalStoreObject());
  }
}

The complete code should be something like this:

function saveLocalStoreObject(key, value) {
  const keys = getLocalStoreKeys();

  if (keys.indexOf(key) > -1) {
    throw new Error(`The key ${key} is already taken.`);
  }

  localStorage.setItem(key, value);
}

function getLocalStoreObject() {
  return { ...localStorage };
}

function getLocalStoreObjectByKey(key) {
  return getLocalStoreObject()[key];
}

function removeLocalStorageObjectByKey(key) {
  localStorage.removeItem(key);
}

function getLocalStoreKeys() {
  return Object.keys(localStorage);
}

function clearLocalStoreData() {
  let keys = getLocalStoreKeys();
  let i = keys.length;
  while (i--) {
    localStorage.removeItem(keys[i]);
  }
  keys = getLocalStoreKeys();
  console.log('All clear?', keys.length === 0);
}

export class LocalStoreManager {
  saveObject(key, value) {
    saveLocalStoreObject(key, value);
    console.log('Object saved on Local Store', getLocalStoreObject());
  }

  getObject() {
    return getLocalStoreObject();
  }

  getObjectByKey(key) {
    const returnedObj = getLocalStoreObjectByKey(key);
    console.log('Object found', returnedObj);
    return returnedObj;
  }

  removeObject(key) {
    removeLocalStorageObjectByKey(key);
    console.log('Object removed', getLocalStoreObject());
  }

  getKeys() {
    return getLocalStoreKeys();
  }

  clearData() {
    clearLocalStoreData();
    console.log('Object cleared', getLocalStoreObject());
  }
}

Testing!

Let’s temporary break a rule accessing the data layer directly from the ViewModel to test our implementation!

Open your /viewModels/index.js file, delete all the previous code, and put this:

import { LocalStoreManager } from '../dataAccess/localStoreManager.js';

const lsm = new LocalStoreManager();

lsm.saveObject('one', 'This is the value of the ONE');
lsm.saveObject('two', 'This is the value of the TWO');
lsm.saveObject('three', 'This is the value of the THREE');
Testing!

Maybe you are thinking: the correct way to import something is…

import { LocalStoreManager } from '../dataAccess/localStoreManager';

Why put the .js at the end? Simply because I can keep it simple and avoid using the webpack (https://webpack.js.org/) at this moment!

You must change the javascript src attribute in the index.html.

from:

<script src="/viewModels/index.js"&gt;</script&gt;

to:

<script type="module" src="/viewModels/index.js"&gt;</script&gt;
the jsvascript src attribute in the index.html

No worries! All suported natively by the Google V8 engine! Please, see: https://v8.dev/features/modules

Run using the Code Live Server and you’ll see:

Done!

Seeing the error: as we learnt, the data persisted in the localStorage has no expiration time, so, if you try to reload the browser, you’ll see the error we coded!

Manually clear the site data: to do this, click on ‘Clear storage and then, on the ‘Clear site data’ button.

Or, simply call the clearData method before starting to persist the data!

import { LocalStoreManager } from '../dataAccess/localStoreManager.js';

const lsm = new LocalStoreManager();

lsm.clearData();

lsm.saveObject('one', 'This is the value of the ONE');
lsm.saveObject('two', 'This is the value of the TWO');
lsm.saveObject('three', 'This is the value of the THREE');

Next post, we’ll code the POC logic. Stay tunned and happy coding!

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s