Angular5 - Тема поведения, приводящая к неопределенности

У меня есть много ссылок Rxjs и ссылок stackoverflow, но я не могу понять это.

У меня есть http.get(), определенный в службе. Я пытаюсь выдать наблюдаемый ответ в субъекте поведения, а затем подписываюсь на него (поскольку субъект поведения имеет преимущества в отношении последнего испускаемого потока данных, я полагаю). Вот сервис и код компонента

SearchService.ts

import { ReplaySubject } from 'rxjs/Rx';
import { error } from 'util';
import { Subject } from 'rxjs/Subject';

import { Response } from '@angular/http';

import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';

import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import {Promotion} from './dto/promo.dto';
import { List } from 'immutable';
import {map, filter, reduce, switchMap, tap} from 'rxjs/operators';


@Injectable()
export class SearchService {
   getUrl: String = './../assets/promotionList.json';
   subject: BehaviorSubject<Promotion[]> ; 
   subjectAsObservable;
   stringify  = require('json-stringify-safe');

   someResult;
   constructor(private http: HttpClient) {
   this.subject = new BehaviorSubject<Promotion[]>([]);

   }
    getNextObservable():Observable<Promotion[]>{
      return this.subject.asObservable(); 
    }
    setValueInSubject(){
       this.getPromoList().subscribe(data => {
       this.someResult = data;
       console.log('getting some result', this.someResult);
      });
  this.subject.next(this.someResult);
}


getPromoList(): Observable<Promotion[]>{

  return this.http.get(`${this.getUrl}`).map(data => {
    console.log('raw data', data);

    this.someResult = data;
    console.log('someresults in first method', this.someResult);
    return this.someResult;
    // now the response returned is the actual Promotion response
  });

 }
}

SearchPromoComponent.ts

import { NgxLoggerLevel } from 'ngx-logger';
import { retry } from 'rxjs/operator/retry';
import { Subject } from 'rxjs/Subject';
import { ActivatedRoute } from '@angular/router';
import { setTimeout } from 'timers';


import { Response } from '@angular/http';

import { FormBuilder, FormGroup, FormControl, Validators, 
ReactiveFormsModule } from '@angular/forms';

import { Observable } from 'rxjs/Observable';
import { Subscription } from 'rxjs/Subscription';
import { debounceTime, filter, flatMap, map, switchMap, tap } from 
'rxjs/operators';

import { Promotion } from './../dto/promo.dto';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import { SearchService } from './../search.service';
import { AfterViewChecked, AfterViewInit, Component, OnDestroy, OnInit 
 } from '@angular/core';
import { NGXLogger } from 'ngx-logger';

@Component({
  selector: 'app-search-promo',
  templateUrl: './search-promo.component.html',
  styleUrls: ['./search-promo.component.css']
})
export class SearchPromoComponent implements  OnInit{
  searchGroup: FormGroup;
  stringify  =  require('json-stringify-safe');
  someResult: any;
  promoList: Promotion[];
  subsc: Subscription;
   subValue;
  localInput = new FormControl('', Validators.required);
       consumedPromoList: Observable<Promotion[]>;
       loading: Boolean = false;


  compSubscription: Subscription;
  // Use activated route to get the data from
  constructor(private searchService: SearchService, fb: FormBuilder,
     private paramConfig: ActivatedRoute,
     private logger: NGXLogger,
     private subjectPromoService: SubjectPromoService
  ) {
     this.searchGroup = fb.group({
  'localInput': this.localInput
  });

   }

    ngOnInit(){

       // inorder for the subject subscription to work
       // call like this

       this.searchService.setValueInSubject();

       this.subsc = 
       this.searchService.getNextObservable().subscribe(data => 
       console.log('in comp', data));
     }

 }

Регистратор in comp всегда приходит как неопределенный, и на самом деле служба http возвращает значения, использованные после in comp

Не могли бы вы помочь мне выяснить, как получить испускаемое http значение из темы поведения


person vijayakumarpsg587    schedule 30.05.2018    source источник


Ответы (2)


Пожалуйста, выдавайте по подписке. this.someResult может быть недоступен, когда вы испускаете.

setValueInSubject(){
   this.getPromoList().subscribe(data => {
       this.someResult = data;
       console.log('getting some result', this.someResult);
       this.subject.next(this.someResult);
  });
}

В вашей реализации это Behavior Subject, поэтому я считаю, что при следующем запросе на получение вы должны получить данные из предыдущего запроса, если только this.someResult не сбрасывается где-либо еще, кроме подписки.

person Ashish Ranjan    schedule 30.05.2018
comment
ты прав Ашиш. this.someresults не определено, но через некоторое время журнал печатается со значениями. Итак, вы хотите, чтобы я подписался на getPromoList() в компоненте? - person vijayakumarpsg587; 30.05.2018
comment
Да, Аших, как упомянул выше Шраван, мне следует подписаться на тему напрямую и включить изменения subject.next() в подписку. Однако, спасибо :) - person vijayakumarpsg587; 30.05.2018
comment
@ Joey587: Я не думаю, что есть какие-то проблемы с тем, как вы подписываетесь на Subject, вы делаете это observable, помещаете это в метод и подписываетесь на него. Это должно работать нормально по моему мнению. Не так ли? - person Ashish Ranjan; 30.05.2018
comment
@ Joey587: Тогда я думаю, что лучше не публиковать Subject. Публичный доступ дает свободу манипулировать Subject из любого места. ты же не хочешь этого, верно? Вы хотите, чтобы getter (как Observable) был общедоступным. Любой может прослушать изменения, но не может изменить значение самостоятельно.. - person Ashish Ranjan; 04.06.2018
comment
это имеет смысл. Ты прав. Думаю, ваш ответ следует пометить как более подходящий. - person vijayakumarpsg587; 04.06.2018

В вашем сервисе переместите this.subject.next внутрь subscribe и в component subscribe к этому subject

Сервис:

  setValueInSubject(){
       this.getPromoList().subscribe(data => {
        this.someResult = data;
        console.log('getting some result', this.someResult);
        this.subject.next(this.someResult);
      });
  }

В вашем компоненте:

 ngOnInit(){

   this.searchService.setValueInSubject();
   this.subsc = 
   this.searchService.subject.subscribe(data => 
   console.log('in comp', data)
   );
 }
person Sravan    schedule 30.05.2018
comment
Рад помочь вам. :-) - person Sravan; 30.05.2018
comment
@ Joey587, что случилось с моим ответом? - person Sravan; 04.06.2018
comment
нет шравана. Кажется, ответ ashish был более актуален для POC, который я разрабатывал. Подписка как на тему, так и на метод работает нормально, но кажется, что сделать тему частной и использовать метод для установки и подписки было более безопасным по сравнению с тем, что я пытался реализовать. - person vijayakumarpsg587; 04.06.2018