Angular - Executing a function in one component from another

Within my Angular-12 application, I have implemented two components: employee-detail and employee-edit.

In the employee-detail.component.ts file:

profileTemplate: boolean = false;
contactTemplate: boolean = false;

profileFunction() {
  this.profileTemplate = true;
  this.contactTemplate = false;
}

contactFunction() {
  this.profileTemplate = false;
  this.contactTemplate = true;
}

The corresponding employee-detail.component.html contains:

<div class="card-body">
  <div id="external-events">
    <button (click)="profileFunction()" type="button" class="btn btn-block btn-primary">Profile</button>
    <button (click)="contactFunction()" type="button" class="btn btn-block btn-success">Contact</button>
  </div>
</div>

<div *ngIf="profileTemplate" class="card card-default color-palette-box">

</div>

<div *ngIf="contactTemplate" class="card card-default color-palette-box">

</div>

By clicking on the buttons, either the profile or contact section is displayed based on the function triggered.

Now onto another component, which is employee-edit:

Within employee-edit.component.ts:

onSubmitProfile() {
  this.router.navigate(['/employees-detail', this._id]);
}

onSubmitContact() {
  this.router.navigate(['/employees-detail', this._id]);
}

I aim to achieve a functionality where upon calling onSubmitProfile(), it triggers profileFunction() causing the

<div *ngIf="profileTemplate" class="card card-default color-palette-box"> 

to become visible. Similarly, if onSubmitContact() is executed, it should render

<div *ngIf="contactTemplate" class="card card-default color-palette-box"> 

How can I implement this seamlessly?

Thank you

Answer №1

Solution 1: Angular Data Sharing Service

1.1 Include the event (contact or profile) within the fragment using NavigationExtras.

employee-edit.component.ts

export class EmployeeEditComponent implements OnInit {

  onSubmitProfile() {
    this.router.navigate(['/employees-detail', this._id], {
      fragment: 'contact'
    });
  }

  onSubmitContact() {
    this.router.navigate(['/employees-detail', this._id], {
      fragment: 'contact'
    });
  }
}

1.2 Extract the fragment from activatedRoute and perform actions based on the retrieved fragment.

employee-detail.component.ts

import { ActivatedRoute, Router } from '@angular/router';

export class EmployeeDetailComponent implements OnInit {
  constructor(private activatedRoute: ActivatedRoute) {}

  ngOnInit() {
    this.activatedRoute.fragment.subscribe(fragment => {
      if (fragment == 'profile') this.profileFunction();
      else if (fragment == 'contact') this.contactFunction();
    });
  }
}

See Sample Solution 1 in StackBlitz

Advantage: Simplifies content manipulation with fragment #event.

Disadvantage: The URL displays the implemented fragment #event.


Solution 2: Create Basic Angular Data Sharing Service

2.1 Develop EmployeeEventService including getter and setter methods for event$.

import { Injectable } from '@angular/core';
import { BehaviorSubject, Observable, Subject } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class EmployeeEventService {
  private event$: BehaviorSubject<
    keyof typeof EVENT | null
  > = new BehaviorSubject(null as keyof typeof EVENT | null);

  setEvent(event: keyof typeof EVENT) {
    this.event$.next(event);
  }

  getEvent() {
    return this.event$.asObservable();
  }
}

export enum EVENT {
  contact,
  profile
}

2.2 Inject EmployeeEventService and set the event using setEvent().

import { EmployeeEventService } from '../employee-event.service';

export class EmployeeEditComponent implements OnInit {
  constructor(
    public employeeEventService: EmployeeEventService
  ) {}

  onSubmitProfile() {
    this.employeeEventService.setEvent('profile');
    this.router.navigate(['/employees-detail', this._id]);
  }

  onSubmitContact() {
    this.employeeEventService.setEvent('contact');
    this.router.navigate(['/employees-detail', this._id]);
  }
}

2.3 Inject EmployeeEventService and obtain event$ Observable through getEvent().

import { EmployeeEventService } from '../employee-event.service';

export class EmployeeDetailComponent implements OnInit {
  constructor(
    public employeeEventService: EmployeeEventService
  ) {}

  ngOnInit() {
    this.employeeEventService.getEvent().subscribe(event => {
      if (event == 'profile') this.profileFunction();
      else if (event == 'contact') this.contactFunction();
    });
  }
}

View Sample Solution 2 in StackBlitz

