Patrik Spišák
Patrik Spišák

Reputation: 77

Angular 6 - Passing variable value

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

Answers (4)

Eliseo
Eliseo

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

Jameel Moideen
Jameel Moideen

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

shokha
shokha

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

Upvotes: 1

qwrtln
qwrtln

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

Related Questions