Angular 6 : Update a value in my component when she change in my service












2














My goal is simple in principle, but I can not put it in place: I want one of my components to be updated when the variable of a service is changed.



To better explain my problem, here is an example :



Here, I have a service that increases or decreases a number of points.
It decreases or increases this number of points when it receives a call to one of its functions.
It also says if this variable is even or odd



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

@Injectable({
providedIn: 'root'
})
export class TestService {
Number: number = 0;
IsOdd: boolean = false;

constructor() {}

IncreaseNumber() {
this.Number = this.Number + 1;
this.IsOdd = !this.IsOdd;
}

DecreaseNumber() {
this.Number = this.Number - 1;
this.IsOdd = !this.IsOdd;
}
}


*Here, I have my component, which needs to know if my figure is even or odd.



At initialization, no problem! It knows it!



How, every time the number changes in my service (test.service.ts) then I make sure that the value pair/import changes in my component (test.component.ts)?*



import { Component, OnInit } from '@angular/core';
import { TestService } from '../test.service'

@Component({
selector: 'app-test',
templateUrl: './test.component.html',
styleUrls: ['./test.component.scss']
})

export class TestComponent implements OnInit {

IsOdd: boolean = false;

constructor(MyService: TestService) {}

ngOnInit() {
this.IsOdd = MyService.IsOdd;
}

}


How should I do it ?



Did my component need to subscribe to my service in some way?
Or Did I have to use one function like ngOnInit but for update?



Thanks in advance










share|improve this question
























  • The component "needs to know" for what kind of purpose? Do you need to be notified to do some additional processing, or do you only need to update the view?
    – ConnorsFan
    Nov 19 '18 at 15:43










  • How did you know that it does not work ? means what did you implement to test your service methods ?
    – selem mn
    Nov 19 '18 at 15:43






  • 1




    you need to use Subject from rxjs in your service and expose it as an Observable in your service. Then in your component you need to subscribe to that Observable of your service. Then you need to emit a new value through the Subject like subject.next({val: this.Number, IsOdd : this.IsOdd }) in your service method IncreaseNumber and the others. When ever any change occurs in your service you will get the update in your component subscription.
    – Niladri
    Nov 19 '18 at 15:48










  • First, thank for the Subject, I will look at this. He needed for additionnel processing Again, I put this example as simple as possible. My real case is more complex and messy. Using a simple and trivial example allow peoples to answer more easily and other people, with the same problem as me, to understand the answer better. I know that the example does'nt work because nothings make him update
    – Scieur Arnaud
    Nov 20 '18 at 13:24
















2














My goal is simple in principle, but I can not put it in place: I want one of my components to be updated when the variable of a service is changed.



To better explain my problem, here is an example :



Here, I have a service that increases or decreases a number of points.
It decreases or increases this number of points when it receives a call to one of its functions.
It also says if this variable is even or odd



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

@Injectable({
providedIn: 'root'
})
export class TestService {
Number: number = 0;
IsOdd: boolean = false;

constructor() {}

IncreaseNumber() {
this.Number = this.Number + 1;
this.IsOdd = !this.IsOdd;
}

DecreaseNumber() {
this.Number = this.Number - 1;
this.IsOdd = !this.IsOdd;
}
}


*Here, I have my component, which needs to know if my figure is even or odd.



At initialization, no problem! It knows it!



How, every time the number changes in my service (test.service.ts) then I make sure that the value pair/import changes in my component (test.component.ts)?*



import { Component, OnInit } from '@angular/core';
import { TestService } from '../test.service'

@Component({
selector: 'app-test',
templateUrl: './test.component.html',
styleUrls: ['./test.component.scss']
})

export class TestComponent implements OnInit {

IsOdd: boolean = false;

constructor(MyService: TestService) {}

ngOnInit() {
this.IsOdd = MyService.IsOdd;
}

}


How should I do it ?



Did my component need to subscribe to my service in some way?
Or Did I have to use one function like ngOnInit but for update?



Thanks in advance










share|improve this question
























  • The component "needs to know" for what kind of purpose? Do you need to be notified to do some additional processing, or do you only need to update the view?
    – ConnorsFan
    Nov 19 '18 at 15:43










  • How did you know that it does not work ? means what did you implement to test your service methods ?
    – selem mn
    Nov 19 '18 at 15:43






  • 1




    you need to use Subject from rxjs in your service and expose it as an Observable in your service. Then in your component you need to subscribe to that Observable of your service. Then you need to emit a new value through the Subject like subject.next({val: this.Number, IsOdd : this.IsOdd }) in your service method IncreaseNumber and the others. When ever any change occurs in your service you will get the update in your component subscription.
    – Niladri
    Nov 19 '18 at 15:48










  • First, thank for the Subject, I will look at this. He needed for additionnel processing Again, I put this example as simple as possible. My real case is more complex and messy. Using a simple and trivial example allow peoples to answer more easily and other people, with the same problem as me, to understand the answer better. I know that the example does'nt work because nothings make him update
    – Scieur Arnaud
    Nov 20 '18 at 13:24














