Reputation: 81
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
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
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
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