Manage Data

Almost every aspect of app development involves some element of sending or receiving data. Starting with the basics, you should use an MVC framework to help you design and implement your app so that data is completely separate from the app's view on that data (see MVC Architecture).

You also need to think about how data is handled when your app is offline (see Offline First). This doc briefly introduces the storage options for sending, receiving, and saving data locally; the remainder of the doc shows you how to use Chrome's File System API (see also the fileSystem API).

API Samples: Want to play with the code? Check out the filesystem-access and storage samples.

Storage options

Packaged apps use many different mechanisms to send and receive data. For external data (resources, web pages), you need to be aware of the Content Security Policy (CSP). Similar to Chrome Extensions, you can use cross-origin XMLHttpRequests to communicate with remote servers. You can also isolate external pages, so that the rest of your app is secure (see Embed external web pages). With Web Intents, your app can share data with other apps (see Connect Apps with Web Intents).

When saving data locally, you can use the Chrome Storage API to save small amounts of string data and IndexedDB to save structured data. With IndexedDB, you can persist JavaScript objects to an object store and use the store's indexes to query data (to learn more, see HTML5 Rock's Simple Todo List Tutorial). For all other types of data, like binary data, use the Filesystem API.

Chrome's Filesystem API extends the HTML5 FileSystem API; apps can create, read, navigate, and write to a sandboxed section of the user's local file system. With Chrome's File System API, packaged apps can read and write files to user-selected locations. For example, a photo-sharing app can use the File System API to read and write any photos that a user selects.

Adding file system permission

To use Chrome's File System API, you need to add the "fileSystem" permission to the manifest, so that you can obtain permission from the user to store persistent data.

"permissions": [
  "...",
  "fileSystem"
]

User-options for selecting files

Users expect to select files in the same way they always do. At a minimum, they expect a 'choose file' button and standard file-chooser. If your app makes heavy use of file-handing, you should also implement drag-and-drop (see below and also check out Native HTML5 Drag and Drop).

If your app connects with other apps using Web Intents you can set up data sharing with those apps. Users can view and/or write to their files using a connected app without having to do all sorts of extra steps to move files back and forth.

Obtaining the path of a fileEntry

To get the full path of the file the user selected, fileEntry, call getDisplayPath():

function displayPath(fileEntry) {
  chrome.fileSystem.getDisplayPath(fileEntry, function(path) {
    console.log(path)
  });
}

Implementing drag-and-drop

If you need to implement drag-and-drop selection, the drag-and-drop file controller (dnd.js) in the filesystem-access sample is a good starting point. The controller creates a file entry from a DataTransferItem via drag-and-drop. In this example, the fileEntry is set to the first dropped item.

var dnd = new DnDFileController('body', function(data) {
  var fileEntry = data.items[0].webkitGetAsEntry();
  displayPath(fileEntry);
});

Reading a file

The following code opens the file (read-only) and reads it as text using a FileReader object. If the file doesn't exist, an error is thrown.

var chosenFileEntry = null;

chooseFileButton.addEventListener('click', function(e) {
  chrome.fileSystem.chooseEntry({type: 'openFile'}, function(readOnlyEntry) {
 
    readOnlyEntry.file(function(file) {
      var reader = new FileReader();

      reader.onerror = errorHandler;
      reader.onloadend = function(e) {
        console.log(e.target.result);
      };

      reader.readAsText(file);
    });
	});
});

Writing a file

The two common use-cases for writing a file are "Save" and "Save as". The following code creates a writableEntry from the read-only chosenFileEntry and writes the selected file to it.

 chrome.fileSystem.getWritableEntry(chosenFileEntry, function(writableFileEntry) {
    writableFileEntry.createWriter(function(writer) {
      writer.onerror = errorHandler;
      writer.onwriteend = callback;

    chosenFileEntry.file(function(file) {
      writer.write(file);
    });   
  }, errorHandler);
});

The following code creates a new file with "Save as" functionality and writes the new blob to the file using the writer.write() method.

chrome.fileSystem.chooseEntry({type: 'saveFile'}, function(writableFileEntry) {
    writableFileEntry.createWriter(function(writer) {
      writer.onerror = errorHandler;
      writer.onwriteend = function(e) {
        console.log('write complete');
      };
      writer.write(new Blob(['1234567890'], {type: 'text/plain'}));  
    }, errorHandler);
});

Back to top