Kamila Nowak
Kamila Nowak

Reputation: 59

Angular2: Subscribe Object to bind objects' values with service

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.

Upvotes: 0

Views: 54

Answers (1)

iamaword
iamaword

Reputation: 1509

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

Upvotes: 1

Related Questions