Я пытаюсь подписаться на свой интерфейс и следить за изменениями, но у меня возникают ошибки.
Получение данных из API и назначение их this.candidateProfile :
export interface CandidateProfile {
about: string,
c_id: {},
certificates_training: [],
city: string,
country: string,
currency: string,
email: string,
expectedpayhourly: boolean,
expectedpayhourlyend: number,
expectedpayhourlystart: number,
expectedpaymonthly: {},
expectedpaymonthlyend: number,
expectedpaymonthlystart: number,
experience: [],
firstname: string,
hobbies: {},
jobskills: [],
langugaes: {},
lastname: string,
personalskills: [],
photo: string,
remotework: boolean,
role: string,
studies: {},
willingtorelocate: {},
willingtorelocatecity: {},
worktype: string
}
Auth.service.ts :
candidateProfile: Observable<CandidateProfile>;
getProfile(id, token) {
const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
})
};
this.http.get(`users/${id}`, httpOptions).subscribe(data => {
this.candidateProfile = data;
},
(error) => { console.info(error) },
() => {
console.info('got profile', this.candidateProfile);
})
}
Компонент.ts :
this.auth.candidateProfile.subscribe( data => {
console.info(data)
})
ошибка :





Когда вы подписываетесь на наблюдаемое, вы подписываетесь на его значение, которое не является наблюдаемым. Когда вы делаете:
this.candidateProfile = data;
По сути, вы сохраняете в профиле кандидата значение, полученное из наблюдаемого. Конечно, у этих данных больше нет функции «подписаться», поскольку они не являются наблюдаемыми.
Вы должны хранить в 'this.candidateProfile' сам наблюдаемый объект, а не значение, которое вы получаете от него. Вот так:
this.candidateProfile = this.http.get(`users/${id}`, httpOptions);
Надеюсь, что я помог вам, хорошего дня!
каждый раз, когда вы подписываетесь на candidateProfile, будет выполняться новый запрос ajax, я думаю, это не то, что ожидается.
Почему? Вы будете подписываться на него только один раз, внутри компонента, который вы используете, или если вы используете службу, каждый раз, когда вы подписываетесь на наблюдаемую, возвращаемую вызовом службы. Вы также можете использовать функцию toPromise() для преобразования наблюдаемого объекта в обещание, если вам так удобнее. Обратите внимание, что вы потеряете все преимущества rxjs Observables, если сделаете это таким образом.
Цель состоит в том, чтобы получить текущий профиль кандидата. Я предполагаю, что это может потребоваться многим компонентам. В этом случае вы не хотите снова и снова запрашивать сервер для получения этой информации, но можете запросить ее только один раз, а затем использовать кэшированные данные. не нужно переключаться на обещание, просто использовал другой наблюдаемый поток, как это было предложено в моем ответе. Надежда теперь более ясна
Это не всегда лучший способ сделать что-то. Вы не должны возвращать наблюдаемое в свой служебный файл. Стандартная практика заключается в том, чтобы возвращать наблюдаемое на самом компоненте.
Что касается обработки ошибок, вы можете сделать это либо в своем сервисе, либо в своем компоненте. В примере, который я привожу ниже, я буду обрабатывать ошибки компонента.
В вашем сервисе вам нужно будет добавить оператор return:
getProfile(id, token) {
const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
})
};
return this.http.get(`users/${id}`, httpOptions);
}
На вашем component.ts вы подписываетесь на него, чтобы вернуть наблюдаемое значение:
this.auth.candidateProfile.subscribe( data => {
console.info(data)
}, error => {
// handle error
});
Но если я хочу поделиться профилем на всех своих страницах, не подписываясь на него на каждой странице?
В этом случае вы можете вернуть его в качестве наблюдаемого в своем сервисе. Однако вам все равно нужно будет выполнить необходимые действия, чтобы отписаться от него.
измените свою службу аутентификации, как показано ниже
export class AuthService {
private _candidateProfile$: BehaviorSubject<CandidateProfile> = new BehaviorSubject(null);
getProfile(id, token): void {
const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
})
};
this.http.get(`users/${id}`, httpOptions).subscribe(data => {
this._candidateProfile$.next(data);
},
(error) => { console.info(error) },
() => {
console.info('got profile', data);
})
}
get candidateProfile$(): Observable<CandidateProfile> {
return this._candidateProfile$.asObservable();
}
}
то вы можете использовать следующее:
this.auth.candidateProfile$.subscribe( data => {
console.info(data)
})
Экспликация
Цель состоит в том, чтобы иметь внутреннюю наблюдаемую на этом сервисе, которая будет транслировать ваш текущий профиль кандидата.
В любом месте вашего приложения вы можете подписаться на него и получить последний выбранный профиль без повторного запуска метода getProfile (и запроса ajax под капотом).
чтобы упростить потребление из AuthService, я создал магический геттер, чтобы абстрагировать его.
get candidateProfile$(): Observable<CandidateProfile> {
return this._candidateProfile$.asObservable();
}
возьмите свой BehaviorSubject и превратите его в простой Observable. В противном случае вы позволите AuthService потребителю перейти к вашему Observable, а это не то, что ожидается.
единственный способ транслировать новые CandidateProfile должен быть здесь:
this.http.get(`users/${id}`, httpOptions).subscribe(data => {
this._candidateProfile$.next(data);
});
Я также рекомендую вам изменить свой getProfile, как показано ниже
getProfile(id, token): Observable<CandidateProfile> {
// [...]
this.http.get(`users/${id}`, httpOptions).subscribe(data => {
this._candidateProfile$.next(data);
},
// [...]
);
return this.candidateProfile$;
}
Таким образом, вы можете использовать свой класс следующим образом:
// Fetch new profile.
this.auth.getProfile(id, token).subscribe();
// Fetch last requested profile.
this.auth.candidateProfile$.subscribe();
candidateProfileв не наблюдаемом, это простоCandidateProfile. Вместо этого вы должны подписаться на функциюgetProfile. И добавьRETURN this.http.get