Advantage: Manages event via service (addresses Solution 1's disadvantage).

Disadvantage: More complex implementation compared to Solution 1.

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

Tips on pre-filling a form using ngModel bindings

I have designed a Modal page where I aim to display pre-populated data to the user. Whenever the user edits the data, it should be bound to my local variable collectDataInModalPage_afterEdit. Check out the demo here:: https://stackblitz.com/edit/ionic-jse ...

Discovering the JavaScript source file for a package using WebStorm and TypeScript

In my TypeScript project, there is a usage of Express with the following method: response.send('Hello'); I am interested in exploring the implementation of the send() method. However, when I try to navigate to the source code by ctrl+clicking o ...

Tips for getting Atom cucumber step jump package to function properly on a Windows operating system

Just recently, I installed the Atom text editor along with the cucumber-step package available at this link. However, after pressing CTRL+ALT+j, it failed to jump to the step implementation/definition. My operating system is Windows 10 and I am utilizing ...

Is the variable empty outside of the subscribe block after it's been assigned?

Why is a variable assigned inside subscribe empty outside subscribe? I understand that subscribe is asynchronous, but I'm not sure how to use await to render this variable. Can someone please help me and provide an explanation? I am attempting to retr ...

Angular: Converting this code into a loop - A step-by-step guide

Currently, I am in the process of learning Angular along with its Angular Material UI Framework. Following the installation of dependencies, I created a Material Rank Table using the command below: ng generate @angular/material:table rank-table --module=ap ...

Encountering an issue with Angular 12 where a TypeError is being thrown, specifically stating "Cannot read properties of null (reading 'length') at

I encountered an error message while making a http request in my Angular Service. Strangely, this error only occurs after I logout, but it disappears upon logging back in: Below is the code snippet of my authentication Service: import { Injectable } from ...

Swapping out 'useResult' in graphql for Vue and Apollo: A step-by-step guide

I need to replace the useResult function that is fetching data from GraphQL with a computed function. const locationOptions = useResult( result, [], ({ getLocations }): Option[] => formatOptions(getLocations) ) Instead, I want ...

Implement the CSS styles from the Parent Component into the Child Component using Angular 6

Is there a way to apply CSS from the Parent Component to style the child component in Angular 6? Please advise on how to approach this issue. How can we inherit the css styles from the Parent Component? <parent> <child> <p>hello ...

Angular - Automatically filling in an empty input field upon dropdown selection

My goal is to create a DropdownBox that will automatically fill input fields based on the selected value. For example, selecting "Arnold" from the dropdown will populate another textbox with "Laptop". How can I accomplish this? { name:'Arnold', i ...

Issues with the linear-gradient feature in Ionic3 are preventing it from properly functioning

I'm currently experimenting with creating a unique gradient color in my Ionic3 variable.sass file. $colors: ( primary: #4471C1, secondary: #32db64, danger: #f53d3d, light: #f4f4f4, dark: #222, newcolor: linear-gradient( ...

The initial character of the input must always be a letter

I need assistance with an input element that requires 5 characters, with the first character being a letter: <input mdInput #acronyme placeholder="Company" type="text" maxlength="5" minlength="5" required [value]="acronyme.value.toUpperCase()"> Th ...

The function '() => Promise<T>' cannot be assigned to type 'Promise<T>'

Here is an interface I have: export interface ITreeViewItem { getChildren: Promise<ITreeViewItem[]>; ... Now, let's take a look at the implementation of it: export class MyClass implements ITreeViewItem { public async getChildren() ...

Angular Component - Array missing initial value in @Input property

Having trouble transferring values between components? I'm currently dealing with a situation involving two components: report-form and comment-form. The report form contains an array of comments, displaying a list of comments and a button for each on ...

Attempting to transform calc application into TypeScript, what data type should this function be?

Currently in the process of converting a calculator app to TypeScript. I've noticed that TypeScript is not prompting me to define the types for the three functions (handleClick, handleEqual, handleClear). Is specifying the type for the argument eno ...

Setting up Typescript classes that inherit from one another with diverse properties for each subclass

I'm fairly new to Typescript and currently grappling with how to effectively manage class inheritance when base classes have distinct properties. Essentially, I have a base class where I aim to define shared functionality and a series of subclasses w ...

The process of releasing a component created with angular-starter onto npm is now underway

After creating angular components with the Angular Starter Kit from https://github.com/AngularClass/angular-starter, I am looking to package them and deploy them on NPM for easy use in other projects. However, I found the documentation to be lacking in thi ...

Placing a MongoDB query results in an increase of roughly 120MB in the total JS heap size

I'm puzzled by the fact that the heap size increases when I include a MongoDB database query in a function within my controller. Here is the code for my router: import { Router } from "express"; import profileController from '../contro ...

Creating a standard arrow function in React using TypeScript: A Step-by-Step Guide

I am currently working on developing a versatile wrapper component for Apollo GraphQL results. The main objective of this wrapper is to wait for the successful completion of the query and then render a component that has been passed as a prop. The componen ...

Troubleshooting Problem in Angular 6: Difficulty in presenting data using *ngFor directive (data remains invisible)

I came across a dataset that resembles the following: https://i.sstatic.net/S0YyO.png Within my app.component.html, I have written this code snippet: <ul> <li *ngFor="let data of myData">{{data.id}}</li> </ul> However, when I ...

Guide on implementing ng-if in an Ionic 2 HTML template

To display records if found and show "no records found" otherwise, I have implemented the code below: <div ng-if="program.videourl"> <video width="100%" controls="controls" preload="metadata" webkit-playsinline="webkit-playsinline" class="vide ...