I'm using Angular 6 and Rxjs 6.
The following code will throw undefined at the ListFormsComponent
over and over and over until the Observable
is assigned by getForms()
at which it will then display the data. The getForms()
is called by the navigation service when attempting to navigate to ListFormsComponent
page.
FormService.ts
export class FormService {
public forms$: Observable <Array<Form>> ;
public assignedForms$: Observable <Array<Form>> ;
public form$: Observable <Form>;
constructor(
private afs: AngularFirestore,
private authService: AuthService,
) {}
getForms() {
let zippedData = zip(this.authService.user$);
zippedData.subscribe(data => {
this.forms$ = this.afs.collection('networks')
.doc(data[0].activeNetworkProfile.id)
.collection('companyProfiles')
.doc(data[0].activeCompanyProfile.id)
.collection<Forms>('inspectionForms')
.valueChanges();
})
}
}
ListFormsComponent.ts
export class ListFormsComponent implements OnInit {
public forms: Forms[];
constructor(private formService: FormService, private navigateService: NavigationService) {
this.formService.forms$.subscribe(forms => { //<---Error here this.formService.forms$ is undefined
this.forms = forms;
console.log("Forms inside component");
console.log(this.forms);
})
}
}
ListFormsComponent.html
<mbsc-listview [options]="listSettings" style="display:none">
<mbsc-listview-item (click)="viewDetails(form.id)" *ngFor="let form of forms">
<h3 class="mbsc-lv-txt">{{form.name}}</h3>
<p class="mbsc-lv-txt">{{form.lastEdited | date: 'medium'}} </p>
</mbsc-listview-item>
</mbsc-listview>
NavigationService.ts
navigateForms() {
this.formService.getForms();
this.navigateService.navigate('forms');
}
So I then decided to initialize the observable by doing the following code(see below) in the constructor of FormService.ts and it stops the errors but It does not trigger the subscription in the ListFormsComponent.ts
. I'm assuming when valueChanges()
returns the Observable
to forms$
it breaks rest of the subscriptions
.
this.forms$ = new Observable<Array<Forms>>();
So the issue is in this function:
navigateForms() {
this.formService.getForms();
this.navigateService.navigate('forms');
}
You've called this.formService.getForms();
which will initialize forms$
on FormService
. But simultaneously, you're also navigating to forms
which will render the ListFormsComponent
. In your ListFormsComponent
you're doing formService.forms$
which might not have initialized at that point. Hence you're getting it as undefined
.
Instead of using the forms$
, I would have simply returned the Observable
value from the getForms
method and I would have called it in the ListFormComponent
's ngOnInit
method:
export class FormService {
public forms$: Observable <Array<Form>> ;
public assignedForms$: Observable <Array<Form>> ;
public form$: Observable <Form>;
constructor(
private afs: AngularFirestore,
private authService: AuthService,
) {}
getForms() {
return zip(this.authService.user$).pipe(
flatMap(data => {
return this.afs.collection('networks')
.doc(data[0].activeNetworkProfile.id)
.collection('companyProfiles')
.doc(data[0].activeCompanyProfile.id)
.collection<Forms>('inspectionForms')
.valueChanges();
})
);
}
}
Then in the ListFormsComponent:
export class ListFormsComponent implements OnInit {
public forms: Forms[];
constructor(
private formService: FormService,
private navigateService: NavigationService
) { }
ngOnInit() {
this.formService.getForms().subscribe(forms => {
this.forms = forms;
console.log("Forms inside component");
console.log(this.forms);
});
}
}
Also, I won't need to call getForms
from navigateForms
now. So I could get rid of that:
navigateForms() {
this.navigateService.navigate('forms');
}