I'm just started building a ionic phonegap app. I am saving json objects or html in a textfile which come from a service so when the app is offline, users still see content. I can read the files and get the objects or html and assign them to my scope variables but my app rarely shows the content. I'm using weinre to debug and it shows me the html from the file but angular is not binding it. Hope someone can help me out.
controller
.controller('infoController', function($rootScope, $scope, $ionicNavBarDelegate, $ionicPopup, CustomContent, CordovaFileSystem, CordovaNetwork){
if($rootScope.online){
console.log('info CTRL online');
CustomContent.getContent('AppInfoTekst').success(function(content){
CordovaFileSystem.saveObject(content.HTML.Data[0].Data, "infotekst.txt", true);
$scope.infoText = content.HTML.Data[0].Data;
});
}
else {
CordovaFileSystem.getObject("infotekst.txt").then(function(data){
console.log(data);
if(data != ""){
$scope.infoText = data;
}
});
}
$scope.back = function() {
$ionicNavBarDelegate.back();
};
})
factory
.factory("CordovaFileSystem", function(){
return {
saveObject: function(object, filename, isJson){
//console.log('save to ' + filename);
if(!isJson)
{
console.log(JSON.stringify(object));
}
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, gotFs, fail);
function gotFs(fileSystem) {
fileSystem.root.getFile("rotterdam/" + filename ,{create: true, exclusive:false},gotFileEntry, fail);
}
function gotFileEntry(fileEntry) {
fileEntry.createWriter(gotFileWriter, fail);
}
function gotFileWriter(writer){
writer.write(object);
}
function fail(error){
console.log(error);
}
},
getObject: function(filename){
return {
then: function(hasObject){
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, gotFS, fail);
function gotFS(fileSystem) {
fileSystem.root.getFile("rotterdam/" + filename, null, gotFileEntry, fail);
}
function gotFileEntry(fileEntry) {
fileEntry.file(gotFile, fail);
}
function gotFile(file){
readAsText(file);
}
function readAsText(file){
var reader = new FileReader();
reader.onloadend = function(evt) {
hasObject(evt.target.result);
};
reader.readAsText(file);
}
function fail(evt) {
console.log('error');
hasObject("");
}
}
}
}
})
html
<ion-view hide-nav-bar="true">
<ion-header-bar title='' align-title="center" class="bar-light" >
<div class="buttons">
<a class="button button-icon ion-arrow-left-a" ng-click="back()">
</a>
</div>
<h1 class="title"><img class="title-image" src="img/logo.png" /></h1>
</ion-header-bar>
<ion-content class="has-header padding">
<h2>Informatie</h2>
<div ng-bind-html="infoText"></div>
</ion-content>
</ion-view>
In your controller, the Cordova file system operations are happening outside of the Angular life cycle. For example here while you are updating the $scope variable, Angular doesn't know to update itself because the callback is not part of the Angular API.
CordovaFileSystem.getObject("infotekst.txt").then(function(data){
console.log(data);
if(data != ""){
$scope.infoText = data;
}
});
Angular has to know about changes, because it will initiate a $digest loop which handles the update of any bindings.
Here are two options.
$scope.$digest();
I would recommend using the ngCordova File package. It makes a nice Angular service for the Cordova File plugin. See the docs here http://ngcordova.com/docs/ and scroll to the $cordovaFile details. Manually triggering a $digest cycle can have side effects (you get errors if one happens to be in progress already).