I've got a service called TargetService
that I'm injecting into various other components. This TargetService has a property called Targets
which is a collection of Target
objects.
My problem is that I want this collection to persist after routing to another view. My routes are working fine, but as soon as the route changes, the Service loses the content of any variables, essentially, it's re-initializing the Service. My understanding was that these injected services are to be singletons that can be passed around?
In the following example, on the TargetIndex, I click a button that populates the Targets[]
object on the service (this.targetService.targets = ts;
). This is working fine, then I route to the TargetShow page, and then back to this index and now this Targets[]
property is empty when I want it to contain what I've already populated.
What am I missing here?
App.Module
const routes: Routes = [
{ path: '', redirectTo: 'targets', pathMatch: 'full'},
{ path: 'targets', component: TargetIndexComponent },
{ path: 'targets/:id', component: TargetShowComponent }
]
@NgModule({
declarations: [
AppComponent,
TargetComponent,
TargetIndexComponent,
TargetShowComponent
],
imports: [
BrowserModule,
FormsModule,
ReactiveFormsModule,
HttpModule,
RouterModule.forRoot(routes)
],
providers: [TargetService],
bootstrap: [AppComponent]
})
export class AppModule { }
TargetService
@Injectable()
export class TargetService {
public targets: Target[];
constructor(private http: Http) {}
getTargets(hostname: String): Observable<Target[]> {
return this.http.request(`url`).map(this.extractData);
}
private extractData(res: Response) {
let body = res.json();
return body || [];
}
}
TargetIndex
@Component({
selector: 'app-targets',
templateUrl: './target-index.component.html',
providers: [TargetService]
})
export class TargetIndexComponent {
loading = false;
constructor(private http: Http, private targetService: TargetService) {}
loadTargets(hostname: HTMLInputElement) {
this.loading = true;
this.targetService.getTargets(hostname.value)
.subscribe((ts: Target[]) => {
this.targetService.targets = ts;
this.loading = false;
})
}
}
TargetShow
@Component({
selector: 'app-target-show',
templateUrl: './target-show.component.html'
providers: [TargetService]
})
export class TargetShowComponent {
id: string
constructor(private route: ActivatedRoute, private targetService: TargetService) {
route.params.subscribe(params => { this.id = params['id']; })
}
}
Try to remove TargetService from components providers, cause you already added it in module providers. When you add this service to components providers, DI creates new instances of it.
Here is quote from https://angular.io/docs/ts/latest/guide/dependency-injection.html :
When to use the NgModule and when an application component? On the one hand, a provider in an NgModule is registered in the root injector. That means that every provider registered within an NgModule will be accessible in the entire application.
On the other hand, a provider registered in an application component is available only on that component and all its children.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With