'How to fix Angular Service Response to Component - Undefined

I am trying to read a value from API response and use this value from service class, and referring this service variable to all other components, since it is a global value comes from database.

My Component code below,

export class MyComponent implements OnInit {

  constructor(private dateService: DataService) {
  }

  ngOnInit(): void {
    const date = this.dateService.getRunningDay().toDate(); // Here its null
  }
  
}

My Service Class as follows,

@Injectable({
  providedIn: 'root'
})
export class DataService {
  
  constructor(private dateService: DateApiControllerService) {
  }
  
  getRunningDay(): Moment {
      this.dateService.handleGetExecutionDay().subscribe(data => {
        return data;
      });
  }

While debugging, before getRunningDay method subscribe comes with data, my component date value executed with null.

How to fix this issue?



Solution 1:[1]

Found a solution for this, I am missing BehaviorSubject's magic. Just wanted to share to someone if get the same issue in future.

My updated component with subscribe the variable in service class, which is BehaviorSubject type,

export class MyComponent implements OnInit {

  private date: Date;

  constructor(private dateService: DataService) {
  }

  async ngOnInit(): Promise<void> {
    this.dateService.date$.subscribe((data) => this.date = data.toDate());
    this.dayMonthYear = this.getDayName(this.date.getDay()) + ' ' + this.getMonthName(this.date.getMonth()) + ' ' + this.date.getDate() + ', ' + this.date.getFullYear();
  }

Updated DateService with BehaviorSubject,

@Injectable({
  providedIn: 'root'
})
export class DataService {

  runningDate: BehaviorSubject<Moment>;

  private date: BehaviorSubject<Moment> = new BehaviorSubject<Moment>(moment());
  date$: Observable<Moment>;

  constructor(protected httpClient: HttpClient, private dateService: DateApiControllerService, private spinner: NgxSpinnerService) {
    this.getRunningDay();
    this.date$ = this.date.asObservable();
  }
  
  
    getRunningDay(): any {
    if (this.runningDate?.value) {
      return this.runningDate.value;
    } else {
      this.dateService.handleGetExecutionDay().subscribe(data => {
        let value = moment(data, 'YYYY-MM-DD');
        this.date.next(value);
        return data;
      });
    }
  }
    

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 DevGo