Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / HTML5

Why HTML5? Why Not? UI / UX Versus Storage Challenge (Part 1 of N)

5.00/5 (3 votes)
28 Dec 2021CPOL9 min read 5.1K   86  
Creation of a simple app (< 50 lines of code) which allows you to save a dynamic catalog of images with an examination of how to save a user's data
There are times when HTML with JavaScript can be the quickest path to a solution. However, the challenge is that there is not a super easy way to store a user's data so that it is retrievable.

Introduction

I'm writing this article in an attempt to start a conversation about Modern App Development.

What is Modern App Development?

It's really the old pipe dream of:

Quote:

Writing an app once and having it run everywhere.

I know that in some ways, it is ridiculous to believe this is possible but it seems equally ridiculous that we are 30 years into the "Consumer" Internet and it is still so difficult.

Background

Recently, I wanted an app that could do the following:

  1. Allow me to save a catalog of images (screenshots, etc.)
  2. Image catalog would be easily updateable so I can add new images very quickly / easily (more about this later).
  3. Be accessible from any of my computers or devices (desktop (running Linux), laptop (running Win10), iPad (iOS), Mac Mini (macOS), Amazon Fire (Android), phone running Android, etc.).

How You Get Pushed toward Particular Technology

Almost every one of my devices runs a different Operating System (Linux, Windows, iOS, macOS, Android). This instantly rules out any kind of desktop or native (mobile Android or iOS) development -- unless I want to duplicate effort.

Of course, all of these devices have the web available to them so it instantly pushes you toward designing some kind of web app.

HTML5 Can (Almost) Solve the Entire Problem (Create the Entire Solution)

The HTML5 Standard includes HTML, CSS & JavaScript.

That means it includes everything we really need to be able to create a User Interface (HTML controls - buttons, drop lists, edit boxes, etc.).

Of course, it includes CSS so we can style it all up and make it look good and help the user understand what the User Interface is attempting to help the user do.

Most of the other functionality can all be taken care of with JavaScript (no matter how much you hate it).

The Problem that HTML5 Can't Really Solve (Almost Solves)

However, because the browser protects the user, we don't have a very good way to save user data. Vanilla JavaScript APIs don't provide a way to write files or data to the user's storage devices. (Yes, there are NodeJS APIs that allow this but pure JavaScript doesn't.)

What Will this Article Cover?

This article is going to set up the base app which will attempt to show that we can fulfill all three of the original requirements (at the top of this article) using only HTML5 technology. Again, however, we will see the limitation of data storage.

Let's go write the code now.

If you want to try it first, you can go to CodePen and check it out at https://codepen.io/raddevus/pen/WNZZRRR^ or download the source and try it.

First, The User Interface

All I need for the main interface is a way to allow the user to include a link to where the image is stored.

It's just a simple HTML input type text and a button the user clicks to add the image.

Image 1

That's it!

Now the user can paste in an image link and click the button and it'll be added to our app.

Well, we need to write some code to handle all of that.

What I Want The App To Do

I want the app to:

  1. Provide a thumbnail view of each image I add
  2. Make it so when the user clicks an image it opens in a new window (tab) and displays the full-size image
  3. Additionally, I'll do a little hover styling so when the user floats over a particular image, it will display a subtle box around it to show the user that something is happening and that the image is clickable.

Here's a basic snapshot of what I'm thinking it will look like after four images are added:

Image 2

What are the Things We Need to Build in Code?

  1. Write code to handle adding the image URL.
  2. Write code to display all thumbnails for images the user has added.

Note: Handling Bad Input

For this article, I will leave it as an exercise for the reader to handle bad input (no text in Image URL textbox, etc.).

If the user clicks the button with no URL, an image tag will be added to the DOM but the link will be invalid and an bad image tag will be displayed. We may cover removing images from localStorage, but for now, I won't cover it.

Here's the code we need to allow the user to add an image:

JavaScript
function addImage(){

  let allImages = JSON.parse(localStorage.getItem("allImg"));

  if (allImages === null){
    allImages = [];
  }

  let localUrl = document.querySelector("#imageUrl").value;
  
  allImages.push(localUrl);
  
  localStorage.setItem("allImg",JSON.stringify(allImages));
  
  document.querySelector("#imageUrl").value = "";
  
  removeMainDiv();
  
  displayImages();
}

Code Explanation

The first thing we try to do is retrieve an item from the user's browser localStorage which is named allImg.

We are expecting that to be an array of strings (URLs) so we wrap it in a call to JSON.parse() which will parse the localStorage data into an object -- in our case, an array. If we didn't parse() the data, then it would just be a string of data.

