Reputation:
How do I sent all the Formgroup data as a Service in Angular to Another Component? I am looking for alternative to ControlValueAccessor. So anytime someone writes something on a form, the receiver will get the value data.
Trying to edit the code below to work.
Address Sender Form:
export class AddressFormComponent implements OnInit {
editAddressForm: FormGroup;
constructor(private formBuilder: FormBuilder) {
this.editAddressForm = this.formBuilder.group({
'streetName' : [null, Validators.required, Validators.maxLength(64)],
'city' : [null, Validators.required, Validators.maxLength(32)],
'state' : [null, Validators.required, Validators.maxLength(16)],
'postalCode' : [null, Validators.required, Validators.maxLength(16)]
});
}
ngOnInit() {
}
// What should I write as Event Code??
}
Service:
export class AddressService {
private messageSource = new Subject();
currentMessage = this.messageSource.asObservable();
constructor() { }
changeMessage(currentMessage) {
this.messageSource.next(currentMessage);
}
}
Receiver:
export class AddressCombinedReceiverComponent implements OnInit {
message: any;
constructor(private readonly addressService: AddressService) {
this.addressService.currentMessage.subscribe(currentMessage => this.message = currentMessage);
}
ngOnInit() {
}
}
Related question: Angular 2 - formControlName inside component
Upvotes: 1
Views: 4392
Reputation: 1705
You don't need to respond to an event. FormGroups
already have an observable that streams the changes.
Example
// address-form.component.ts
export class AppComponent implements OnDestroy {
editAddressForm: FormGroup;
ngOnDestroy() {
// cleanup
this.addressService.formValues$ = null;
}
constructor(private addressService: AddressService) {
this.editAddressForm = new FormGroup({
streetName: new FormControl(null, { validators: [Validators.required, Validators.maxLength(64)]}),
city: new FormControl(null, { validators: [Validators.required, Validators.maxLength(32)]}),
state: new FormControl(null, { validators: [Validators.required, Validators.maxLength(16)]}),
postalCode: new FormControl(null, { validators: [Validators.required, Validators.maxLength(16)]}),
});
this.addressService.formValues$ = this.editAddressForm.valueChanges;
}
}
// address.service.ts
export class AddressService {
formValues$: Observable<any>;
constructor() { }
}
In regards to the receiver, if the intention is to show the form changes in the template, then I recommend using the async pipe for that, so that you only subscribe when it's defined, like:
// address-combined-receiver.component.ts
export class SimpleComponent implements OnInit {
addressValues$: Observable<any>;
constructor(private addressService: AddressService) {
this.addressValues$ = this.addressService.formValues$;
}
ngOnInit() {
}
}
<!-- address-combined-receiver.component.html -->
<ng-container *ngIf="addressValues$ | async as addressValues">
<pre>{{ addressValues | json }}</pre>
</ng-container>
Upvotes: 1
Reputation: 6283
This doesnt look far away from what you need, in your AddressFormComponent try the following. Ensure to clean up the subscription when needed, added below.
public subs = new Subscription();
public editAddressForm: FormGroup;
constructor(addressService: AddressService){}
public ngOnInit(): void {
this.editAddressForm = this.formBuilder.group({
'streetName' : [null, Validators.required, Validators.maxLength(64)],
'city' : [null, Validators.required, Validators.maxLength(32)],
'state' : [null, Validators.required, Validators.maxLength(16)],
'postalCode' : [null, Validators.required, Validators.maxLength(16)]
});
this.subs.add(this.editAddressForm.valueChanges.subscribe(data =>
{
this.addressService.changeMessage(this.editAddressForm);
}));
}
public ngOnDestroy(): void
{
this.subs.unsubscribe();
}
That should in turn push the data to the subject you have an in turn cause the subscribers of that subject to receive the data. To confirm try the following
export class AddressCombinedReceiverComponent implements OnInit {
public message: any;
constructor(private readonly addressService: AddressService) {}
public ngOnInit() {
this.addressService.currentMessage.subscribe(currentMessage => {
this.message = currentMessage;
console.log(this.message); // should be the form coming through
});
}
}
Upvotes: 1