2












2








2







My goal is simple in principle, but I can not put it in place: I want one of my components to be updated when the variable of a service is changed.



To better explain my problem, here is an example :



Here, I have a service that increases or decreases a number of points.
It decreases or increases this number of points when it receives a call to one of its functions.
It also says if this variable is even or odd



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

@Injectable({
providedIn: 'root'
})
export class TestService {
Number: number = 0;
IsOdd: boolean = false;

constructor() {}

IncreaseNumber() {
this.Number = this.Number + 1;
this.IsOdd = !this.IsOdd;
}

DecreaseNumber() {
this.Number = this.Number - 1;
this.IsOdd = !this.IsOdd;
}
}


*Here, I have my component, which needs to know if my figure is even or odd.



At initialization, no problem! It knows it!



How, every time the number changes in my service (test.service.ts) then I make sure that the value pair/import changes in my component (test.component.ts)?*



import { Component, OnInit } from '@angular/core';
import { TestService } from '../test.service'

@Component({
selector: 'app-test',
templateUrl: './test.component.html',
styleUrls: ['./test.component.scss']
})

export class TestComponent implements OnInit {

IsOdd: boolean = false;

constructor(MyService: TestService) {}

ngOnInit() {
this.IsOdd = MyService.IsOdd;
}

}


How should I do it ?



Did my component need to subscribe to my service in some way?
Or Did I have to use one function like ngOnInit but for update?



Thanks in advance










share|improve this question















My goal is simple in principle, but I can not put it in place: I want one of my components to be updated when the variable of a service is changed.



To better explain my problem, here is an example :



Here, I have a service that increases or decreases a number of points.
It decreases or increases this number of points when it receives a call to one of its functions.
It also says if this variable is even or odd



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

@Injectable({
providedIn: 'root'
})
export class TestService {
Number: number = 0;
IsOdd: boolean = false;

constructor() {}

IncreaseNumber() {
this.Number = this.Number + 1;
this.IsOdd = !this.IsOdd;
}

DecreaseNumber() {
this.Number = this.Number - 1;
this.IsOdd = !this.IsOdd;
}
}


*Here, I have my component, which needs to know if my figure is even or odd.



At initialization, no problem! It knows it!



How, every time the number changes in my service (test.service.ts) then I make sure that the value pair/import changes in my component (test.component.ts)?*



import { Component, OnInit } from '@angular/core';
import { TestService } from '../test.service'

@Component({
selector: 'app-test',
templateUrl: './test.component.html',
styleUrls: ['./test.component.scss']
})

export class TestComponent implements OnInit {

IsOdd: boolean = false;

constructor(MyService: TestService) {}

ngOnInit() {
this.IsOdd = MyService.IsOdd;
}

}


How should I do it ?



Did my component need to subscribe to my service in some way?
Or Did I have to use one function like ngOnInit but for update?



Thanks in advance







angular typescript service components






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 19 '18 at 15:41









SiddAjmera

13.1k31137




13.1k31137










asked Nov 19 '18 at 15:35









Scieur Arnaud

443




