Reputation: 77
Is there any option for how to pass only value from one variable saved in Component1 to a variable in Component2 without any template binding?
I have component Header and Footer, and in the header is a variable test which is boolean and I need pass value from variable TEST to variable TEST2 in Footer component.
I was looking for some solutions with @Input but I did not find any solutions without template bindings as [test]="test"
In short, I just need to pass value from one .ts
file to another .ts
file.
I was following this example: Pass data to nth level child component in Angular 4
But variable still is not passed to the component
HeaderService.ts
import { Injectable } from '@angular/core';
@Injectable()
export class HeaderService {
getTheme: boolean;
}
HeaderComponent.ts
import { Component, OnInit, ViewEncapsulation } from '@angular/core';
import { SideBarService } from '../sidebar/sidebar.service';
import { googleMapConfig } from '../content/google-map/config.service';
import { HeaderService } from './header.service';
@Component({
selector: 'app-header',
templateUrl: './header.component.html',
styleUrls: ['./header.component.scss'],
encapsulation: ViewEncapsulation.None,
})
export class HeaderComponent implements OnInit {
Name = 'Menučkáreň';
Navigation = 'Navigácia';
nightTheme;
icons = ['favorites','notification_important'];
tooltip = ['Obľúbené položky','Zoznam zmien'];
constructor(
public sideBarService: SideBarService,
public mapService: googleMapConfig,
private headerService: HeaderService
) { }
public toggle() {
this.sideBarService.toggle.emit();
}
public changeDark() {
this.nightTheme = true;
this.headerService.getTheme = true;
this.mapService.changeDark.emit();
}
public changeLight() {
this.nightTheme = false;
this.headerService.getTheme = false;
this.mapService.changeLight.emit();
}
ngOnInit() { }
}
FooterComponent
import { Component } from '@angular/core';
import { HeaderService } from '../header/header.service';
@Component({
selector: 'app-footer',
templateUrl: './footer.component.html',
styleUrls: ['./footer.component.scss'],
providers: [HeaderService]
})
export class FooterComponent {
Copyright = 'Copyright 2018 | Vytvoril Patrik Spišák';
Version = '0.0.1';
nightTheme: boolean;
constructor(private headerService: HeaderService) {
this.nightTheme = this.headerService.getTheme;
}
}
So when I invoke my function changeDark() from HeaderComponent.html it does not trigger this.headerService.getTheme = true;
<mat-grid-tile>
<button (click)="this.changeDark($event)" mat-icon-button>
<mat-icon aria-label="Nočný režim">brightness_3</mat-icon>
</button>
</mat-grid-tile>
UPDATE
So I was able achieve what I was needed with this code: Problem was with providers declared in FooterComponent. While were providers declared in FootersComponent I was getting Undefined, when I removed them and keep providers only in app.modules.ts variable is set and read properly.
HeaderService.ts
import { Injectable } from '@angular/core';
@Injectable()
export class HeaderService {
nightTheme:boolean;
get data():boolean{
return this.nightTheme;
}
set data(value:boolean){
this.nightTheme = value;
}
constructor(){}
}
Header Component
import { Component, OnInit, ViewEncapsulation } from '@angular/core';
import { SideBarService } from '../sidebar/sidebar.service';
import { googleMapConfig } from '../content/google-map/config.service';
import { HeaderService } from './header.service';
@Component({
selector: 'app-header',
templateUrl: './header.component.html',
styleUrls: ['./header.component.scss'],
encapsulation: ViewEncapsulation.None,
})
export class HeaderComponent implements OnInit {
Name = 'Menučkáreň';
Navigation = 'Navigácia';
icons = ['favorites','notification_important'];
tooltip = ['Obľúbené položky','Zoznam zmien'];
constructor(
public sideBarService: SideBarService,
public mapService: googleMapConfig,
private headerService: HeaderService
) {}
public toggle() {
this.sideBarService.toggle.emit();
}
public changeDark() {
this.headerService.nightTheme = true;
console.log(this.headerService.nightTheme);
this.mapService.changeDark.emit();
}
public changeLight() {
this.headerService.nightTheme = false;
console.log(this.headerService.nightTheme);
this.mapService.changeLight.emit();
}
ngOnInit() { }
}
Footer Component
import { Component, OnInit } from '@angular/core';
import { HeaderService } from '../header/header.service';
@Component({
selector: 'app-footer',
templateUrl: './footer.component.html',
styleUrls: ['./footer.component.scss'],
})
export class FooterComponent {
Copyright = 'Copyright 2018 | Vytvoril Patrik Spišák';
Version = '0.0.1';
constructor(private headerService: HeaderService) { }
ngOnInit() {
console.log('FOOTER:'+this.headerService.nightTheme);
}
}
Upvotes: 1
Views: 8063
Reputation: 57929
UPDATE
@PatrikSpišák, when you use a getter, any change in your application force Angular to "recalculate" the value. The "tip" is that you have anly a variable (the variable is the variable defined in the service). Make a getter make that you can use the "getter" in the .html of the component. You can use the getter to make any change of other variable of the component
Update 2 (corrected the name of the variables)
Your footer component. footer need know the value of getTheme
constructor(private headerService: HeaderService)
get getTheme()
{
return this.headerService.getTheme;
}
Your header component, header need know the value of nightTheme and can change
constructor(private headerService: HeaderService)
get getTheme()
{
return this.headerService.getTheme;
}
set getTheme(value)
{
this.headerService.getTheme=value;
}
//You can do anywhere
this.getTheme=true
Your service headerService
getTheme:any;
constructor(){}
You only has one variable getTheme in headerService (equal you can use another variable). Seeing your code I think you want to referred to "nightTheme"
Upvotes: 0
Reputation: 7931
You can use Angular services for sharing your common data across your components. Please see my answer
Pass data to nth level child component in Angular 4
And other option is RxJs , you can communicate with some isolated component through Observable
Angular 6 communication between component and a directive
Upvotes: 0
Reputation: 3179
Take a look at official angular documentation - Parent and children communicate via a service. The idea is to create a service which has some RxJS Subject
properties. Your components will inject this service and using those Subject
s - they can interact with each other. Why Subject
? because you can subscribe and emit values at the same time. For more information - check this article about understanding subjects.
If you're not familiar with RxJS Subjects, as a workaround (but it's not a good solution) - you can just share the values of the same service by changing it properties. But in this case your components cannot be notified if there were any changes. This is why Subjects are good candidate for component interaction via Service.
Upvotes: 1
Reputation: 281
You could use a service which stores the variable and from which components can access it. More about services here: https://angular.io/tutorial/toh-pt4
Upvotes: 0