Populate reactive form with date retrieved from ngrx store
Problem Description:
I want to populate a form with data from store, but whatever I try (setValue, patchValue), the form is still empty
export class MyComponent implements OnInit, OnDestroy {
public newsletterToEdit$: Observable<NewNewsletter> =
this.store.selectNewsletterToEdit();
public form = this.fb.group({
title: ['', Validators.required],
subtitle: ['', Validators.required],
message: ['', Validators.required],
users: [''],
groups: [''],
searchedUsers: [''],
searchedGroups: [''],
allowReplies: [false, Validators.required],
replyFrom: ['NONE'],
});
ngOnInit(): void {
// this.newMessageForm.controls[‘title’].setValue(‘test title’); -> this works, it populates control with the string
this.newsletterToEdit$.pipe(
tap((newsletter) => {
console.log('newsletter to edit: ', newsletter);
// this.newMessageForm.patchValue(newsletter) -> another try
this.form.setValue({
title: newsletter.title,
allowReplies: null,
groups: newsletter.sentToGroupCode[0],
message: newsletter.message,
replyFrom: 'NONE',
searchedGroups: '1',
searchedUsers: '2',
subtitle: newsletter.subtitle,
users: '3',
});
})
);
}
}
I already checked, I do have data in store, but it seems that the console log is never logged so this means pipe(tap()) are not called
Solution – 1
The reason is that ngrx selectors provide cold observables. Cold observables do not emit any data until someone subscribes to it.
Try using
this.newsletterToEdit$.subscribe(
(newsletter) => {
console.log('newsletter to edit: ', newsletter);
// this.newMessageForm.patchValue(newsletter) -> another try
this.form.setValue({
title: newsletter.title,
allowReplies: null,
groups: newsletter.sentToGroupCode[0],
message: newsletter.message,
replyFrom: 'NONE',
searchedGroups: '1',
searchedUsers: '2',
subtitle: newsletter.subtitle,
users: '3',
});
})
});
in order to receive a value from it.
Please be aware that you should either unsubscribe from it or use an declerative approach (e.g. defining the form as an observable and using async
pipe to subscribe to it).