443












  • The component "needs to know" for what kind of purpose? Do you need to be notified to do some additional processing, or do you only need to update the view?
    – ConnorsFan
    Nov 19 '18 at 15:43










  • How did you know that it does not work ? means what did you implement to test your service methods ?
    – selem mn
    Nov 19 '18 at 15:43






  • 1




    you need to use Subject from rxjs in your service and expose it as an Observable in your service. Then in your component you need to subscribe to that Observable of your service. Then you need to emit a new value through the Subject like subject.next({val: this.Number, IsOdd : this.IsOdd }) in your service method IncreaseNumber and the others. When ever any change occurs in your service you will get the update in your component subscription.
    – Niladri
    Nov 19 '18 at 15:48










  • First, thank for the Subject, I will look at this. He needed for additionnel processing Again, I put this example as simple as possible. My real case is more complex and messy. Using a simple and trivial example allow peoples to answer more easily and other people, with the same problem as me, to understand the answer better. I know that the example does'nt work because nothings make him update
    – Scieur Arnaud
    Nov 20 '18 at 13:24


















  • The component "needs to know" for what kind of purpose? Do you need to be notified to do some additional processing, or do you only need to update the view?
    – ConnorsFan
    Nov 19 '18 at 15:43










  • How did you know that it does not work ? means what did you implement to test your service methods ?
    – selem mn
    Nov 19 '18 at 15:43






  • 1




    you need to use Subject from rxjs in your service and expose it as an Observable in your service. Then in your component you need to subscribe to that Observable of your service. Then you need to emit a new value through the Subject like subject.next({val: this.Number, IsOdd : this.IsOdd }) in your service method IncreaseNumber and the others. When ever any change occurs in your service you will get the update in your component subscription.
    – Niladri
    Nov 19 '18 at 15:48










  • First, thank for the Subject, I will look at this. He needed for additionnel processing Again, I put this example as simple as possible. My real case is more complex and messy. Using a simple and trivial example allow peoples to answer more easily and other people, with the same problem as me, to understand the answer better. I know that the example does'nt work because nothings make him update
    – Scieur Arnaud
    Nov 20 '18 at 13:24
















The component "needs to know" for what kind of purpose? Do you need to be notified to do some additional processing, or do you only need to update the view?
– ConnorsFan
Nov 19 '18 at 15:43




The component "needs to know" for what kind of purpose? Do you need to be notified to do some additional processing, or do you only need to update the view?
– ConnorsFan
Nov 19 '18 at 15:43












How did you know that it does not work ? means what did you implement to test your service methods ?
– selem mn
Nov 19 '18 at 15:43




How did you know that it does not work ? means what did you implement to test your service methods ?
– selem mn
Nov 19 '18 at 15:43




1




1




you need to use Subject from rxjs in your service and expose it as an Observable in your service. Then in your component you need to subscribe to that Observable of your service. Then you need to emit a new value through the Subject like subject.next({val: this.Number, IsOdd : this.IsOdd }) in your service method IncreaseNumber and the others. When ever any change occurs in your service you will get the update in your component subscription.
– Niladri
Nov 19 '18 at 15:48




you need to use Subject from rxjs in your service and expose it as an Observable in your service. Then in your component you need to subscribe to that Observable of your service. Then you need to emit a new value through the Subject like subject.next({val: this.Number, IsOdd : this.IsOdd }) in your service method IncreaseNumber and the others. When ever any change occurs in your service you will get the update in your component subscription.
– Niladri
Nov 19 '18 at 15:48












First, thank for the Subject, I will look at this. He needed for additionnel processing Again, I put this example as simple as possible. My real case is more complex and messy. Using a simple and trivial example allow peoples to answer more easily and other people, with the same problem as me, to understand the answer better. I know that the example does'nt work because nothings make him update
– Scieur Arnaud
Nov 20 '18 at 13:24




First, thank for the Subject, I will look at this. He needed for additionnel processing Again, I put this example as simple as possible. My real case is more complex and messy. Using a simple and trivial example allow peoples to answer more easily and other people, with the same problem as me, to understand the answer better. I know that the example does'nt work because nothings make him update
– Scieur Arnaud
Nov 20 '18 at 13:24












3 Answers
3






active

oldest

votes


















2














It would have automatically updated if these service variables were of a complex type like an Object or an Array as these are reference types. But since you have Service variables of type number and boolean, these will not be updated automatically as they are primitive types and hence passed by value.



So you'll have to use BehaviorSubjects and expose them asObservables. You'll update the values of these BehaviorSubjects by calling the next method on them. Here's how:



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

@Injectable({
providedIn: 'root'
})
export class TestService {
private myNumberValue = 0;
private isOddValue = false;
private myNumber: BehaviorSubject<number> = new BehaviorSubject<number>(this.myNumberValue);
private isOdd: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);

myNumber$: Observable<number> = this.myNumber.asObservable();
isOdd$: Observable<boolean> = this.isOdd.asObservable();

constructor() {}

increaseNumber() {
this.myNumberValue = this.myNumberValue + 1;
this.myNumber.next(this.myNumberValue);
this.isOddValue = !this.isOddValue;
this.isOdd.next(this.isOddValue);
}

decreaseNumber() {
this.myNumberValue = this.myNumberValue - 1;
this.myNumber.next(this.myNumberValue);
this.isOddValue = !this.isOddValue;
this.isOdd.next(this.isOddValue);
}
}


Now in your Component, all you need to do is subscribe to the publicly exposed Observable values from the Service:



import { Component, OnInit, OnDestroy } from '@angular/core';
import { TestService } from '../test.service'
import { Subscription } from 'rxjs';

