0

I am a beginner in JavaScript and I have problem when I want to bind my data which comes from HTML page ( I invoke methods from service to set the properties):

onSubmit() {
    this.setCustomerDataFromService(this.purchaseFormModule)
    this.setShippingDataFromService(this.purchaseFormModule)
  }

  setCustomerDataFromService(customerForm: FormGroup) {
    this.formService.setCustomerData(customerForm)
  }

  setShippingDataFromService(shippingForm: FormGroup) {
    this.formService.setShippingData(shippingForm)
  }

The methods in serice class:

setCustomerData(customerForm: FormGroup) {
    this.customerData.name = customerForm.get('customer.name').value
    this.customerData.surname = customerForm.get('customer.surname').value
    this.customerData.email = customerForm.get('customer.email').value
    this.customerData.phoneNumber = customerForm.get('customer.phoneNumber').value
  }

  setShippingData(shippingForm: FormGroup) {
    this.shippingData.building = shippingForm.get("shipping.building").value
    this.shippingData.postalCode = shippingForm.get("shipping.postalCode").value
    this.shippingData.country = shippingForm.get("shipping.country").value
    this.shippingData.city = shippingForm.get("shipping.city").value
    this.shippingData.street = shippingForm.get("shipping.street").value
  }

And now it't good, I have objects with values came from the HTML page. Now I would like to share these objects with other TypeScript classes. I know that can be done by subscribing, but I have already done it with single properties, not objects.

I am trying like that (in e.g class Summary where I want to show these values):

 customerData: Customer = new Customer();
  paymentData: Payment = new Payment();
  shippingData: Shipping = new Shipping();

  constructor(private formService: FormService) { }

  updatePurchaseDetails() {
    this.formService.getCustomerData().subscribe(result => {
      this.customerData = result
    })

    this.formService.getShippingData().subscribe(result => {
      this.shippingData = result
    })
  }

I saw on SO that to subscribe objects I need to change it to Observable:

 getCustomerData(): Observable<Customer> {
    return of(this.customerData)
  }
  getShippingData(): Observable<Shipping> {
    return of(this.shippingData)
  }

but now I get in Summary class undefined on these objects.

1 Answer 1

1

If a service is declared in the global scope (usually default, denoted by @Inectable({providedIn: 'root'}) at the top of the service class) then you will be able to access properties from the service in any class and they will accurately reflect the property values.

With this in mind, you could define properties in the service, set them on submit, and access them from other components that inject the service. However, this will not cause an update to the classes/components that are currently using those properties. Once they access the property there would be nothing in place to tell them to change if the value changes. This would require a way to have a sort of send out an update to notify those who are accessing the value that it has changed, and to update their value. Cue Observables, Subjects, and BehaviorSubjects.

You likely want to hold your value that needs to be shared inside of a subject or behaviorsubject, .next() to update it, and .subscribe in the components that need to use it.

Read more here https://blog.angulartraining.com/rxjs-subjects-a-tutorial-4dcce0e9637f and to dive deep, just look up rxjs

Sign up to request clarification or add additional context in comments.

2 Comments

At first thank you for your comment. I would like not to share these objects with all classes, but only with some, that's why I have choosen to .subscribe(). I forgot to use .next() to update data - my bad - but actually it gives me error, because .next does not operate on objects and I suspect that I should turn it info Observable. I will try. Thank you.
create a behaviorSubject mySubject in the service, and think of it as 'holding your current value'. When you want to update it, run mySubject.next(my new and updated value~~). To access it from within your components that need it, inject the service, and on init do myService.mySubject.subscribe(res => { myLocalVal = res; or whatever else})

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.