AmanDeepSharma
AmanDeepSharma

Reputation: 2208

How to pass value from parent component to child in routing: Angular 2

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:

enter image description here

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:

enter image description here

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

Answers (3)

Jayakrishnan
Jayakrishnan

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

Julia Passynkova
Julia Passynkova

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

Ashish Ranjan
Ashish Ranjan

Reputation: 12960

There are two ways to correctly provide services, I don't remember the exact names:

  1. A Global service, which you define in your module and can be accessed inside all the components declared inside the module:

    @NgModule({
        ...
        providers: [yourServiceName]
    })
    
  2. 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

Related Questions