Hi all, I’m updating the model within the constructor of my class, but the changes on the model are not visible, when clicking something or navigating back, the fields are updated.
The stuff done in the class:
constructor(public navCtrl: NavController, public navParams: NavParams, public loadingCtrl: LoadingController, public alertCtrl: AlertController, public profilData: ProfilData, public authData: AuthData) {
this.loading = this.loadingCtrl.create({
content: 'Lade Daten',
dismissOnPageChange: true
});
this.loading.present();
this.navCtrl = navCtrl;
this.profilData = profilData;
// Data is loaded async. The userProfil is used by the model
this.profilData.getUserProfile().on('value', (data) => {
this.userProfile = data.val();
this.birthDate = this.userProfile.birthDate;
this.loading.dismiss();
});
ProfilData does not look idiomatic. Ordinarily such services return futures such as Observables or Promises, and if you make it do that, things should start working as you expect.
Hi,it’s an firebase service, see how PrfilData is called:
import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
import firebase from 'firebase';
import 'rxjs/add/operator/map';
@Injectable()
export class ProfilData {
// Create a database reference to the userProfile node
userProfile: any;
// Create an auth reference to the logged user
currentUser: any;
/**
* Create the references from above
*/
constructor(public http: Http) {
this.currentUser = firebase.auth().currentUser;
this.userProfile = firebase.database().ref('/userProfile');
}
/**
* This function returns a Database reference to the userProfile/uid
* of the current user an we'll use it to get the user profile in our page
*/
getUserProfile(): any {
return this.userProfile.child(this.currentUser.uid);
}
Firebase is delivering promises… or did I missunderstood something?
one solution is to wrap it in a zone… not sure it is the best, but it will work.
import {NgZone} from '@angular/core';
Be sure to add to constructor…
constructor(private zone: NgZone) {}
use in callback
// Data is loaded async. The userProfile is used by the model
this.profilData.getUserProfile().on('value', (data) => {
this.zone.run(() => {
this.userProfile = data.val();
this.birthDate = this.userProfile.birthDate;
this.loading.dismiss();
})
});
I hate disagreeing with @aaronksaunders, but I feel strongly that direct use of zones in client code should be discouraged. As far as is humanly possible, zones should be treated as an opaque implementation detail of Angular and all interaction with them should be isolated to shim libraries that wrap and return zone-aware futures.
I think this is really the best solution, which is what I was implying about shim libraries. I do not have any knowledge as the pros and cons of options here, if there are even multiple such.