Return the reference to an injected service class from the location where it was implemented

Is it feasible to return a reference from a component class with a custom interface implemented to the injected service class in my Angular 6 project?

Here is an example of what I am aiming for.

ServiceClass

@Injectable()
export class MyService {
    constructor(private parent: MyComponent){ // <- Somehow get a reference from the component I inject this into?
        parent.doStuff();
    }
}

ComponentClass

@Component({
  selector: 'project-a-component',
  template: `
    <div>stuff</div>
  `,
  styleUrls: ['./a.component.scss']
})
export class AComponent implements MyComponent {
    constructor(private myService: MyService){ }

    doStuff(): void {
        console.log('yey!');
    }
}

Edit: My goal is to listen to the OnDestroy event for a component in order to run .pipe(takeUntil(parent.isDestroyed)) to unsubscribe a subscription without having to add it manually every time I use my services in my project or pass a reference to my parent component in each method call. Having the reference available in the constructor (or just one place) would be ideal. Trying to explain the issue as clearly and simply as possible.

Answer №1

Check out this interesting article on how to automatically unsubscribe in Angular: . By hooking into the OnDestroy lifecycle method of components, you can customize your own behavior:

export function MyDecorator( constructor ) {
  const original = constructor.prototype.ngOnDestroy;
  constructor.prototype.ngOnDestroy = function () {
    if (this.myService) {
      // Perform custom actions here
    }
  };
}

You can follow the example provided in the article to automatically unsubscribe all subscriptions, not just for a single service. Import the decorator into your component and apply it like this:

@MyDecorator
export class MyComponent {
// ...

Answer №2

I found a helpful approach to managing this issue by creating a method within my service that takes the component's interface and assigns it to a variable within the service itself. By calling this method in the ngOnInit() lifecycle hook wherever it is needed, I was able to significantly reduce the amount of code within my components. It seems like a practical and efficient way to handle this task.

@Injectable()
export class DataService {
    private currentComponent: MyComponent;

    constructor(){}

