Passing variable values in Angular 6

Is there a way to transfer the value of a variable from Component1 to a variable in Component2 without using any template binding?

I have two components, Header and Footer. In the Header component, there is a boolean variable called test that I need to pass the value from test to TEST2 in the Footer component.

I tried using @Input but couldn't find a solution without using template bindings like [test]="test"

In simple terms, I just want to pass a value from one .ts file to another .ts file.

I referred to this example: Pass data to nth level child component in Angular 4

However, the variable is still not being 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;

   }

}

When I call my function changeDark() from HeaderComponent.html, it doesn't set 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

Finally, I was able to achieve the desired outcome with this code: The issue was with the providers declared in FooterComponent. When the providers were declared in FooterComponent, I was getting undefined. Once I removed them and kept the providers only in app.modules.ts, the variable was set and read correctly.

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

Answer №1

Refer to the official Angular documentation on how parent and children can communicate via a service. The concept involves creating a service with RxJS Subject properties that components can inject to interact with each other. Using Subjects allows for both subscription and emission of values simultaneously. Learn more about Subjects by reading this article on understanding subjects.

If you are not familiar with RxJS Subjects, as a temporary solution (although not recommended), you can share values within the same service by modifying its properties. However, in this scenario, components will not be notified of any changes. This is why Subjects are a preferred method for enabling component interaction through a service.

Answer №2

A convenient solution is to utilize a service to store the variable and allow components to access it easily. For more information on services, check out: this link

Answer №3

If you're looking to share data across your Angular components, utilizing Angular services is a great solution. Check out my response here:

Pass data to nth level child component in Angular 4

Another approach is using RxJs to communicate with specific isolated components through Observables.

Angular 6 communication between component and a directive

Answer №4

IMPORTANT UPDATE:

Hello @PatrikSpišák, it is essential to note that when you utilize a getter in Angular, any modifications within your application will prompt Angular to recalculate the value. The key here is having only one variable (which should be defined in the service). By creating a getter method, you can then access this value directly in the .html file of your component. This not only allows you to easily retrieve the value but also gives you the flexibility to modify other variables within the component.

Update 2: Correction made to variable names

In your footer component, it is crucial for the footer to have knowledge about the value retrieved by getTheme.

constructor(private headerService: HeaderService) 
get getTheme()
{
    return this.headerService.getTheme;
}

For your header component, it needs to be aware of the nightTheme value and should be able to make changes to it.

constructor(private headerService: HeaderService) 
get getTheme()
{
    return this.headerService.getTheme;
}
set getTheme(value)
{
    this.headerService.getTheme=value;
}
//You are free to make changes anywhere
this.getTheme=true

Regarding your headerService service,

getTheme:any;
constructor(){}

It is worth noting that you currently only possess one variable, getTheme, within the headerService, unless you want to refer to another variable specifically named "nightTheme," based on what I observed from your code.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

When the mat-select form-field in Angular is focused, the mat-label vanishes

Recently delved into Angular and have been studying the Material documentation on mat-form-fields. Encountering a strange bug where the mat-label disappears upon focusing the form-field, only to reappear once focus is lost. The issue seems to be specific ...

Error in vue3 with typescript: unable to assign a ComputeRef<number[]> argument to an iterable<number> in d3.js

This code snippet was originally sourced from an example at https://medium.com/@lambrospd/5-simple-rules-to-data-visualization-with-vue-js-and-d3-js-f6b2bd6a1d40 I attempted to adapt the example to a TypeScript/Vue 3 version, and below is my implementatio ...

How to select a DOM element in Angular 2.x

Although it may seem simple, there are not many examples of using Angular 2.0 yet. In one of my components, I have a situation where I need to add a class to the body tag. However, my application is bootstrapped deeper than the body element, so I am looki ...

How can a TypeScript function be used to retrieve a string (or JSON object)?

When attempting to retrieve data from a web API using TypeScript and return the JSON object, encountering an error has left me puzzled. Inside my function, I can successfully display the fetched data on the console, but when I try to return it with return ...

Changing the left border color dynamically based on the value of an object within a loop

