Angular 6 : Update a value in my component when she change in my service
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
add a comment |
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
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 useSubject
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 likesubject.next({val: this.Number, IsOdd : this.IsOdd })
in your service methodIncreaseNumber
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
add a comment |
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
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
angular typescript service components
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 useSubject
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 likesubject.next({val: this.Number, IsOdd : this.IsOdd })
in your service methodIncreaseNumber
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
add a comment |
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 useSubject
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 likesubject.next({val: this.Number, IsOdd : this.IsOdd })
in your service methodIncreaseNumber
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
add a comment |
3 Answers
3
active
oldest
votes
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 BehaviorSubject
s and expose them asObservable
s. You'll update the values of these BehaviorSubject
s 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 public
ly 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 subscribe
d 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.
1
It can be achieved usingSubject
also . And it's good to useunsubscribe
in the component duringngOndestroy
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
add a comment |
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;
}
}
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
add a comment |
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
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
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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 BehaviorSubject
s and expose them asObservable
s. You'll update the values of these BehaviorSubject
s 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 public
ly 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 subscribe
d 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.
1
It can be achieved usingSubject
also . And it's good to useunsubscribe
in the component duringngOndestroy
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
add a comment |
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 BehaviorSubject
s and expose them asObservable
s. You'll update the values of these BehaviorSubject
s 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 public
ly 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 subscribe
d 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.
1
It can be achieved usingSubject
also . And it's good to useunsubscribe
in the component duringngOndestroy
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
add a comment |
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 BehaviorSubject
s and expose them asObservable
s. You'll update the values of these BehaviorSubject
s 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 public
ly 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 subscribe
d 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.
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 BehaviorSubject
s and expose them asObservable
s. You'll update the values of these BehaviorSubject
s 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 public
ly 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 subscribe
d 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.
edited Nov 19 '18 at 16:19
answered Nov 19 '18 at 15:49
SiddAjmera
13.1k31137
13.1k31137
1
It can be achieved usingSubject
also . And it's good to useunsubscribe
in the component duringngOndestroy
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
add a comment |
1
It can be achieved usingSubject
also . And it's good to useunsubscribe
in the component duringngOndestroy
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
add a comment |
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;
}
}
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
add a comment |
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;
}
}
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
add a comment |
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;
}
}
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;
}
}
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
add a comment |
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
add a comment |
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
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
add a comment |
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
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
add a comment |
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
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
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
add a comment |
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
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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 likesubject.next({val: this.Number, IsOdd : this.IsOdd })
in your service methodIncreaseNumber
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