Executing a function in a separate component [Angular]

I'm still learning Angular. This question on Stack Overflow is similar to what I'm facing, but it doesn't provide the answer I need. In my case, the two components are independent and not parent-child. They exist at the same directory level, which sets my problem apart from others. I've tried using:

  1. @ViewChild();
  2. @Output() ....EventEmitter()

However, I keep encountering an error in navbar.component.ts:

ERROR TypeError: "this.articles is undefined"

The first component is called NavBar and the second component is called Articles

So, the challenge is for the pressed() method in NavBar to call the callSearch(arg) method in Articles.

Below is a snippet of my navbar.component.ts

import { ..., ViewChild } from '@angular/core';
import { ArticlesComponent } from '../articles/articles.component';

@Component({
  ...
})
export class NavbarComponent implements OnInit {

  text='something';

  @ViewChild(ArticlesComponent, {static: false}) articles: ArticlesComponent;

  constructor() { }

  /*  This method is triggered by a click event in the HTML page*/
  pressed(text: string) {
    this.articles.callSearch(text);
  }

  ngOnInit() {
  }
}

navbar.component.html

<li class="nav-item">
  <button class="btn" (click)="pressed(text)">Search</button>
</li>

And here is the component I want to call a method from NavBar.

articles.component.ts

import { ... } from '@angular/core';

@Component({
  ...
})
export class ArticlesComponent implements OnInit {

  articles = [];
  filteredArticles=[];

  constructor(...) { }

  ngOnInit() {
    ...
  }

  /*  invoked from navbar typescript file to trigger SearchFunction below*/
  callSearch(text: string) {
    this.SearchFunction(text);
  }

  SearchFunction(text: string) {
    this.filteredArticles=(this.articles.filter(e => {
      /* some logic*/
    }));
  }
}

articles.component.html

<div *ngFor="let article of filteredArticles; let i = index;">
  <div class="card text-center">
    <div class="card-body">
      <!-- card design related html -->
    </div>
  </div>
</div>

If you spot any errors, please point them out.

P.S.: You can access the code on StackBlitz.

Answer №1

If you need to communicate between two components that are not directly related, a service can help bridge the gap.

    @Injectable({
    providedIn: 'root',
})
export class CommunicationService {

    private dataSubject: Subject<any> = new Subject<any>();

    public getDataStream() {
        return this.dataSubject.asObservable();
    }

