Store Backbone models in localStorage

It's time to use what you have learned about localStorage to store and retrieve objects. The DataStore object is responsible to transform models into strings to be stored in localStorage:

class DataStore {
  constructor(name) {
    this.name = name;

    // Keep track of all ids stored for a particular collection
this.index = this.getIndex();
  }

getIndex() {
var index = localStorage.getItem(this.name);
    return (index &&index.split(',')) || [];
  }
}

The DataStore object needs a name to be used as a collection index prefix. The first use case is to create a new item:

class DataStore {
// ...

  create(model) {
    // Assign an id to new models
    if (!model.id&& model.id !== 0) {
      model.id = generateId();
model.set(model.idAttribute, model.id);
    }

    // Save model in the store with an unique name,
    // e.g. collectionName-modelId
localStorage.setItem(
this.itemName(model.id), this.serialize(model)
    );

    // Keep track of stored id
this.index.push(model.get(model.idAttribute));
this.updateIndex();

    // Return stored model
    return this.find(model);
  }
}

When a new model is created, it assigns a new ID with a generateId()function:

var crispy = require('crispy-string');

const ID_LENGTH = 10;

function generateId() {
  return crispy.base32String(ID_LENGTH);
}

The itemName() function generates a key that is to be used in localStorage given the model ID; the serialize()method transforms a model into a JSON string that is ready to be stored in localStorage. Finally, the index attribute in DataStore tracks all the available IDs so that we should push the model ID in the index.

For the update method, we will overwrite the current value of the model:

class DataStore {
// ...

  update(model) {
    // Overwrite the data stored in the store,
    // actually makes the update
localStorage.setItem(
this.itemName(model.id), this.serialize(model)
    );

    // Keep track of the model id in the collection
varmodelId = model.id.toString();
    if (_.indexOf((this.index, modelId)) >= 0) {
this.index.push(modelId);
this.updateIndex();
    }

    // Return stored model
    return this.find(model);
  }
}

If you call the setItem() method with an existent key on localStorage, the previous value is overwritten with the new one, the net effect is an update operation.

When you are looking for a model, you need to set the ID of the model and call the fetch() method on it in order to retrieve the data from a server. In our DataStore, we can call this operation find:

class DataStore {
// ...

  find(model) {
    return this.deserialize(
localStorage.getItem(this.itemName(model.id))
    );
  }
}

The find() method is very simple, it tries to get the data from localStorege with an ID built with the itemName() method; if the model is not found, it will return a null value. While returning a single model is very simple, retrieving a list of them is a more complex operation:

class DataStore {
// ...

findAll() {
var result = [];

    // Get all items with the id tracked for the given collection
    for (let i = 0, id, data; i<this.index.length; i++) {
      id = this.index[i];
      data = this.deserialize(localStorage.getItem(
this.itemName(id)
      ));

      if (data) {
result.push(data);
      }
    }

    return result;
  }
}

This method loops over all the available keys for the given collection; for each item in the list, it converts it from string to a JSON object. All items are aggregated in a single array that returns as a result.

To remove an item from DataStore, you will need to remove its value from localStorage and drop the index that is related to it:

class DataStore {
// ...

  destroy(model) {
    // Remove item from the store
localStorage.removeItem(this.itemName(model.id));

    // Rmoeve id from tracked ids
varmodelId = model.id.toString();
    for (let i = 0; i<this.index.length; i++) {
      if (this.index[i] === modelId) {
this.index.splice(i, 1);
      }
    }
this.updateIndex();

    return model;
  }
}

We use the updateIndex() method when the collection of models is altered in localStorage; it should store a list of IDs as strings:

class DataStore {
// ...

  // Save the ids comma separated for a given collection
updateIndex() {
localStorage.setItem(this.name, this.index.join(','));
  }
}

Model IDs are generated with the name of the collection and its ID:

class DataStore {
// ...
itemName(id) {
    return this.name + '-' + id;
  }
}

The DataStore class, by itself, can store and retrieve models from localStorage; however, it is not fully integrated with Backbone. In the next section, we will examine how Backbone stores and retrieves models from a RESTful API and how to change this behavior to use the DataStore driver.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.37.38