@Component({
selector: 'app-test',
templateUrl: './test.component.html',
styleUrls: ['./test.component.scss']
})

export class TestComponent implements OnInit, OnDestroy {

isOdd: boolean;
subscription: Subscription;

constructor(private testService: TestService) {}

ngOnInit() {
this.subscription = this.testService.isOdd$.subscribe(isOdd => this.isOdd = isOdd);
}

ngOnDestroy() {
this.subscription && this.subscription.unsubscribe();
}

}


Now since you've subscribed to isOdd$ in ngOnInit which gets called during component initialization, isOdd on your Component will update every time there is a change in the isOddValue in the service.



Also since this is a custom subscription it should be assigned to a property in the Component(subscription) which would be of type Subscription which is what we get from the subscribe method as a return value. We will have to call unsubscribe on it in ngOnDestroy to avoid memory leaks.



PS: Property and method names in Angular Classes should be in lowerCamelCase according to Angular's Styleguide.




Do use lower camel case to name properties and methods.







share|improve this answer



















  • 1




    It can be achieved using Subject also . And it's good to use unsubscribe in the component during ngOndestroy to avoid memory leak
    – Niladri
    Nov 19 '18 at 15:52










  • Thanks, it help a lot. And I think it will help a lot of other peoples since the example is pretty simple ! ^^
    – Scieur Arnaud
    Nov 20 '18 at 13:17



















1














For what you are saying to work, you should be increasing/decreasing the number in the service within the TestComponent, not in other components.



import { Component, OnInit } from '@angular/core';
import { TestService } from '../test.service'

@Component({
selector: 'app-test',
templateUrl: './test.component.html',
styleUrls: ['./test.component.scss']
})

export class TestComponent implements OnInit {

IsOdd: boolean = false;

constructor(MyService: TestService) {}

ngOnInit() {
this.IsOdd = MyService.IsOdd;
}

increase() {
MyService.IncreaseNumber();
}

decrease() {
MyService.DecreaseNumber();
}

getIsOdd() {
return MyService.IsOdd;
}

}





share|improve this answer





















  • It was an example, I tried to figure out a simple example to explain my problem. Because with my work, these things would get messy and complicated ^^
    – Scieur Arnaud
    Nov 20 '18 at 13:14



















1














There are multiple solutions you can use including setting up an Observable to subscribe to changes. These are all valid solutions.



The simplest solution would be to bind to the service in the template rather than the value:



<div> {{ MyService.IsOdd }} </div>


In ngOnInit, you are assigning the boolean value to a property on the component. This value never changes. In order to create a data binding and respond to changes, you have to bind a reference to a property using an object which requires a . Thus, the MyService.IsOdd will work in the template.



https://stackblitz.com/edit/angular-rktij7






share|improve this answer





















  • Thanks, it was the method is used at first. But I could'nt stop thinking "what if I needed to see it without using it directly in the html". So i was looking for the other method ^^
    – Scieur Arnaud
    Nov 20 '18 at 13:16











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53377973%2fangular-6-update-a-value-in-my-component-when-she-change-in-my-service%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























3 Answers
3






active

oldest

votes








3 Answers
3






active

oldest

votes









active

oldest

votes






active

oldest

votes









2














It would have automatically updated if these service variables were of a complex type like an Object or an Array as these are reference types. But since you have Service variables of type number and boolean, these will not be updated automatically as they are primitive types and hence passed by value.



So you'll have to use BehaviorSubjects and expose them asObservables. You'll update the values of these BehaviorSubjects by calling the next method on them. Here's how:



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

@Injectable({
providedIn: 'root'
})
export class TestService {
private myNumberValue = 0;
private isOddValue = false;
private myNumber: BehaviorSubject<number> = new BehaviorSubject<number>(this.myNumberValue);
private isOdd: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);

myNumber$: Observable<number> = this.myNumber.asObservable();
isOdd$: Observable<boolean> = this.isOdd.asObservable();

constructor() {}

increaseNumber() {
this.myNumberValue = this.myNumberValue + 1;
this.myNumber.next(this.myNumberValue);
this.isOddValue = !this.isOddValue;
this.isOdd.next(this.isOddValue);
}

decreaseNumber() {
this.myNumberValue = this.myNumberValue - 1;
this.myNumber.next(this.myNumberValue);
this.isOddValue = !this.isOddValue;
this.isOdd.next(this.isOddValue);
}
}


Now in your Component, all you need to do is subscribe to the publicly exposed Observable values from the Service:



