1

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);
  }
  
}

7
  • You can't... Either use a common service or the template syntax. Components shouldn't be tightly coupled Commented Aug 29, 2018 at 13:54
  • You can't access the property of the component , instead you can access the value inside the service in the component where you want't access. Commented Aug 29, 2018 at 15:30
  • In your source code you didn't invoke the changeDark and changeLight anywhere , that's the place where you are setting the value to the service. Also I would suggest you to move the source code to the question by editing it and remove the answer. Commented Aug 29, 2018 at 15:43
  • Sorry for that, I have already eddited my post. You can see that actually Im calling that function which trigger events which I defined except the last one which I need to pass to Footer component Commented Aug 29, 2018 at 17:20
  • @PatrikSpišák, use a getter in your component: Don't declare nightTheme, just: get nightTheme(){ return this.headerService.getTheme;} Commented Aug 29, 2018 at 19:10

4 Answers 4

1

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 Subjects - 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.

Sign up to request clarification or add additional context in comments.

Comments

0

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

Comments

0

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

Comments

0

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"

4 Comments

But I dont need show value at all. I need just pass value from one variable in.Header.ts to another variable in Footert.ts Problem is that i have same variable (nightTheme) in Header and Footer component. In the header component is button which should change theme from Light to Dark with changeDark() function. So my button does what I expecting but only in the Header component, so I mean, when I hit button, my theme is switch to dark because function set nightTheme to TRUE, but I need set nightTheme to TRUE in FooterComponent at the same time when I hit button in HeaderComponent
Update the answer
I have tried your code but does not work... nighTheme variable in Footer component still remain set as False while in Header Component was set to True
I wrote so quickly and change the names of the function:see the stackbliz stackblitz.com/edit/…

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.