To-do web app. vanilla JS ES6. Offline

https://github.com/josepagan/to-do

https://codepen.io/daifuco/full/pxrwxq/

A few weeks ago I learned the basics of the ES6 class syntax, I wanted to make a little project to reinvent a few wheels.
The project seems to work but I am not very confident with a few things.

Sorry I still have not commented properly the code.

There is a class Entry which holds the actual “to do” objects,
Then a container class Book (adds, removes, appends Entries)
And a main class… Main contains Books and deals with all the webstorage data.

Once the stored data has been parsed, I have noticed it “loses” its methods, they no longer behave like fresh objects but they are kinda ‘dead’.
What I did was to use Object.setPrototypeOf, on both books and entries.
It works but I have a feeling that is not the way to do it

class Main {
  constructor() {
    if (localStorage.getItem('stringData')) {
      this.books = JSON.parse(localStorage.getItem('stringData'));

      // this code sets the prototype of the raw data (probably not the most efficient way)

      this.books.forEach((object) => {
        Object.setPrototypeOf(object, Book.prototype);
        object.entries.forEach((object) => { Object.setPrototypeOf(object, Entry.prototype); });
      });
    } else {
this.books = [new Book('Main')];

The codepen does not work with mobile phones. I dont know why!!!

I am not sure if the design of the methods is the best one.
I am still not sure how to use getters and setters. I have read some theory but to me they dont look so different from common methods or just calling a propierty to access it.

JSON is a format for passing around structured text data (+ numbers and booleans), it isn’t designed to (and should not know) anything about specific programming constructs used in arbitrary programming languages (in this case, the language used is JavaScript and the consteucts are classes and functions, but that applies to any programming language)

The JSON.parse function does allow you to provide a second argument, which has to be a callback function (the reviver) which allows you to transform the object before it is returned — https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse#Using_the_reviver_parameter

You can use this to do what you’re trying to do, but note this is error prone, and not advisable. You should be using JSON to pass around data, it is not designed to do what you are trying to do. It is not connected to JavaScript beyond the syntax being based on JS objects, and has no concept of what anything beyond strings, numbers, booleans and lists of things are.

You will need to write a method that converts the methods on the object to properties of some kind (ie write a toJSON method for your specific class). Then in the reviver, you need to reinstantiate the object, somehow using those properties to rebuild what you had. Here is a question on Stack Overflow covering this ground: https://stackoverflow.com/questions/8111446/turning-json-strings-into-objects-with-methods

Wow thanks a lot for your advice. Even though my project was minimal I guess it still requires some proper database work.
The point of the project was just to practice some ES6 magic anyway before I delve into react ,node and other unknown territories.

Nope. Your issue here is that you’re aren’t thinking about what you’re trying to store.

A database stores data.

This database stores it as text, which is why you are converting JS objects to JSON.

And really, JSON has nothing to do with JS (or programming languages), it is just a standardised way of writing some information in a text format that is really easy to write programs to convert to/from whatever the equivalent of an object is in any given language.

You need to store a collection of entries.

You do not need to 1. take JavaScript code, 2. convert it to text form, 3 store it, 4. then later rebuild it, 5. then execute it. You can simplify steps 2, 3 and 4 by just not doing them: doing them will make life insanely difficult for yourself, for absolutely zero benefit.


So the todos, they are what you need to generate, and they need to be plain objects - no methods. The other parts of the program should act on those. It’s fine to use classes to build out the structure of your program, there’s no issue there at all. But those classes, with programmatic methods, they are your program - they are not the data that you are storing… So you could well have a Book class that deals with collections of Entry type objects, but you don’t store that Book class as it is now. It is good that you’re thinking along these lines but you need to have a bit more of a think about how you’re architecting things here