Mimeer
Mimeer

Reputation: 81

Component not getting updated data when sharing Data between components with a Service

I want to use the brandName variable from a sibling component to another in the same module. I've tried to do this using BehaviorSubject

However while I can get the updated brandName sent to my service, my component still uses the default message.

my Service file looks like this:

import { Injectable } from '@angular/core';

import { BehaviorSubject } from 'rxjs';


@Injectable()

export class DataService {


  private messageSource = new BehaviorSubject('default message');

  currentMessage = this.messageSource.asObservable();


  constructor() { }

  changeMessage(message: string) {

    console.log('service sent: ' + message);

    this.messageSource.next(message);

  }

}

here the console prints out the updated message.

however when I try to update my variable in Order component I get the "default message"

Order.component.ts:


import {DataService} from '../services/data.service';

...
export class OrderComponent implements OnInit {
...

constructor(...private data: DataService)

...

this.data.currentMessage.subscribe(message => this.brandName = message);

console.log('brandname');

console.log(this.brandName);

prints out 'default message'

only their common parent app.module.ts contains the DataService provider.

Edit

I have tried to also get the variable from a third component, using:

this.data.currentMessage.subscribe(message => this.brandName = message);

In this one do in fact get the updated brandname, but still nothing in the component that it is intended for, even though both components are same level siblings.

Furthermore I have tried remaking the service using

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root',
})
export class DataService {

  private data: string;

  setOption(value) {

    this.data = value;
    console.log('service sent: ' + value + 'and data ' + this.data );
  }

  getOption() {
    console.log('service returned');
    console.log(this.data);
    return this.data;


  }

However I get the same exact problem with the service getting the updated value, the third component canget this updated value, but my component the service was intended for gets the default one.

Upvotes: 0

Views: 941

Answers (3)

Mohamed Ali RACHID
Mohamed Ali RACHID

Reputation: 3297

Try to declare the service like below to have a single instance ( add providedIn: 'root' )

@Injectable({
  providedIn: 'root',
})
export class DataService {


  private messageSource = new BehaviorSubject('default message');

  currentMessage = this.messageSource.asObservable();


  constructor() { }

  changeMessage(message: string) {

    console.log('service sent: ' + message);

    this.messageSource.next(message);

  }
}

And since service is called asynchronously, console.log(this.brandName); is called before the end of the service work, so i suggest to move logging this.brandName value inside subscribe:

this.data.currentMessage.subscribe(message => {
 this.brandName = message;
 console.log(this.brandName); // will show the new message
});

console.log('brandname');

console.log(this.brandName); // will show the default message

I created a Stackblitz app containing your code , and in which the shared service is working : https://stackblitz.com/edit/angular-ele1cu

Upvotes: 1

orimdominic
orimdominic

Reputation: 1135

Service file

import { Observable, Subject, } from 'rxjs';


@Injectable({providedIn: 'root'})

export class DataService {

  // private messageSource = new BehaviorSubject('default message');
  // currentMessage = this.messageSource.asObservable();

  private messageSource = new Subject<string>();

  constructor() { }

  /*changeMessage(message: string) {
    console.log('service sent: ' + message);
    this.messageSource.next(message);
  }*/

  setMessage(message: string) {
    this.messageSource.next(message);
  }

  getMessage() {
    return this.messageSource.asObservable();
  }
}

Use the getMessage method in the service to subscribe to changes in the message in your component, and use the setMessage method to set the message

Upvotes: 0

Severin Klug
Severin Klug

Reputation: 754

You have to provide this Service as singleton on higher (module) level. It seems you have two different instances of this service.

Upvotes: 0

Related Questions