BehaviorSubject не может получить значение с подпиской

В моем угловом приложении

Я сделал несколько попыток получить значения, используя BehaviorSubject, чтобы узнать, когда значение было изменено или получено. Я не могу получить значения до загрузки компонента.

По этой ссылке вы можете увидеть, что вы возвращаете:

https://dev.moip.com.br/v1.5/reference

data.service.ts:

dataOnChanged: BehaviorSubject<any> = new BehaviorSubject({});

getData() {
    return new Promise((resolve, reject) => {
        this.http.get(this.api_URL + 'plans/, this.httpOptions).subscribe((data: any) => {

            // the result is
            // data = {plans: Array(5)}

            this.dataOnChanged.next(data);
            resolve(data);
        },
            (response: any) => {
                reject(response.error);
            });
    });
}

resolve.service.ts:

constructor(
    private dataService: DataService, {
}

* Resolve
 * @param {ActivatedRouteSnapshot} route
 * @param {RouterStateSnapshot} state
 * @returns {Observable<any> | Promise<any> | any}
 */
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<any> | Promise<any> | any {
    return new Promise((resolve, reject) => {
        Promise.all([
            this.dataService.getData()
        ]).then(
            () => {
                resolve();
            },
            reject
        );
    });
}

routes.module.ts:

        {
            path: 'home',
            component: HomeComponent,
            resolve: {
                data: ResolveService,
            },
        },

home.component.ts:

constructor(
    public data: DataService,
) {

    this.dataService.dataOnChanged.subscribe((result: any) => {
        // no result
        debugger;
    });

Проблема в том, что я не могу загрузить данные, возвращаемые HTTP GET, до загрузки компонента. Мне нужно загрузить данные раньше и показать экран.

2 ответа

Я думаю, что лучший способ получить значение будет получить его из ActivatedRoute

В вашем компоненте, если вы вводите ActivatedRoute:

constructor(ars: ActivatedRoute) {
  console.log(ars.snapshot.data.data) // This will log your value here
}

Таким образом, вам не нужен BehaviourSubject.

Вот пример на StackBlitz.

Когда вы посещаете маршрут /about, он получает значение с задержкой в ​​2 секунды, чтобы продемонстрировать

Использование BehaviorSubject здесь избыточно, вместо этого вы можете получить доступ к разрешенным данным, используя data свойство объекта снимка ActivatedRoute или подписаться на ActivatedRoute data Свойство, которое содержит статические и разрешенные данные текущего маршрута
Рекомендуется использовать Observables над обещаниями. При переходе к обещанию вы потеряете возможность отмены запроса и возможность связывать операторов RxJS.

Из документов

  1. Положитесь на маршрутизатор, чтобы вызвать распознаватель. Не беспокойтесь обо всех способах навигации пользователя. Это работа роутера. Напишите этот класс и позвольте роутеру взять его оттуда.

  2. Наблюдаемое, предоставленное маршрутизатору, должно быть завершено. Если наблюдаемое не завершено, навигация не будет продолжена.

data.service.ts:

 getData():Observable<any> {
        return this.http.get(this.api_URL + 'plans/, this.httpOptions);
            }

resolve.service.ts:

import { Injectable } from '@angular/core';
    import { Resolve } from '@angular/router';
   import {Observable} from 'rxjs';

    @Injectable()
    export class resolver implements Resolve<Observable<any>> {
      constructor(private service:Service) {}

      resolve() {
        return this.dataService.getdata();
      }
    }

routes.module.ts:

 {
            path: 'home',
            component: HomeComponent,
            resolve: {
                data: resolver,
            },
        },

home.component.ts:,

  constructor( private route:ActivatedRoute) {
                 this.route.data.subscribe(value=>{
                       console.log(value);
                       });}

или же

 constructor( private route:ActivatedRoute) {
                 this.item=this.route.snapshot.data;
                    console.log(this.route.snapshot.data);
                     }

STACKBLITZ DEMO

Другие вопросы по тегам