import { Component, OnInit, OnDestroy } from '@angular/core';
import { TestService } from '../test.service'
import { Subscription } from 'rxjs';

@Component({
selector: 'app-test',
templateUrl: './test.component.html',
styleUrls: ['./test.component.scss']
})

export class TestComponent implements OnInit, OnDestroy {

isOdd: boolean;
subscription: Subscription;

constructor(private testService: TestService) {}

ngOnInit() {
this.subscription = this.testService.isOdd$.subscribe(isOdd => this.isOdd = isOdd);
}

ngOnDestroy() {
this.subscription && this.subscription.unsubscribe();
}

}


Now since you've subscribed to isOdd$ in ngOnInit which gets called during component initialization, isOdd on your Component will update every time there is a change in the isOddValue in the service.



Also since this is a custom subscription it should be assigned to a property in the Component(subscription) which would be of type Subscription which is what we get from the subscribe method as a return value. We will have to call unsubscribe on it in ngOnDestroy to avoid memory leaks.



PS: Property and method names in Angular Classes should be in lowerCamelCase according to Angular's Styleguide.




Do use lower camel case to name properties and methods.







share|improve this answer



















  • 1




    It can be achieved using Subject also . And it's good to use unsubscribe in the component during ngOndestroy to avoid memory leak
    – Niladri
    Nov 19 '18 at 15:52










  • Thanks, it help a lot. And I think it will help a lot of other peoples since the example is pretty simple ! ^^
    – Scieur Arnaud
    Nov 20 '18 at 13:17
















2














It would have automatically updated if these service variables were of a complex type like an Object or an Array as these are reference types. But since you have Service variables of type number and boolean, these will not be updated automatically as they are primitive types and hence passed by value.



So you'll have to use BehaviorSubjects and expose them asObservables. You'll update the values of these BehaviorSubjects by calling the next method on them. Here's how:



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

@Injectable({
providedIn: 'root'
})
export class TestService {
private myNumberValue = 0;
private isOddValue = false;
private myNumber: BehaviorSubject<number> = new BehaviorSubject<number>(this.myNumberValue);
private isOdd: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);

myNumber$: Observable<number> = this.myNumber.asObservable();
isOdd$: Observable<boolean> = this.isOdd.asObservable();

constructor() {}

increaseNumber() {
this.myNumberValue = this.myNumberValue + 1;
this.myNumber.next(this.myNumberValue);
this.isOddValue = !this.isOddValue;
this.isOdd.next(this.isOddValue);
}

decreaseNumber() {
this.myNumberValue = this.myNumberValue - 1;
this.myNumber.next(this.myNumberValue);
this.isOddValue = !this.isOddValue;
this.isOdd.next(this.isOddValue);
}
}


Now in your Component, all you need to do is subscribe to the publicly exposed Observable values from the Service:



import { Component, OnInit, OnDestroy } from '@angular/core';
import { TestService } from '../test.service'
import { Subscription } from 'rxjs';

@Component({
selector: 'app-test',
templateUrl: './test.component.html',
styleUrls: ['./test.component.scss']
})

export class TestComponent implements OnInit, OnDestroy {

isOdd: boolean;
subscription: Subscription;

constructor(private testService: TestService) {}

ngOnInit() {
this.subscription = this.testService.isOdd$.subscribe(isOdd => this.isOdd = isOdd);
}

ngOnDestroy() {
this.subscription && this.subscription.unsubscribe();
}

}


Now since you've subscribed to isOdd$ in ngOnInit which gets called during component initialization, isOdd on your Component will update every time there is a change in the isOddValue in the service.



Also since this is a custom subscription it should be assigned to a property in the Component(subscription) which would be of type Subscription which is what we get from the subscribe method as a return value. We will have to call unsubscribe on it in ngOnDestroy to avoid memory leaks.



PS: Property and method names in Angular Classes should be in lowerCamelCase according to Angular's Styleguide.




Do use lower camel case to name properties and methods.







share|improve this answer



















  • 1




    It can be achieved using Subject also . And it's good to use unsubscribe in the component during ngOndestroy to avoid memory leak
    – Niladri
    Nov 19 '18 at 15:52










  • Thanks, it help a lot. And I think it will help a lot of other peoples since the example is pretty simple ! ^^
    – Scieur Arnaud
    Nov 20 '18 at 13:17














2












2








2






It would have automatically updated if these service variables were of a complex type like an Object or an Array as these are reference types. But since you have Service variables of type number and boolean, these will not be updated automatically as they are primitive types and hence passed by value.