If the allImg item does not exist in the user's localStorage, then it will return a null.

If the allImages variable is null, then we initialize it to an empty array.

Next, we get the new value that the user entered into URL textbox:

JavaScript
let localUrl = document.querySelector("#imageUrl").value;

Next, we push the new image URL onto the array of images (that was previously empty or contained the images that were already stored in localStorage).

Before we continue on talking about what this code does, let's take a moment and talk a bit more about Browser API localStorage.

About localStorage

Basically, it is Browser storage that is based on name/value pairs. The name and the value are stored as strings.

You can simply provide a string name and then any value and store it. Your data will be stored as a string also so you'll need to convert it to your expected type.

localStorage is bound to the web site's TLD (top level domain). Values stored at one domain are completely inaccessible by any other domain.

That means if you store anything at http://localhost/, then you cannot retrieve those values from http://<anyOtherDomain>.

The data is also stored in each browser instance. That means on the same desktop user's account but different browser, you will not be able to access the same data even if you're on the same domain.

For example, if you save data to localStorage using the Google Chrome browser on http://mySite.com and then access the same site using your FireFox browser, the data is not accessible. This is true even if it is the same desktop user.

Data Access

Data stored in localStorage is only retrievable on the same browser on the same domain where it was initially saved.

This a security feature but also makes it difficult to share your data or make it so the data is available to the same user no matter where she is using your Single Page App.

What This Means to Us for Our App

This means that as long as you (and your user) are aware of this limitation, then it may be valid to write a simple app like this which requires the user to always use the same browser from the same device to retrieve her data.

This is a frustrating limitation however and one that must be overcome in order to make it so our image catalog can be used across our many devices.

Running the App Locally

This can provide a little utility app by running the code locally.

For example, follow these steps:

  1. Get the source code (top of this article) and save it into a directory.
  2. Double-click the index.htm.
  3. Add an image URL.

Any images you add will be added to your browser's localStorage and the next time you double-click the index.htm from that folder, they will be reloaded. Here's mine running from a file location in the Brave browser:

Image 3

All Data In localStorage Is A String

Continuing with our explanation of our code, you'll now see that when I store our JavaScript array of strings that I actually call JSON.stringify() on the array so that it is turned into a pure string. Since everything that is stored in localStorage is a string, this helps with escape characters, etc. being handled properly.

Since we pushed the new image URL onto our array, it will show up last in our list of URLs.

It also means we have the entire list (any previously loaded ones and our new one) ready to be saved to localStorage. We then make the call to turn the array into a string and then wrap that with a call to save the data into localStorage:

JavaScript
localStorage.setItem("allImg",JSON.stringify(allImages));

This ensures that the next time the page is refreshed (or the user visits the site) that all the images will be in localStorage and can be loaded in and displayed again.

Using Your Browser's Console to Examine localStorage

If you load our app and then open up your browser's console window (F12 in most browsers), then you can examine localStorage.

Once you open the console, just type: localStorage.getItem("allImg") and press Enter.

If you've added any images, then you'll see a list of URLs. Here's what mine looks like (I partially blurred that last one out since it is a link to some proprietary source code.)

Image 4

You can see that it is a stringified array, because it has outer single quotes that wrap the array braces [ ].

What Does the Rest of the Code Do?

The rest of the code simply:

  1. iterates through any images which are in localStorage
  2. creates a new link tag for each (to make the image clickable)
  3. creates a new img tag for each
  4. sets the src value of the img tag to the URL found in localStorage

All of that work displays the thumbnail images and makes them clickable so they open in a new window at their original size.

Summary / Looking Forward / RFC

All of this has been to start a conversation about two main points:

  1. HTML can make building User Interfaces very easy -- very little code here for the dynamic view that we've created
  2. Storing a user's data so it is easily retrievable is far more difficult with HTML5 technologies

Alternate Ways of Storing This Simple User Data

Going forward, I will provide various ideas for storing user data and I would like to hear from readers about what they've found.

In the next article, I will look at a few easy ways of posting data to a remove server where the data will be stored.

Request for Comments

What have you found that is useful to do that?

In the past, I've used Google Firebase but there are some limitations and challenges there.

The Pipe Dream

A remote persistent storage that allows me to post data via WebAPI and retrieve it using a secret / strong key. Data would be encrypted using AES256. All the user would have to do is call one API and the data would be stored.

I have an idea for this and will be writing it up in one of these future articles.

History

  • 27th December, 2021: First release

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)