    setCurrentComponent(component: MyComponent): void {
        this.currentComponent = component;
    }
}

@Component({
  selector: 'project-b-component',
  template: `
    <div>content goes here</div>
  `,
  styleUrls: ['./b.component.scss']
})
export class BComponent implements MyComponent {
    constructor(private dataService: DataService){
        dataService.setCurrentComponent(this);
    }
}

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 Computed Properties in Angular Models

We are currently in the process of developing an application that involves the following models: interface IEmployee{ firstName?: string; lastName?: string; } export class Employee implements IEmployee{ public firstName?: string; public l ...

Using the timer function to extract data within a specific time frame - a step-by-step guide

Is there anything else I need to consider when the temperature increases by 1 degree? My plan is to extract data from my machine for the last 30 seconds and then send it to my database. set interval(function x(){ If(current_temp != prev_temp){ if((c ...

Troubleshooting Angular2: Issues with ngModel functionality within an ngIf directive

Whenever I attempt to reference an NgModel directive using a template reference variable within an *ngIf statement, I encounter a "Cannot read property 'valid' of undefined" error. Consider the following form as an example: <form (ngSubmit)= ...

Error encountered during Typescript compilation in Angular9 using Babylon4.1.0 - Unable to locate 'react' module or namespace 'JSX' not found

I am currently encountering compilation issues with Babylon4.1.0 within an angular9 app. It appears that the inspector is having trouble importing the internally used "react" module. To reproduce the issue: * Create a new angular9 app using the CLI * Add @ ...

Can the inclusion of a type guard function impact the overall performance of the application?

const typeGuard = (param: any): param is SomeType => { return ( !!param && typeof param === "object" && param.someProperty1 !== null && param.someProperty2 === null ) } If a type guard function similar to the code above is exe ...

Resolving the error message "Default props must have construct or call signatures for 'Component' in Typescript"

I'm currently working on a function component called MyComponent and I'm facing an issue with setting a default prop for component. The goal is to have the root node render as a "span" if no value is provided. However, I am encountering the follo ...

Viewing an image from a local file on a web browser

I am currently working on a project where I want the user to be able to select a local image that will then be displayed on the page. As someone who is new to web development, I did a lot of research and found some helpful information on StackOverflow. I t ...

I'm receiving an error message stating "mongoose.connect is not a function" while attempting to establish a connection with mongoose. Can you help me troub

I'm a beginner in Node.js and I'm currently working on creating a node/express/mongoose server app using TypeScript. Below is my app.ts file: // lib/app.ts import express from 'express'; import * as bodyParser from 'body-parser&a ...

The object may be 'null', and the argument of type 'null' cannot be passed as a parameter of type 'CloudProduct' in Angular

After successfully creating my backend API with functionalities to create, update, and delete products, I have been tasked with developing the frontend using Angular and Bootstrap. While I managed to make the homepage visually appealing, I encountered issu ...

The type 'void | Observable<User>' does not include the property 'subscribe'. Error code: ts(2339)

authenticate() { this.auth.authenticate(this.username, this.password).subscribe((_: any) => { this.router.navigateByUrl('dashboard', {replaceUrl: true}); }); } I'm puzzled by this error message, I've tried a few solu ...

The custom validator in Material2 Datepicker successfully returns a date object instead of a string

Im currently working on developing a unique custom validator for the datepicker feature within a reactive form group. Within my code file, specifically the .ts file: form: FormGroup; constructor( private fb: FormBuilder, ...

Error: Angular 4 encountered an unexpected character and could not parse

I am encountering an issue with a code snippet that looks like this: persona = { ... edadNiño = 9 } I'm trying to bind it using the following syntax: <input type="number" name="edadNiño" [(ngModel)] = "persona.edadNiño"> However, when I a ...

Exploring the concept of union return types in TypeScript

Hello, I am facing an issue while trying to incorporate TypeScript in a way that may not be its intended use. I have created a custom hook called useGet in React which can return one of the following types: type Response<T> = [T, false, false] | [nul ...

Building a resolver to modify a DynamoDB item via AppSync using the AWS Cloud Development Kit (CDK)

After successfully creating a resolver to add an item in the table using the code provided below, I am now seeking assistance for replicating the same functionality for an update operation. const configSettingsDS = api.addDynamoDbDataSource('configSet ...

What is the best way to provide data types for Vuex mapState functions?

In my Vuex component using Typescript, I want to add types to the mapping functions in mapState. Previously, I had it set up like this: @Component({ computed: { ...mapState( MY_NAMESPACE, { fooIndex: ( state: MyModel ) => state.values.index ...

Angular 4: Triggering Scroll Event when Select Dropdown Reaches End

I am attempting to trigger a Scroll Event within the component class when the end of the dropdown list is reached. I have a large list and initially only load the first 30 records in ngOnInit(). As the user scrolls down, I want to update the dropdown list ...

What's the best way to position an ion-label at the top of the stack

I'm having trouble creating an input label similar to the new Google style. However, when the label moves up, it gets cut in the middle as shown here. Despite trying to adjust the margin, padding, and Z-index, none of these solutions have resolved my ...

What is the proper way to employ if and else if statements within Angular2?

Here's a question that has been duplicated on my How to utilize *ngIf else in Angular? post! ...

What is the relationship between directives, templates, and ViewContainers in Angular?

I have implemented a basic functionality in my component where numbers are injected after a delay using a custom directive called *appDelay It is known that the Angular syntax hints with * will de-sugar into something like this: <ng-template ...> .. ...

Using LitElement: What is the best way to call functions when the Template is defined as a const?

When the template is defined in a separate file, it's not possible to call a function in the component. However, if the template is defined directly as returning rendered HTML with this.func, it works. How can one call a function when the template is ...