Я вызываю loadUserData() в конструкторе службы. Но связанный наблюдаемый объект не определен, когда страница загружается в первый раз. Однако, когда я вызываю функцию загрузки явно из компонента, она работает. Пожалуйста, посмотрите две реализации в ngOnInit()
в файле component.ts. Эта услуга предоставляется с использованием интерфейса ModuleWithProviders
со статическим forRoot()
в app.module.ts. Если я вручную уйду, а затем вернусь на эту страницу, resumeData$
наблюдаемое сработает. и мне не нужно вызывать loadUserdata() из файла component.ts. Что мне здесь не хватает?
Загрузить файл службы данных
import { Injectable } from '@angular/core';
import { AngularFirestore } from '@angular/fire/firestore';
import { AngularFireAuth } from '@angular/fire/auth';
import { User } from '../model/user.model';
import { ResumeData } from '../model/resumeData.model';
import { Observable, of } from 'rxjs';
import { map, first } from 'rxjs/operators';
import { convertSnaps } from './db-utils';
import { Summary } from '../model/summary.model';
import { Category } from '../model/skill.model';
import { Education } from '../model/education.model';
import { CoreCompetency } from '../model/competency.model';
@Injectable()
export class LoadFirestoreDataService {
user: firebase.User | null;
summaryList$: Observable<Summary[]>;
categoryList$: Observable<Category[]>;
educationList$: Observable<Education[]>;
coreCompetencyList$: Observable<CoreCompetency[]>;
resumeData$: Observable<ResumeData[]>;
constructor(private db: AngularFirestore, private afAuth: AngularFireAuth) {
this.afAuth.authState.subscribe(user => {
if (user) {
this.user = user;
this.loadUserData();
} else {
this.user = null;
}
});
}
loadUserData(): Observable<ResumeData[]> {
// console.log(this.user);
const user = <User>JSON.parse(localStorage.getItem('user'));
// console.log(userId);
// if (user.uid) {
this.resumeData$ = this.db
.collection('users')
.doc(user.uid)
.collection('userData')
.snapshotChanges()
.pipe(map(snaps => convertSnaps<ResumeData>(snaps)));
return this.resumeData$;
}
}
Файл component.ts
ngOnInit() {
// Following does not work
this.dataService.resumeData$.subscribe(data => {
console.log(data);
});
// Following works
this.dataService.loadUserData().subscribe(data => {
console.log(data);
});
}
Правки: Только что обнаружил, что даже после успешной аутентификации функция loadUserData() не вызывалась из конструктора(). Сейчас ищу почему так.
Этот фрагмент кода был преобразован в следующую более удобочитаемую форму:
constructor(private db: AngularFirestore, private afAuth: AngularFireAuth) {
this.loadUserData();
}
loadUserData(): void {
const user = <User>JSON.parse(localStorage.getItem('user'));
this.resumeData$ = this.db
.collection('users')
.doc(user.uid)
.collection('userData')
.snapshotChanges()
.pipe(
map(snaps => {
return convertSnaps<ResumeData>(snaps)[0];
})
);
this.summaryList$ = this.resumeData$.pipe(pluck('summaryList'));
this.educationList$ = this.resumeData$.pipe(pluck('educationList'));
this.categoryList$ = this.resumeData$.pipe(pluck('categoryList'));
this.coreCompetencyList$ = this.resumeData$.pipe(pluck('coreCompetencyList'));
}
и файл component.ts выглядит следующим образом:
ngOnInit() {
this.summaryList$ = this.dataService.summaryList$;
}
подписка wan выполняется с использованием асинхронного канала:
<div *ngFor="let item of (summaryList$ | async) as summaryList; let i = index">
<app-summary-item [item]="item" [itemIndex]="i"></app-summary-item>
</div>
this.loadUserData()
даже не вернет наблюдаемое, на которое я могу подписаться позже? 21.05.2020async
каналы для предотвращения утечек памяти. Поэтому я переместил код в этом направлении 21.05.2020loadUserData()
заполняетresumeData$
, на которую вы пытаетесь подписаться позже. Итак, моя единственная подсказка для вас нерабочий код, чтоloadUserData()
почему-то скорее всего вообще не вызывается... Отлаживать поток пробовали? Какой Angular вы используете? Начиная с версии 6.0 вы можете использовать@Injectable({ providedIn: 'root' ,})
вместо решения статической функцииforRoot()
. В любом случае, пожалуйста, попробуйте создать stackblitz (с фиктивными / смоделированными данными), и я постараюсь вам помочь. 23.05.2020