I have an app establishing connection with Firebase realtime db, through authWithCustomToken and fetches some data.
Flow is next:
Parent component => triggers Service (establishes connection) => Parent receives Data from Service and sends it to child component through binding. Child component has onChanges lifecycle hook to react on binding update.
Problem: onChange is not triggered when binding is updated
Service:
...
self.data = null;
self.authenticate = function() {
return $http.get('/api/v2/fbtoken')
.then(function(res) {
const ref = new Firebase(firebaseBaseUrl);
return ref.authWithCustomToken(
res.data,
saveData(error, authData);
);
});
};
function saveData(error, authData) {
if(error) {
return false;
}
self.data = authData;
return true;
}
self.getData() {
return self.data;
}
parent.component.html:
<child-component notification-list="ParentCtrl.notifications"></child-component notification-list>
parent.component.js:
...
function ParentCtrl(
Service
) {
const viewModel = this;
viewModel.notifications = null;
Service.authenticate()
.then((data) => {
viewModel.notifications = Service.getData();
});
}
child.component.js:
...
.component('childComponent', {
bindings: {
notificationList: '<'
},
templateUrl:
'someUrl',
controller:
'ChildCtrl as ChildCtrl'
})
...
function ChildCtrl() {
const viewModel = this;
viewModel.$onChanges = onChanges;
function onChanges(changes) {
if (changes) { // Not triggered
console.log('binding has changed');
}
}
}
I know that AngularJS doesn't know anything about native Promise, and change detection is not triggered. To force changeDetection we need to use $q library for that. But this example is using AngularJS $http client which returns $q.promise.
Wrapper Angularfire library for Firebase client is also returning a $q.promise under the hood:
FirebaseAuth = function($q, $firebaseUtils, ref) {
this._q = $q;
...
authWithCustomToken: function(authToken, options) {
var deferred = this._q.defer();
try {
this._ref.authWithCustomToken(authToken, this._utils.makeNodeResolver(deferred), options);
} catch (error) {
deferred.reject(error);
}
return deferred.promise;
}
If to comment part with authWithCustomToken => change detection is triggered, variable in Parent is changed, binding on child is updated, and onChanges hook also triggered.
But with authWithCustomToken part, variable in Parent is changed, but this change is not reflected on child's binding and onChanges hook is not triggered.
What am I missing here?