Reputation: 2487
In my angular app I have two services, one deals with the http layer, and the other is simply a route guard to implement the canActivate
method related to the status of the first service. For example:
backend.service:
@Injectable()
export class BackendService {
private data: any;
constructor(private http: Http) {
console.log('backend service constructor hit');
this.data = 'initial';
}
getData() {
console.log(this.data);
return this.data;
}
setData(data) {
// http stuff
this.data = data;
}
}
routeguard.service:
@Injectable()
export class RouteguardService implements CanActivate {
constructor(private backendService: BackendService) { }
canActivate() {
return this.backendService.getData() !== 'initial';
}
}
I believe I am providing one of the services in the wrong location? Currently I have both services in the providers
array of my app.module
. But I can tell with the console.log statements that the backend.service
is being new'd up separately when it gets called as part of the routing versus when a component uses it, so the data is different and the data always comes back as 'initial' when checked in the canActivate method despite having it set to something else from a component. Hope I explained that clearly, I'm still new to angular.
Do I need to provide one of the services in a different location or am I doing something else wrong entirely? Thanks for any pointers.
Upvotes: 2
Views: 3697
Reputation: 2487
I realized the problem was that I accidentally also included the backend.service
in the root app.component
providers, which meant that sub components of that would have one instance injected, however the one in my routes file was injected from app.module
providers instead, thus the duplicate services and discrepancy in data.
So the solution was to remove the service from the app.component
and always have it be provided by app.module
instead.
Upvotes: 1
Reputation: 3170
Try to declare the property you want to set in BackendService
as a static
one. Then use getters and setters to access it. Don't initialize it in the constructor
of the service.
@Injectable()
export class BackendService {
private static data: any = 'initial';
constructor(private http: Http) {
console.log('backend service constructor hit');
}
get data() {
console.log(this.data);
return BackendService.data;
}
set data(data: any) {
// http stuff
BackendService.data = data;
}
}
You can then access the private static data
value outside using the getters and setters. Like for example in the canActivate
guard,
@Injectable()
export class RouteguardService implements CanActivate {
constructor(private backendService: BackendService) { }
canActivate() {
return this.backendService.data !== 'initial';
// this.backendService.data <-- denotes getter
// this.backendService.data = 'not-initial'; <-- denotes setter
}
}
You are providing the services in the right places as understood from the question. Try and see if this fixes it.
Upvotes: 1