So you'll have to use BehaviorSubjects and expose them asObservables. You'll update the values of these BehaviorSubjects by calling the next method on them. Here's how:



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

@Injectable({
providedIn: 'root'
})
export class TestService {
private myNumberValue = 0;
private isOddValue = false;
private myNumber: BehaviorSubject<number> = new BehaviorSubject<number>(this.myNumberValue);
private isOdd: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);

myNumber$: Observable<number> = this.myNumber.asObservable();
isOdd$: Observable<boolean> = this.isOdd.asObservable();

constructor() {}

increaseNumber() {
this.myNumberValue = this.myNumberValue + 1;
this.myNumber.next(this.myNumberValue);
this.isOddValue = !this.isOddValue;
this.isOdd.next(this.isOddValue);
}

decreaseNumber() {
this.myNumberValue = this.myNumberValue - 1;
this.myNumber.next(this.myNumberValue);
this.isOddValue = !this.isOddValue;
this.isOdd.next(this.isOddValue);
}
}


Now in your Component, all you need to do is subscribe to the publicly exposed Observable values from the Service:



import { Component, OnInit, OnDestroy } from '@angular/core';
import { TestService } from '../test.service'
import { Subscription } from 'rxjs';

@Component({
selector: 'app-test',
templateUrl: './test.component.html',
styleUrls: ['./test.component.scss']
})

export class TestComponent implements OnInit, OnDestroy {

isOdd: boolean;
subscription: Subscription;

constructor(private testService: TestService) {}

ngOnInit() {
this.subscription = this.testService.isOdd$.subscribe(isOdd => this.isOdd = isOdd);
}

ngOnDestroy() {
this.subscription && this.subscription.unsubscribe();
}

}


Now since you've subscribed to isOdd$ in ngOnInit which gets called during component initialization, isOdd on your Component will update every time there is a change in the isOddValue in the service.



Also since this is a custom subscription it should be assigned to a property in the Component(subscription) which would be of type Subscription which is what we get from the subscribe method as a return value. We will have to call unsubscribe on it in ngOnDestroy to avoid memory leaks.



PS: Property and method names in Angular Classes should be in lowerCamelCase according to Angular's Styleguide.




Do use lower camel case to name properties and methods.







share|improve this answer














It would have automatically updated if these service variables were of a complex type like an Object or an Array as these are reference types. But since you have Service variables of type number and boolean, these will not be updated automatically as they are primitive types and hence passed by value.



So you'll have to use BehaviorSubjects and expose them asObservables. You'll update the values of these BehaviorSubjects by calling the next method on them. Here's how:



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

@Injectable({
providedIn: 'root'
})
export class TestService {
private myNumberValue = 0;
private isOddValue = false;
private myNumber: BehaviorSubject<number> = new BehaviorSubject<number>(this.myNumberValue);
private isOdd: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);

myNumber$: Observable<number> = this.myNumber.asObservable();
isOdd$: Observable<boolean> = this.isOdd.asObservable();

constructor() {}

increaseNumber() {
this.myNumberValue = this.myNumberValue + 1;
this.myNumber.next(this.myNumberValue);
this.isOddValue = !this.isOddValue;
this.isOdd.next(this.isOddValue);
}

decreaseNumber() {
this.myNumberValue = this.myNumberValue - 1;
this.myNumber.next(this.myNumberValue);
this.isOddValue = !this.isOddValue;
this.isOdd.next(this.isOddValue);
}
}


Now in your Component, all you need to do is subscribe to the publicly exposed Observable values from the Service:



import { Component, OnInit, OnDestroy } from '@angular/core';
import { TestService } from '../test.service'
import { Subscription } from 'rxjs';

@Component({
selector: 'app-test',
templateUrl: './test.component.html',
styleUrls: ['./test.component.scss']
})

export class TestComponent implements OnInit, OnDestroy {

isOdd: boolean;
subscription: Subscription;

constructor(private testService: TestService) {}

ngOnInit() {
this.subscription = this.testService.isOdd$.subscribe(isOdd => this.isOdd = isOdd);
}

ngOnDestroy() {
this.subscription && this.subscription.unsubscribe();
}

}


Now since you've subscribed to isOdd$ in ngOnInit which gets called during component initialization, isOdd on your Component will update every time there is a change in the isOddValue in the service.



Also since this is a custom subscription it should be assigned to a property in the Component(subscription) which would be of type Subscription which is what we get from the subscribe method as a return value. We will have to call unsubscribe on it in ngOnDestroy to avoid memory leaks.



PS: Property and method names in Angular Classes should be in lowerCamelCase according to Angular's Styleguide.




