Reputation: 2208
I have an app.component and child.component. I want to pass the variable inside child component which I'm passing in router-outlet.
Routing looks like this in app.module.ts :
const routes: Routes = [
{'path': '', 'component': ChildComponent}
]
app.component.html :
<button (click) = "toggle()">toggle</button>
<p>toggle value in app.component.html :</p> {{val}}
<router-outlet></router-outlet>
app.component.ts :
....
....
val = 1;
toggle(){
if(this.val == 1){
this.val = 0;
}else{
this.val = 1;
}
}
....
....
So, Now on my browser output looks like:
Now I want to pass this value 1 or 0 that I'm getting whn I click on button to Child component and I want to show it with "child works" line like this:
Both values should change on clicking the button. I tried to use services but not working. I don't want to attach the val in url and send in path as route param as it will be visible in url.
Upvotes: 2
Views: 2095
Reputation: 4294
You need to provide service at module level instead of component level.Please find below code:
your module:
@NgModule({
imports: [BrowserModule,
HttpModule
],
declarations: [App],
providers: [SharedService],
bootstrap: [App]
})
export class AppModule { }
your service:
export class SharedService {
public val: any = 0;
}
your app component:
constructor(private sharedService: SharedService){
}
....
....
this.sharedService.val = 1;
toggle(){
if(this.sharedService.val == 1){
this.sharedService.val = 0;
}else{
this.sharedService.val = 1;
}
}
....
....
In above component, don't provide SharedService as provider otherwise it will create the new instance of SharedService.
Using SharedService at the module level will create only one instance.
Hope it helps!!
Upvotes: 0
Reputation: 17899
You can also inject the parent component to the child one in constructor:
export class ChildComponent {
constructor(private app: AppComponent) {...}
}
Here is a way to pass events as the author of the question asked but I do not suggest to go with this path (only if there is a strong reason why parents and child should be coupled)
@Component({
selector: 'my-app',
template: `
<button (click)="toggle()">click</button>
<child-component></child-component>
`,
})
export class App {
subject = new Subject();
id=0;
toggle() {
this.subject.next(this.id++);
}
}
@Component({
selector: 'child-component',
template: `
{{id | async }}
`,
})
export class Child {
id;
constructor(private app: App) {
this.id = app.subject.asObservable();
}
}
Upvotes: 0
Reputation: 12960
There are two ways to correctly provide services, I don't remember the exact names:
A Global service, which you define in your module and can be accessed inside all the components declared inside the module:
@NgModule({
...
providers: [yourServiceName]
})
A local Service, I guess, it's called a dedicated service.Which you provide inside a Component
@Component({
...
providers: [yourService]
})
This service is accessible to this component and all the child components of this component.
If you are doing any of these two, then the data should be available in your desired component.
Remember not to provide the service in both the components. It should be provided in a higher hierarchy.
Upvotes: 1