I am using electron-json-storage
and I'm attempting to set an AngularJS $scope
variable equal to the data stored.
Below is my code:
portal.controller('portalViewController', function($scope) {
//$scope.url = "http://www.google.com"; //correctly sets $scope.url to google.com
storage.get('portal_url', (err, data) => {
console.log(data.url); //prints out data as it should
$scope.url = data.url;
});
});
As you can see, I have each individual component of this working, but when I combine them, the $scope.url
does not seem to be getting set. I've been stuck on this for a while now and can't figure out what the issue is. I'm fairly new to AngularJS so this may be something really simple that I'm missing.
Thanks for any help you can provide!
As storage
seems to be a third party plugin, so any change in the $scope
does not execute the digest cycle. Use $timeout
to force a digest cycle so as the changes gets rendered in UI.
portal.controller('portalViewController', function($scope, $timeout) {
storage.get('portal_url', (err, data) => {
console.log(data.url); //prints out data as it should
$timeout(function(){
$scope.url = data.url;
});
});
});
If the callback is truly from a third-party source outside the AngularJS execution context, one can simply use $apply
:
portal.controller('portalViewController', function($scope) {
storage.get('portal_url', (err, data) => {
$scope.$apply(function() {
$scope.url = data.url;
});
});
});
From the Docs:
AngularJS modifies the normal JavaScript flow by providing its own event processing loop. This splits the JavaScript into classical and AngularJS execution context. Only operations which are applied in the AngularJS execution context will benefit from AngularJS data-binding, exception handling, property watching, etc... You can also use
$apply()
to enter the AngularJS execution context from JavaScript.Keep in mind that in most places (controllers, services)
$apply
has already been called for you by the directive which is handling the event. An explicit call to$apply
is needed only when implementing custom event callbacks, or when working with third-party library callbacks.
— AngularJS Developer Guide - Integration with the browser event loop
One can integrate a callback-based API into the AngularJS framework by creating a service:
app.service("storageAPI", function($q) {
this.get = function(url) {
var deferred = $q.defer();
storage.get(url, (err, data) => {
if (err) {
deferred.reject(err);
} else {
deferred.resolve(data);
};
});
return deferred.promise;
};
});
Usage:
app.controller('portalViewController', function($scope, storageAPI) {
storageAPI.get('portal_url')
.then(function(data) {
$scope.url = data.url;
}).catch(function(err) {
console.log(err);
});
});
The advantage of this approach is that it integrates the API into the AngularJS framework without the need of $apply
(the $q service does that automatically). In addition, it robustly handles errors from the API.
For more information, see - AngularJS $q Service API Reference - The Deferred API .
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.