I am using the cordova file transfer and file plugins to go to a server and get some data and image. I am then saving this data to the device's storage, the data format is a .json file and some images. I am able to save all the data to the device.
My problem happens when I try to use that data. When I try to load the local data, I get
Failed to load resource: net::ERR_FILE_NOT_FOUND file:///android_asset/www/Android/data/com.mydomain.myApp/files/data.json
From the console log messages I can see that 'file:///android_asset/www/' is being added to the path when it is being called, is this correct?
I am using the angularjs $resource service.
var localData = $resource(filePath);
If anyone can help I would really appreciate it.
Are you sure that you are storing the files in the right folder?
Reading the Cordova File Plugin documentation you get this:
Where to Store Files
As of v1.2.0, URLs to important file-system directories are provided. Each URL is in the form file:///path/to/spot/, and can be converted to a DirectoryEntry using window.resolveLocalFileSystemURL().
cordova.file.applicationDirectory - Read-only directory where the application is installed. (iOS, Android, BlackBerry 10)
cordova.file.applicationStorageDirectory - Root directory of the application's sandbox; on iOS this location is read-only (but specific subdirectories [like /Documents] are read-write). All data contained within is private to the app. ( iOS, Android, BlackBerry 10)
cordova.file.dataDirectory - Persistent and private data storage within the application's sandbox using internal memory (on Android, if you need to use external memory, use .externalDataDirectory). On iOS, this directory is not synced with iCloud (use .syncedDataDirectory). (iOS, Android, BlackBerry 10)
cordova.file.cacheDirectory - Directory for cached data files or any files that your app can re-create easily. The OS may delete these files when the device runs low on storage, nevertheless, apps should not rely on the OS to delete files in here. (iOS, Android, BlackBerry 10)
cordova.file.externalApplicationStorageDirectory - Application space on external storage. (Android)
cordova.file.externalDataDirectory - Where to put app-specific data files on external storage. (Android)
cordova.file.externalCacheDirectory - Application cache on external storage. (Android)
cordova.file.externalRootDirectory - External storage (SD card) root. (Android, BlackBerry 10)
cordova.file.tempDirectory - Temp directory that the OS can clear at will. Do not rely on the OS to clear this directory; your app should always remove files as applicable. (iOS)
cordova.file.syncedDataDirectory - Holds app-specific files that should be synced (e.g. to iCloud). (iOS)
cordova.file.documentsDirectory - Files private to the app, but that are meaningful to other application (e.g. Office files). (iOS)
cordova.file.sharedDirectory - Files globally available to all applications (BlackBerry 10)
Based on this list my advice is for you to usually store files in cordova.file.dataDirectory doing this:
var targetPath = cordova.file.dataDirectory + filename + extension
var fileTransfer = new FileTransfer();
var uri = encodeURI("http://some.server.com/download.php");
fileTransfer.download(
uri,
targetPath,
function(entry) {
console.log("download complete: " + entry.toURL());
},
function(error) {
console.log("download error source " + error.source);
console.log("download error target " + error.target);
console.log("upload error code" + error.code);
},
false,
{
headers: {
"Authorization": "Basic dGVzdHVzZXJuYW1lOnRlc3RwYXNzd29yZA=="
}
}
);
It's both compatible with iOS and Android.
For example you can open your downloaded image using the targetPath
variable:
//On your controller assign it to the scope
$scope.targetPath = targetPath;
//then on your view just use it as the src for your img
<img ng-src="targetPath">
Ok, so I was doing this all wrong. Because the data is local I shouldn't be making a $resource
request. I have instead used readAsText(path, file)
from the ngCordova documentation.
Essentially when I am saving the data to a .json file it is being treated as a text file, I can then use the method about in conjunction with JSON.parse(data);
this can then be set to my scope and used in the same way as the remote data.
P.S. I have tried with both 'cordova.file.dataDirectory' and 'cordova.file.externalDataDirectory' and both worked in my tests. And the info offered by 'Fabio Antunes' in this post is worth a read.