Using Angular 8 to Pass Form Data to Another Component via a Service

Is there a way to send all the Formgroup data as a Service in Angular to Another Component without using ControlValueAccessor? I want the receiver to automatically receive the value data whenever someone enters information on a form.

I am attempting to modify the code below to achieve this functionality.

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

Answer №1

Here is a suggestion that may be close to what you are looking for in your AddressFormComponent. Make sure to properly manage the subscription as shown 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();
}

This setup will then send data to the specific subject and notify its subscribers accordingly. To verify, you can try the following approach:

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 display the form data received
    });
  }

}

Answer №2

There is no need to manually respond to an event. The FormGroup already comes with an observable that handles the changes.

For example:

// address-form.component.ts
export class AppComponent implements OnDestroy {
  editAddressForm: FormGroup;

  ngOnDestroy() {
    // Perform 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() { }
}

If you want to display the form changes in the template, it's recommended to use the async pipe for subscribing only when the data is defined. Here's how you can do it:

// 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>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

I am encountering an issue while running npm run webpack in production mode where the CSS file is not being generated separately in the dist folder as expected. The file is not appearing as it should

Here is the code snippet from my webpack configuration file: const currentTask = process.env.nmp_lifecycle_event const path = require("path") const MiniCssExtractPlugin = require('mini-css-extract-plugin') const config = { entry: './ ...

Issue with integrating Contact Form 7 HTML into Wordpress

I've revisited this question with a new "input" HTML tag Despite changing everything, CSS still isn't being applied. HTML Code : <form action="#" class="contact-one__form row"> <div class="col-lg-6"> ...

Unusual patterns appearing in HTML image files

As a beginner in html, please pardon my silly questions and mistakes. I have designed this webpage: <!DOCTYPE html> <html> <head> <meta charset = "UTF-8"> <style type = text/css> #topbar { ...

The filter predicate function is failing to produce a result and the following error occurs: Unable to access the 'data' property in MatTableDataSource within

There seems to be an issue with the function that is causing it to not work correctly the first time a letter is entered in the search bar. It returns nothing in the array initially, but works fine when letters are removed and typing continues. createFilt ...

Struggling with textpath SVG elements in jQuery

Currently, I am implementing SVG in my project and aiming to apply the toggleClass function using jQuery on the textpath elements upon clicking. My initial plan was: $("text#names > textpath").click(function() { $(this).toggleClass("newClass"); }) ...

Center align the division within the list item

Check out the fiddle provided here: https://jsfiddle.net/5jnnutg8/ I am looking for a way to center align and display inline the "something #" list items. While the title "Hi" can be centered using text-align: center in css, this doesn't seem to wor ...

Nested REST API calls in Angular are causing only the inner call to be returned

When retrieving a ShoppingCart with ShoppingCartItems through an outer REST call, an Observable of the ShoppingCartItems is then used to make an inner call in order to enhance the items with a Provider. After the inner call, a tap(console.log) shows that ...

Utilizing a jQuery plugin for input file validation

This code is functioning properly, however the file field is not being validated. All input fields are successfully validated by this plugin except for the file type field. I believe there may be something missing in my implementation, so please help me de ...

Issue with submitting a form within a React modal - lack of triggering events

I am utilizing the npm package react-modal (https://www.npmjs.com/package/react-modal) in my project. The issue I am facing is that when I click on 'Submit', nothing happens. The function handleSubmit</a> is not being triggered, as no conso ...

VueJS3 and Vuetify are in need of some additional CSS classes

We are currently in the process of upgrading our application from old VueJS+Vuetify to VueJS3. However, we have encountered some classes defined in the template that are not available in the new version. These classes include xs12 (which is intended to co ...

Ways to reduce the width of an input field: Utilizing Bootstrap v5 or employing CSS techniques

I am struggling to find a way to adjust the width of the input window. It seems like there is no specific code that controls the width of the input window. The code snippet below is extracted from the Bootstrap v5 documentation, specifically focusing on th ...

React - z-index issue persists

My React App with Autocomplete feature is almost complete, but I need some assistance to double-check my code. https://i.stack.imgur.com/dhmck.png In the code snippet below, I have added a search box with the className "autocomplete" style. The issue I a ...

Leverage the power of the async pipe with ngFor on an Observable containing Observables within Angular

I have a variable defined in this way: myVar: Observable<Observable<MyObject>[]>. I am utilizing an Angular4 feature to iterate using the async pipe *ngFor="let obsMyObject of (myVar | async)" Currently, I have an Observable of MyObject, but ...

Explore the hidden route of the input components

HTML: <div id="quiz"> <div id="question"> <p id="quiz-txt">What is your favorite color?</p> <ul id="quiz-opt"> <div id="ans"> <input type="checkbox" id="Red" value="Red" class="options"> ...

Shifting static information both above and below a 100vh element

At the moment, I have a stationary image in the center of my screen that moves horizontally when scrolling with the mouse. Now, I want to include a screen above and below this element, each with a height of 100vh. However, when I attempt to do so, the fixe ...

Implementing a JQuery script that triggers every time there is a change in the scroll

This script creates a shrinking effect on a box followed by a fade-in/out transition when the scroll position changes. However, the issue is that it triggers every time there is a scroll position change. For example, if the scroll position is at 100px and ...

Alter attribute with an impact

I am looking for a solution to switch the image source using attr, while also incorporating a fade effect in the process. I have attempted to implement one of the suggestions from another post, but it is not producing the desired outcome. Current Appearan ...

Filter array to only include the most recent items with unique names (javascript)

I'm trying to retrieve the most recent result for each unique name using javascript. Is there a straightforward way to accomplish this in javascript? This question was inspired by a similar SQL post found here: Get Latest Rates For Each Distinct Rate ...

Having trouble incorporating Duo Web SDK into angular application

We are currently working on incorporating Duo Two-factor authentication into our Angular application. For instructions, you can take a look at the documentation available here. The issue we are encountering is that their JavaScript file searches for an i ...

The concept of CSS sprites and managing background positions

I have been working on integrating a star-rating widget that requires the use of a sprite file. The sprite file I am using looks like this: https://i.stack.imgur.com/ZSMMj.png This is how my HTML is structured: HTML <span id="star-ratings" class="c ...