Do use lower camel case to name properties and methods.








share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 19 '18 at 16:19

























answered Nov 19 '18 at 15:49









SiddAjmera

13.1k31137




13.1k31137








  • 1




    It can be achieved using Subject also . And it's good to use unsubscribe in the component during ngOndestroy to avoid memory leak
    – Niladri
    Nov 19 '18 at 15:52










  • Thanks, it help a lot. And I think it will help a lot of other peoples since the example is pretty simple ! ^^
    – Scieur Arnaud
    Nov 20 '18 at 13:17














  • 1




    It can be achieved using Subject also . And it's good to use unsubscribe in the component during ngOndestroy to avoid memory leak
    – Niladri
    Nov 19 '18 at 15:52










  • Thanks, it help a lot. And I think it will help a lot of other peoples since the example is pretty simple ! ^^
    – Scieur Arnaud
    Nov 20 '18 at 13:17








1




1




It can be achieved using Subject also . And it's good to use unsubscribe in the component during ngOndestroy to avoid memory leak
– Niladri
Nov 19 '18 at 15:52




It can be achieved using Subject also . And it's good to use unsubscribe in the component during ngOndestroy to avoid memory leak
– Niladri
Nov 19 '18 at 15:52












Thanks, it help a lot. And I think it will help a lot of other peoples since the example is pretty simple ! ^^
– Scieur Arnaud
Nov 20 '18 at 13:17




Thanks, it help a lot. And I think it will help a lot of other peoples since the example is pretty simple ! ^^
– Scieur Arnaud
Nov 20 '18 at 13:17













1














For what you are saying to work, you should be increasing/decreasing the number in the service within the TestComponent, not in other components.



import { Component, OnInit } from '@angular/core';
import { TestService } from '../test.service'

@Component({
selector: 'app-test',
templateUrl: './test.component.html',
styleUrls: ['./test.component.scss']
})

export class TestComponent implements OnInit {

IsOdd: boolean = false;

constructor(MyService: TestService) {}

ngOnInit() {
this.IsOdd = MyService.IsOdd;
}

increase() {
MyService.IncreaseNumber();
}

decrease() {
MyService.DecreaseNumber();
}

getIsOdd() {
return MyService.IsOdd;
}

}





share|improve this answer





















  • It was an example, I tried to figure out a simple example to explain my problem. Because with my work, these things would get messy and complicated ^^
    – Scieur Arnaud
    Nov 20 '18 at 13:14
















1














For what you are saying to work, you should be increasing/decreasing the number in the service within the TestComponent, not in other components.



import { Component, OnInit } from '@angular/core';
import { TestService } from '../test.service'

@Component({
selector: 'app-test',
templateUrl: './test.component.html',
styleUrls: ['./test.component.scss']
})

export class TestComponent implements OnInit {

IsOdd: boolean = false;

constructor(MyService: TestService) {}

ngOnInit() {
this.IsOdd = MyService.IsOdd;
}

increase() {
MyService.IncreaseNumber();
}

decrease() {
MyService.DecreaseNumber();
}

getIsOdd() {
return MyService.IsOdd;
}

}





share|improve this answer





















  • It was an example, I tried to figure out a simple example to explain my problem. Because with my work, these things would get messy and complicated ^^
    – Scieur Arnaud
    Nov 20 '18 at 13:14














1












1








1






For what you are saying to work, you should be increasing/decreasing the number in the service within the TestComponent, not in other components.



import { Component, OnInit } from '@angular/core';
import { TestService } from '../test.service'

@Component({
selector: 'app-test',
templateUrl: './test.component.html',
styleUrls: ['./test.component.scss']
})

export class TestComponent implements OnInit {

IsOdd: boolean = false;

constructor(MyService: TestService) {}

ngOnInit() {
this.IsOdd = MyService.IsOdd;
}

increase() {
MyService.IncreaseNumber();
}

decrease() {
MyService.DecreaseNumber();
}

getIsOdd() {
return MyService.IsOdd;
}

}





share|improve this answer












For what you are saying to work, you should be increasing/decreasing the number in the service within the TestComponent, not in other components.



import { Component, OnInit } from '@angular/core';
import { TestService } from '../test.service'

@Component({
selector: 'app-test',
templateUrl: './test.component.html',
styleUrls: ['./test.component.scss']
})

export class TestComponent implements OnInit {

IsOdd: boolean = false;

constructor(MyService: TestService) {}

ngOnInit() {
this.IsOdd = MyService.IsOdd;
}

increase() {
MyService.IncreaseNumber();
}

decrease() {
MyService.DecreaseNumber();
}

getIsOdd() {
return MyService.IsOdd;
}

}






