Search code examples
angularhttpclientbehaviorsubject

Angular5 - Behavior Subject resulting in undefined


I have through many Rxjs links and stackoverflow links but I am not able to figure this one out

I have a http.get() defined in a service. I am trying to emit the observable response in a Behavior subject and then subscribe to it (since behavior subject has advantages of feetching the last emitted stream of data I believe). Here are the service and component code

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));
     }

 }

The logger in comp always comes as undefined and actually the http service returns the values consumed after in comp

Could you kindly help me figuring out how to get the http emitted value from behavior subject


Solution

  • Please emit under the subscription. this.someResult might not be available when you emit.

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

    In your implementation, it is a Behavior Subject, so on your next get request I believe you should get the data from the previous request, unless this.someResult is getting reset anywhere else other than the subscription.