'BehaviorSubject in angular returning null null
I am using BehaviorSubject to store some form data info, but for some reason, the info returned by BehaviorSubject is null. myService.ts
taskData$: BehaviorSubject<any> = new BehaviorSubject({});
<sc-form-wrapper>
<div class="button-wrap">
<div class="input-text-container">
<sc-text-input id="taskName" (onFocusout)="getTaskName($event)"
[required]="true"
label="Task Name"
size="md">
</sc-text-input>
</div>
</div>
<div class="">Task Colors</div>
<div *ngFor="let code of taskdata; let i = index" class="radio-container">
<ng-container>
<div class="radio-task-list">
<input id="{{ 'radio-' + i }}" class="radio-custom" name="radio-group" type="radio" (change)="selectTaskCode($event,code)">
<label for="{{ 'radio-' + i }}" class="radio-custom-label tag-color-{{i}}"></label>
</div>
</ng-container>
</div>
</sc-form-wrapper>
task.create.component.ts
import { Component, OnInit, Renderer2 } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { SetTask } from '../../models/task.model';
import { TaskSetCode } from '../../models/task-set-code.model';
import { ErrorHandlerService } from '../../services/error-handler.service';
import { TaskListService } from '../../services/task-list.service';
@Component({
selector: 'app-task-create',
templateUrl: './task-create.component.html',
styleUrls: ['./task-create.component.css']
})
export class TaskCreateComponent implements OnInit {
private destroy$: Subject<boolean> = new Subject<boolean>();
setTask: SetTask;
selectedTaskName: any;
selectedTaskCode: any;
setTaskData: any;
disableCreateButton: boolean = true;
taskSetCode: TaskSetCode = new TaskSetCode();
selectedTaskData: any;
constructor(
private errorHandlerService: ErrorHandlerService,
private taskService: TaskListService,
private router: Router,
private activeRoute: ActivatedRoute,
private renderer: Renderer2
) { }
ngOnInit(): void {
this.setTask = {
taskName: "",
taskCode: "",
createdBy: ""
};
this.createButtonDisable();
}
ngOnDestroy(): void {
this.destroy$.next(true);
this.destroy$.complete();
}
//Getting the task name
getTaskName(event) {
Object.defineProperty(this.setTask, event.controlName, { value: event.value });
this.selectedTaskName = this.setTask.taskName;
if (event.controlName === "taskName" && event.value !== undefined) {
this.disableCreateButton = false;
} else {
this.disableCreateButton = true;
}
this.createButtonDisable();
const setTaskData: SetTag = {
taskName: this.selectedTaskTaskName,
taskCode: this.selectedTaskCode,
};
this.createButtonDisable();
}
//Getting the selected task code
selectTaskCode(e, Code: string) {
this.selectedTaskCode = code;
const setTaskData: SetTag = {
taskName: this.selectedTaskTaskName,
taskCode: this.selectedTaskCode,
};
this.setTaskData = setTaskData;
if (this.selectedTaskCode == '' && this.selectedTaskName == '' ) {
this.disableCreateButton = true;
} else {
this.disableCreateButton = false;
}
this.createButtonDisable();
}
createButtonDisable() {
if (this.setTaskData !== undefined) {
this.taskService.taskData$.next(this.setTaskData);
}
}
}
Trying to subscribe the data in task-list.component and trying to get the data, but getting null value
import { Component, EventEmitter, OnInit, Output } from '@angular/core';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { TaskListService } from '../../services/task-list.service';
import { TaskCreateComponent } from '../task-create/task-create.component';
import { ModalService } from 'model-components';
@Component({
selector: 'app-task-list',
templateUrl: './task-list.component.html',
styleUrls: ['./task-list.component.css']
})
export class TaskListComponent implements OnInit {
private destroy$: Subject<boolean> = new Subject();
taskData: any;
constructor(
public taskService: TaskListService
) { }
ngOnInit(): void {
}
ngOnDestroy(): void {
this.destroy$.next(true);
this.destroy$.unsubscribe();
}
createTask(): void {
const ref = this.modalService.openModal('Create Task', TaskCreateComponent,
{
cancelText: 'Cancel',
submitText: 'Create'
}
);
const modalCompInstance: any = ref.componentInstance;
modalCompInstance.modalEvent.subscribe((event) => {
const type = event.type;
if (type !== 'submit') {
ref.close();
return;
}
else {
this.saveTag();
ref.close();
}
});
}
saveTask() {
this.taskService.taskData$.pipe(takeUntil(this.destroy$))
.subscribe((tasks: any) => {
this.taskData = tasks;
});
}
}
Can you please point out the issue or guide me?
Solution 1:[1]
You need to call your saveTask in your ngOnInit lifecycle hook within your TaskListComponent
ngOnInit() {
this.saveTask();
}
ngOnInit will listen for any changes emitted by your special observable taskData$
Also, it is a good practice to have functions within your service to handle your subject, you want only your service nexting the values, with this approach, it is also easier for testing purposes
export class YourService {
private theSubject = new BehaviorSubject({});
getTasks(): Observable<any> {
return this.theSubject.asObservable();
}
nextMyValue(value: any): void {
this.theSubject.next(value);
}
}
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 |