My objective is to achieve a design where the left border of the cards appears as shown in the image below: The loop structure is as follows: <ion-card *ngFor="let office of searchItems" class="custom"> Ideally, I would like to ...

What could be causing the inability to update a newly logged-in user without refreshing the page?

Hello, I have encountered an issue with my application that involves registration and login functionality. The problem arises when a new user logs in, as I must refresh the page to get the current user information. I am currently using interpolation on the ...

Is it advisable to avoid circular imports in typescript development?

After spending 4 long hours troubleshooting a TypeScript error, I finally found the root cause. Object literal may only specify known properties, and 'details' does not exist in type 'Readonly<{ [x: `details.${string}.value`]: { value: st ...

Unidentified Controller Scope in Angular and TypeScript

I am struggling with my Angular 1.5 app that uses Typescript. Here is a snippet of my code: mymodule.module.ts: angular.module('mymodule', []).component('mycomponent', new MyComponent()); mycomponent.component.ts export class MyCont ...

Resetting the initial values in Formik while utilizing Yup validation alongside it

Currently, I am working on a React application with Typescript and using Formik along with Yup validation. However, I have encountered an issue with setting values in a Select element. It seems that the value is not changing at all, or it may be resettin ...

Angular 7: Polyfill required for npm package to support 'Class'

I am encountering an issue where my Angular 7-based app is not functioning in Internet Explorer 11. The npm package I am using begins in index.js: class PackageClass { // code } While the app works as intended in other browsers, it fails to open in ...

Compel a customer to invoke a particular function

Is there a way to ensure that the build method is always called by the client at the end of the command chain? const foo = new Foo(); foo.bar().a() // I need to guarantee that the `build` method is invoked. Check out the following code snippet: interface ...

Tips for displaying a modal popup in Angular with content from a separate page

I want to display a modal popup on a different page that has its body content in the app.component.html file. App.Component.html: <ng-template #template> <div class="modal-header"> <h4 class="modal-title pull-left">Modal ...

Checking for undefined based on certain conditions

When looking at the following code snippet type stringUndefined = "string" | undefined; type What<T> = T extends undefined ? "true" : "false"; const no : What<stringUndefined> = ""; The value of ' ...

Remove a specific NgRx node using LazyLoading technique

I am currently developing an Angular 9 application utilizing NgRx with lazy loading functionality. Upon initial app load, the state appears as follows: https://i.sstatic.net/C7C7P.jpg However, when navigating to the '/account-config' route, th ...

Phaser3 encountering issues while loading files from Multiatlas

Attempting to utilize the multiatlas functionality in Phaser alongside TexturePacker. Encountering this issue: VM32201:1 GET http://localhost:8080/bg-sd.json 404 (Not Found) Texture.js:250 Texture.frame missing: 1/1.png The JSON file can actually be fou ...

Can Javascript (PWA) be used to detect fake GPS or mock GPS in applications?

Looking for a solution to prevent users from using Fake Location tools in my PWA application that gathers absence location data. Is there a method or package in JavaScript to detect the presence of Fake GPS installed on the device? ...

What is the best way to determine the type of `rootReducer`?

My project is set up with a combination of React, Redux, Immutable.js, and TypeScript. As I worked on implementing it, I made an effort to declare types wherever possible which led me to discover an interesting issue. A code example illustrating the proble ...

Utilizing Next.js and React to interact with Open AI through API requests

I'm currently experimenting with the OpenAI API to develop a chatbot using React, TypeScript, and Next.js. I am facing an issue where clicking the send button in the UI does not trigger any action. Even after adding console.log statements, nothing sho ...

Incorporating SVG graphics within a SharePoint web part

I am in the process of developing a webpart for SharePoint using the SharePoint Framework, TypeScript, and ReactJS. I have encountered an issue while trying to incorporate an svg image into my webpart code, resulting in build errors. Initially, I used the ...

The NodeJS application experiences a crash if incorrect parameters are provided to the API

Currently, I have built a CRUD API using TypeScript with Node.js, Express, and MongoDB. My goal is to ensure that the API functions correctly when the correct parameters are sent through a POST request. However, if incorrect parameters are passed, the Node ...