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

Exploring the syntax of typescript when using createContext

Just starting out with typescript and I have some questions. Could someone break down the syntax used in this code snippet for me? What is the significance of having two groups containing signIn, signOut, and user here? Is the first group responsible fo ...

Having trouble with enzyme in React Typescript application

One of my components is called app.tsx import React, { useState } from "react"; const TestComponent = () => { return( <> <div className="head">hey there</div> <select name="xyz" id=&qu ...

Offset the CDK Menu

Is it possible to adjust the position of the trigger using the CDK overlay by setting an offset (e.g. cdkConnectedOverlayOffsetY)? I've looked through the CDK menu documentation but couldn't find a similar functionality. Is there a method to achi ...

React Typescript Context state isn't refreshing properly

Struggling to modify my context state, I feel like I'm overlooking something as I've worked with context in the past. The challenge lies in changing the 'isOpen' property within the context. You can view my code here: CodeSand **app.ts ...

TypeScript - Issue with generic function's return type

There exists a feature in typescript known as ReturnType<TFunction> that enables one to deduce the return type of a specific function, like this function arrayOf(item: string): string[] { return [item] } Nevertheless, I am encountering difficulti ...

AGM MAP | Placing marker within a custom polygon created on the map

Query Description I am utilizing the AGM_MAP library for an Angular website, which includes a map where users can select an address for their orders. Current Issue The problem I am facing is that when I add a polygon to the map, the marker cannot be p ...

Utilize [markdown links](https://www.markdownguide.org/basic-syntax/#

I have a lengthy text saved in a string and I am looking to swap out certain words in the text with a highlighted version or a markdown link that directs to a glossary page explaining those specific words. The words needing replacement are contained within ...

Guide on formatting the API response using a callback function in Angular development

How can I reformat my API response using a callback function and access the data within the angular subscribe method? I attempted to use mergemap but it didn't work as expected. this.http.get('https://some.com/questions.xml', {headers, res ...

Update a specific form data field within an Angular application

I recently encountered a situation where I had an angular form with 9 fields and submitted it to the server using a post request. However, I realized that I had only filled in values for 8 fields while leaving one as null. Now, in a new component, I am w ...

Angular does not display a loading indicator in the header

When handling service calls, I have implemented a loading indicator to provide feedback to the user. However, it appears that this indicator is not effectively preventing users from interacting with header items before the loading process is complete. My ...

Tips for managing a group of checkboxes in Angular 2 RC5

My task involves creating a form where users can edit their magazine subscriptions. Here is the code snippet I am working with: Component: export class OrderFormComponent { subscriptions = [ {id: 'weekly', display: 'Weekly new ...

SharePoint Online / Angular - Issue: Unhandled Error: Zone is already loaded

I recently completed a project in Angular and integrated it into a SharePoint page using the Content Editor. Everything was running smoothly until yesterday, when I encountered an error while loading the page. zone-evergreen.js:42 Uncaught Error: Zone alre ...

Attempting to integrate Bootstrap 5 accordion into Angular 17 using ngFor has posed a challenge for me

<div class="accordion w-50 mx-auto" id="accordionExample"> <div *ngFor="let note of notes; index as i;"> <div class="accordion-item"> <h2 class="accordion-header" id="headi ...

Leverage Angular, NodeJS, and Sequelize to extract data from HTML tables

Is there a way to extract data from a specific HTML table, identified by its ID, and save it into a mysql database using a NodeJS API with sequelize? The HTML code snippet that needs to be parsed: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 T ...

Obtain the Enum's Name in TypeScript as a String

I am currently looking for a solution to transform the name of an enum into a string format. Suppose I have the following Response enum, how can I obtain or convert 'Response' into a string? One of my functions accepts any enum as input and requi ...

Cypress eliminating the "X-CSRFToken" header

There seems to be an issue with the Cypress test runner where it is removing X-CSRFToken from the request header, leading to a 403 Forbidden error. I have compared the headers between a manual run and a Cypress test run, and you can see the difference in t ...

unable to retrieve information from the redis cache

Attempting to retrieve data from cache using the readData function in the controller file. Encountering an issue where the someVal variable is initially undefined after calling readData, but eventually gets populated with data after receiving a callback ...

Tips for identifying MIME type errors in an Angular 9 application and receiving alerts

While working on my Angular app, I encountered the MIME type error Failed to load module script: The server responded with a non-javascript mime type of text/html. Fortunately, I was able to resolve it. Now, I'm stuck trying to figure out how to rece ...

Is it possible to showcase a unique date for every item that gets added to a list?

I am new to using React, so please bear with me. I want to be able to show the date and time of each item that I add to my list (showing when it was added). I am struggling to get this functionality working with my current code. Any help or explanation o ...

The browser is sending numerous requests for the audio tag

I am facing an issue with an audio tag in my code. The URL is being parsed and returned by a function. <audio class="fr-draggable" controls autoplay [src]="extractAudioUrl(message)" style="width:100%"></audio> Unfortunately, the browser ends ...