    public sendData(data: any) {
        this.dataSubject.next(data);
    }

To use this service in your components, make sure to import it:

import { CommunicationService } from ...

In the component where you want to send data, simply call:

this.communicationService.sendData(yourData);

In the component where you want to receive the data:

this.communicationService.getDataStream().subscribe(
    data => {
        this.receivedData = data;
        this.callYourFunction();
    }
)

You can also call the function without passing any specific data if needed.

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

Different methods to display my view when the initial value is late

I am facing an issue with a component that manages a boolean value in its state and has a button to toggle this value. The boolean value is obtained from an object created in a parent component. The button gets rendered when the object is created, but th ...

The Angular JS Root scope is modified after submitting a form

I'm new to Angular JS and I'm trying to figure out how to save an object into $rootScope in my application. However, when I try to make a post request without including the object from rootScope, it doesn't work as expected. Now, on a newly ...

sending object value to directive rather than other data variables

I have been attempting to customize the functionality of this functioning http://jsfiddle.net/markcoleman/JNqqU/. In the current fiddle, the object is directly assigned where I am trying to change it to $scope.obj.items. However, passing the object to the ...

Webpack 4 operates in a nonsequential manner when loading pages

Recently, I made the switch to webpack 4 for my Rails project where Vue.js 2 is utilized. In addition, I have configured chunks in my setup. However, after the upgrade, I noticed that the page loading sequence seems off. The HTML contents load before style ...

What is the process for converting BitmapData from Flash into HTML canvas?

Currently facing a significant challenge as I transition from using Flash to JS. The issue lies in handling SOAP returned data, specifically when dealing with images stored as strings that need to be converted into BitmapData for use in Flash. Despite tryi ...

Adding a custom property to a React component

Currently, I am facing an issue while attempting to modify an MUI component. Everything works smoothly until I execute the build command, at which point it fails. I have experimented with a few variations of this, but essentially I am looking to introduce ...

The File Reader just informed me that parameter 1 is not in the form of a blob

When working with a file input in my React component, I keep encountering an error with the FileReader. Here's the specific error message: Uncaught TypeError: Failed to execute 'readAsDataURL' on 'FileReader': parameter 1 is not o ...

Can one verify if an Angular application currently has active app modules running?

I am developing a unique plugin for Angular that is designed to automatically initialize an Angular app module if none are found. However, if there is already a running or declared ng-app, my plugin will utilize that existing module instead. Here is an i ...

Knockout.JS encounters difficulty retrieving the value attribute in a select tag when the data is sourced from the server

After making an ajax request and binding the dropdown list, I noticed that the select tag was not reading the value attribute. However, when I bind the drop down list in the view model, it does recognize the value. For example: It works if I bind the mode ...

Strange behavior observed with @click.native on <b-form-checkbox> in Bootstrap-Vue

Encountering a problem with b-form-checkbox and b-form-checkbox-group. Using @click.native, the method is triggered twice. Oddly, directly displaying selected values in the DOM {{selected}} reveals the correct elements in the array. However, when I console ...

The union type generated by TS Expression is too intricate for proper representation using Material-UI and @react-three/fiber

I've been working on a Next.js application that incorporates both Material-UI and the @react-three/fiber library. Recently, after upgrading to Material-UI V5, I encountered an error. Here's the specific error message: https://i.sstatic.net/SNEw5 ...

Accessing an external webpage within a React.js application while maintaining visibility of the navbar

Seeking assistance on how to open an external link within a React app below the navbar when navigating to "/WebSite". Currently using react router for page navigation. Here's the code snippet: const App = () => { return( <BrowserRouter&g ...

Tips for dynamically updating an input within a shadow DOM using code?

Snippet: https://jsfiddle.net/5zrwdjy7/2/ I'm currently working on automating keystrokes with a script within Cypress, however, the target website I am dealing with utilizes web components as inputs. These input elements are nested inside what is kno ...

The paths required are not correct following the transpilation of a TypeScript file using Babel

Issue Every time I use nodemon with npm run start, I encounter the error message "Error: Cannot find module 'Test'". Similarly, when I build files using npm run build and try to run ./dist/index.js, I face the same issue. It seems that the requ ...

Disabling ion-select in Ionic 2 with Typescript

To disable an ion-select element in Angular, you can use the disabled attribute like this: <ion-item> <ion-label stacked>Property Type</ion-label> <ion-select [(ngModel)]="propType" (ionChange)="ionChanger()" di ...

React: Struggling to render values within {} of a multidimensional object

I'm facing a challenge that I can't seem to overcome and haven't found a solution for. The values between curly braces are not displaying in the Content and Total components. I've double-checked the JSX rules, but it seems like I might ...

Inquiry into the use of Jquery.ajax()

Hey there, I'm curious about using Jquery Ajax to retrieve a numeric value from a website. Any suggestions on where I should begin? Any advice would be greatly appreciated. Thanks in advance! Best regards, SWIFT ...

Showing information in Angular without using $scope

When working with Angular and angular UI-Router, my goal is to display content without relying on $scope. In my mainController, using directives like ng-repeat is no problem. However, I am struggling to access information from my postsController. Despite ...

Protractor: A Guide to Right Clicking on a Specific Element

Is it possible to trigger a right-click event on a specific element using mouse simulation? I have attempted the following code, but the context menu does not appear: var testElem = $('#someElementId span'); return browser.actions().mouseMove(t ...

Refreshing the page does not trigger Angular callHooks

Encountering an issue with the proper invocation of F5 button or directive call URL from the address bar resulting in ngOnInit not being triggered correctly. Using a debugger to analyze the situation, it was noticed that callHook is not initiated after ngO ...