I have an iframe in my template, src
refers to a physical html file.
<iframe id="myiframe" src="{{src}}">
</iframe>
In the controller, a function rewriteAllFiles
is called from time to time to update the physical html, js, css
files. It first removes all the old files, then write the new one, then refresh the iframe.
var refreshIframe = function () {
var iframe = document.getElementById('myiframe');
iframe.src = iframe.src;
console.log("refreshIframe, done")
}
rewriteAllFiles = function (path, files) {
return $http.post('/emptyDir', { dir: prefix + idP + "/", path: path })
.then(function (res) {
console.log("rewriteAllFiles /emptyDir, done");
return $http.post('/writeFiles', { dir: prefix + idP + "/", files: files })
.then(function (res) {
console.log("rewriteAllFiles /writeFiles, done");
refreshIframe();
return res
})
})
}
$scope.$watch(... {
return rewriteAllFiles($location.path(), $scope.files);
})
My test shows sometimes it works without error, but sometimes, it gives the following log:
rewriteAllFiles /emptyDir, done
GET http://localhost:3000/tmp/P0L7JSEOWux3YE1FAAA6/index.html 404 (Not Found)
rewriteAllFiles /writeFiles, done
refreshIframe, done
So it seems that after the old files are removed and before new files are written, the html template tries to load src
, and of cause the file is temporarily unavailable. I did not set a watcher for src
, does anyone know where is the listener to src
, and how to disable it?
Edit 1: here is the code of writeFiles
in the server side:
router.post('/writeFiles', function (req, res, next) {
var dir = req.body.dir, files = req.body.files;
var fs = require('fs');
var queue = files.map(function (file) {
return new Promise(function (resolve, reject) {
fs.writeFile(dir + file.name, file.body, function (err) {
if (err) return reject(err);
console.log(dir + file.name + " is written");
resolve(file);
})
})
});
Promise.all(queue)
.then(function(files) {
console.log("All files have been successfully written");
res.json(dir);
})
.catch(function (err) {
return console.log(err)
});
});
I realise that it is related to another line of code in the controller.
$scope.src = getSrc() // getSrc(); returns the right html link initiated by a resolving
$scope.$watch(... {
return rewriteAllFiles($location.path(), $scope.files);
})
When we load the template, the above code has a possibility that $scope.src = getSrc()
is executed just after after the old files are removed and before new files are written, which raises a Not Found
error.
So we just need to make sure the execution order by then
; the following code works:
$scope.$watch(... {
return rewriteAllFiles($location.path(), $scope.files)
.then(function () {
$scope.src = getSrcP();
});
});