Angular get data from api with ReplaySubject

Рейтинг: 0Ответов: 1Опубликовано: 08.02.2023

В компоненте я получаю юзера, далее я хочу установить в UserService свойство socialAccount (данные соц. аккаунта) по user.id и вернуть socialAccount обратно в компонент (загрузку юзера надо дождаться поэтому я использую switchMap - не знаю насколько это правильно), но я всегда получаю пустой массив [], во вкладке network я вижу что данные с бека приходят. Подскажите, как правильно решить мою задачу.

UserService

    export class UserService {
       private user:  BehaviorSubject<IUser | null> = new BehaviorSubject<IUser | null>(this.getUserFromLocalStorage()) // getUserFromLocalStorage() - устанавливаю начальное значение юзера из localStorage
      private socialAccount: Subject<ISocialAccount> = new ReplaySubject<ISocialAccount>(1);
    
      constructor(private http: HttpClient) { }
    
      getUser() {
        return this.user
      }
    
      getUserById(id: number): Observable<IUser> {
        return this.http.get<IUser>(`${environment.BASE_URL}:${environment.PORT}/api/users/${id}`)
      } 
      //Получаю соц. аккаунт по API и устанавливаю в this.socialAccount
      setSocialAccountByUserId(id: number): Observable<void> {
       
        return this.http.get<ISocialAccount>(`${environment.BASE_URL}:${environment.PORT}/api/users/${id}/social-account`).pipe(
          map((account: ISocialAccount) => {
            return this.socialAccount.next(account) 
          })
         )
      } 
    
      getSocialAccount(){
        return this.socialAccount
      }

......
    }

интерфейс - ISocialAccount

export interface ISocialAccount {
    id: number
    user_id: number
    provider_id: number
    provider: string
    token: string
  }

Мой компонет

export class EventCreateComponent implements OnInit {
  user: IUser[] = []
  socialAccount: ISocialAccount[] = []
  subscriptions: Subscription[] = []
  subscription_1: Subscription = new Subscription()
  subscription_2: Subscription = new Subscription()

  createEventForm: FormGroup = new FormGroup({})

  constructor(private userService: UserService) { }

  getUserWithSocialAccount(){
    this.subscription_1 = this.userService.getUser().pipe(
      switchMap((user:any) => {
        this.user = user
        return this.userService.setSocialAccountByUserId(user.id)
        .pipe(
          map(() => {
            // this.socialAccount = account
            this.getSocialAccount()
          })
        )
      }),
    )
    .subscribe()
  }

   getSocialAccount(){
    this.subscription_2 = this.userService.getSocialAccount().subscribe((socialAccount: any) => {
       this.socialAccount = socialAccount
    })
  }



  ngOnInit() {
    this.getUserWithSocialAccount()
    
    console.log(this.user)
    console.log(this.socialAccount) // пустой массив


    //Добавляем подписки в массив
 ...
  }

  ngOnDestroy(){
    // отписываемся от всех подписок
   ....
  }

}

ответ от бека введите сюда описание изображения

Ответы

▲ 0Принят

Чтобы получить массив в консоли на до установить SetTimer

console.log(this.user)
setTimeout(()=>
  console.log(this.socialAccount.provider)
,1000)

А в шаблоне проверить существует ли значение

<div *ngIf="socialAccount">{{ socialAccount.provider }}</div>