Я пытаюсь подписаться на мой интерфейс и следить за изменениями, но у меня есть ошибки.

  1. Получение данных из API и назначение их профилю this.candidate:

     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.log(error) },
  () => {
    console.log('got profile', this.candidateProfile);
  })

 }

Component.ts:

this.auth.candidateProfile.subscribe( data => {
console.log(data)
})

Ошибка :

This.auth.candidateProfile.subscribe не является функцией

0
Devla 2 Май 2019 в 12:45

3 ответа

Лучший ответ

Изменить ваш сервис аутентификации, как показано ниже

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.log(error) },
            () => {
                console.log('got profile', data);
            })
    }

    get candidateProfile$(): Observable<CandidateProfile> {
      return this._candidateProfile$.asObservable();
    }
}

Тогда вы можете использовать как следующее:

this.auth.candidateProfile$.subscribe( data => {
console.log(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();
1
Yanis-git 2 Май 2019 в 10:00

Это не всегда лучший способ сделать что-то. Вы не должны возвращать наблюдаемое в вашем сервисном файле. Стандартная практика заключается в том, чтобы возвращать наблюдаемое на самом компоненте.

С точки зрения обработки ошибок, вы можете сделать это либо на вашем сервисе, либо на вашем компоненте. В приведенном ниже примере я буду обрабатывать ошибки компонента.

В вашем сервисе вам нужно будет добавить инструкцию возврата:

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.log(data)
}, error => {
  // handle error
});
1
wentjun 2 Май 2019 в 09:55

Когда вы подписываетесь на наблюдаемое, вы подписываетесь на его значение, которое не является наблюдаемым. Когда вы делаете:

this.candidateProfile = data;

По сути, вы сохраняете вандидат в профиле значение, которое вы получили из наблюдаемой. Конечно, эти данные больше не имеют функции «подписка», поскольку они не наблюдаемы.

Вы должны хранить в 'this.candidateProfile' саму наблюдаемую информацию, а не значение, которое вы получаете от нее. Вот так:

this.candidateProfile = this.http.get(`users/${id}`, httpOptions);

Надеюсь, что я вам помог, хорошего дня!

1
Giovanni Orciuolo 2 Май 2019 в 09:50