share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 19 '18 at 15:48









gatsbyz

195317




195317












  • It was an example, I tried to figure out a simple example to explain my problem. Because with my work, these things would get messy and complicated ^^
    – Scieur Arnaud
    Nov 20 '18 at 13:14


















  • It was an example, I tried to figure out a simple example to explain my problem. Because with my work, these things would get messy and complicated ^^
    – Scieur Arnaud
    Nov 20 '18 at 13:14
















It was an example, I tried to figure out a simple example to explain my problem. Because with my work, these things would get messy and complicated ^^
– Scieur Arnaud
Nov 20 '18 at 13:14




It was an example, I tried to figure out a simple example to explain my problem. Because with my work, these things would get messy and complicated ^^
– Scieur Arnaud
Nov 20 '18 at 13:14











1














There are multiple solutions you can use including setting up an Observable to subscribe to changes. These are all valid solutions.



The simplest solution would be to bind to the service in the template rather than the value:



<div> {{ MyService.IsOdd }} </div>


In ngOnInit, you are assigning the boolean value to a property on the component. This value never changes. In order to create a data binding and respond to changes, you have to bind a reference to a property using an object which requires a . Thus, the MyService.IsOdd will work in the template.



https://stackblitz.com/edit/angular-rktij7






share|improve this answer





















  • Thanks, it was the method is used at first. But I could'nt stop thinking "what if I needed to see it without using it directly in the html". So i was looking for the other method ^^
    – Scieur Arnaud
    Nov 20 '18 at 13:16
















1














There are multiple solutions you can use including setting up an Observable to subscribe to changes. These are all valid solutions.



The simplest solution would be to bind to the service in the template rather than the value:



<div> {{ MyService.IsOdd }} </div>


In ngOnInit, you are assigning the boolean value to a property on the component. This value never changes. In order to create a data binding and respond to changes, you have to bind a reference to a property using an object which requires a . Thus, the MyService.IsOdd will work in the template.



https://stackblitz.com/edit/angular-rktij7






share|improve this answer





















  • Thanks, it was the method is used at first. But I could'nt stop thinking "what if I needed to see it without using it directly in the html". So i was looking for the other method ^^
    – Scieur Arnaud
    Nov 20 '18 at 13:16














1












1








1






There are multiple solutions you can use including setting up an Observable to subscribe to changes. These are all valid solutions.



The simplest solution would be to bind to the service in the template rather than the value:



<div> {{ MyService.IsOdd }} </div>


In ngOnInit, you are assigning the boolean value to a property on the component. This value never changes. In order to create a data binding and respond to changes, you have to bind a reference to a property using an object which requires a . Thus, the MyService.IsOdd will work in the template.



https://stackblitz.com/edit/angular-rktij7






share|improve this answer












There are multiple solutions you can use including setting up an Observable to subscribe to changes. These are all valid solutions.



The simplest solution would be to bind to the service in the template rather than the value:



<div> {{ MyService.IsOdd }} </div>


In ngOnInit, you are assigning the boolean value to a property on the component. This value never changes. In order to create a data binding and respond to changes, you have to bind a reference to a property using an object which requires a . Thus, the MyService.IsOdd will work in the template.



https://stackblitz.com/edit/angular-rktij7







share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 19 '18 at 15:53









Explosion Pills

149k38225310




149k38225310












  • Thanks, it was the method is used at first. But I could'nt stop thinking "what if I needed to see it without using it directly in the html". So i was looking for the other method ^^
    – Scieur Arnaud
    Nov 20 '18 at 13:16


















  • Thanks, it was the method is used at first. But I could'nt stop thinking "what if I needed to see it without using it directly in the html". So i was looking for the other method ^^
    – Scieur Arnaud
    Nov 20 '18 at 13:16
















Thanks, it was the method is used at first. But I could'nt stop thinking "what if I needed to see it without using it directly in the html". So i was looking for the other method ^^
– Scieur Arnaud
Nov 20 '18 at 13:16




Thanks, it was the method is used at first. But I could'nt stop thinking "what if I needed to see it without using it directly in the html". So i was looking for the other method ^^
– Scieur Arnaud
Nov 20 '18 at 13:16


















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.





Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


Please pay close attention to the following guidance:


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53377973%2fangular-6-update-a-value-in-my-component-when-she-change-in-my-service%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

MongoDB - Not Authorized To Execute Command

in spring boot 2.1 many test slices are not allowed anymore due to multiple @BootstrapWith

Npm cannot find a required file even through it is in the searched directory