0

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.

1
  • can you put together a stackblitz display the wrong functionality? Commented Apr 8, 2019 at 14:43

3 Answers 3

1

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

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

4 Comments

I have tried to add the providedIn in Injectable, but I still get the default message.
Could the fact that the component where I change message, is loaded before Order.component is subscribed to the message mean it doesn't work?
thanks for your answer Mohamed, unfortunately I still get the default value from this.data.currentMessage.subscribe(message => { this.brandName = message; console.log(this.brandName); // will show the new message }); I have edited my original post with further information
from your code i noticed that you are not calling changeMessage method , i created a working a stackblitz : stackblitz.com/edit/angular-ele1cu
0

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

Comments

0

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.