Retrieve functions contained within the component.ts file of an Angular library: tips and tricks

I have developed an Angular library, named 'mylib', where I have utilized only the mylib.component.ts file. The HTML element codes are included inside the template variable of this file, along with the functions responsible for modifying these elements. After successfully building and publishing the library to npm, I encountered a problem while trying to install and use it in a new project. The error message stated that the functions were not recognized. What could be the issue here? I need guidance on how to access functions declared within the component.ts file of an Angular library. And if direct access is not possible, what steps should be taken to utilize these functions after installing the library in another project?

mylib.component.ts

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'srr-mylib',
  template: `
    <h1> Random Text </h1>
  `,
  styles: [
  ]
})
export class ElapsedtimerComponent implements OnInit {

constructor() { }

ngOnInit(): void {
}

startTrans(){

//some code here

}
}

mylib.module.ts

import { NgModule } from '@angular/core';
import { MylibComponent } from './mylib.component';
import { CommonModule } from '@angular/common';  
import { BrowserModule } from '@angular/platform-browser';



@NgModule({
declarations: [MylibComponent],
imports: [
CommonModule,
BrowserModule
],
exports: [MylibComponent]
})
export class MylibModule { }

public.api.ts

/*
* Public API Surface of mylib
*/

export * from './lib/mylib.service';
export * from './lib/mylib.component';
export * from './lib/mylib.module';

This is how I attempted to use the above library in a new project:

app.component.html

<srr-mylib></srr-mylib>

app.component.ts

import { Component } from '@angular/core';
import { MylibModule } from '@somename/mylib'

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {

constructor(
private libz:MylibModule
) {

libz.startTrans() //<----- This does not work. It gives the error "Property 'startTrans' does not exist on type 'MylibModule'.ts(2339)"
}


}

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppComponent } from './app.component';
import { MylibModule } from '@somename/mylib'

@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
MylibModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }

Answer №1

When working in Angular, it is important to avoid directly calling methods of other components. Instead, consider using @Input to trigger a function call:

mylib.component.ts

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'srr-mylib',
  template: `
    <h1 [ngStyle]="{'font-size': myFontSize}"> Random Text </h1>
    <button type="button" (click)="onClickPlusFontSize()">Larger font size</button>
  `,
  styles: [
  ]
})
export class ElapsedtimerComponent implements OnInit, OnChanges {

  @Input() inputFontSize: number;
  @Output() inputFontSizeChange: EventEmitter<number> = EventEmitter();

  public myFontSize: string;

  constructor() {
  }

  ngOnInit(): void {
  }


  ngOnChanges(changes: SimpleChanges): void {
    if (changes.inputFontSize) {
      // triggered every time the @Input value changes
      this.onFontSizeChange(changes.inputFontSize.currentValue);
    }
  }

  onFontSizeChange(newFontSize) {
    this.myFontSize = `${newFontSize}px`;
    // some other stuff
  }

  onClickPlusFontSize() {
    this.inputFontSize++; // updates the value
    onFontSizeChange(this.inputFontSize); // triggers the function that should be called, as if the change came from the parent
    this.inputFontSizeChange.emit(this.inputFontSize) // tells the parent that the value changed
  }
}

app.component.html

<srr-mylib [(inputFontSize)]="myLibFontSize" (inputFontSizeChange)="onFontSizeChange($event)"></srr-mylib>

app.component.ts

import { Component } from '@angular/core';
import { MylibModule } from '@somename/mylib'

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  public myLibFontSize: number;

  constructor() {
    this.myLibFontSize = 12; // will trigger ngOnChanges on myLib
  }

  onSpecificEvent() {
    // do stuff
    this.myLibFontSize = 20; // will also trigger ngOnChanges on myLib
  }
 
  onFontSizeChange(newFontSize: number) {
    // this method is optionnal.
    // with '[(inputFontSize)]="myLibFontSize"' in the HTML, the value of 'myLibFontSize' will already be updated automatically.
    // this function is only useful if the parent wants to do specific work when the value changes.
    // so there is absolutely no need to do "this.myLibFontSize = newFontSize" here.
    // the only thing to know, is that you have no clue of either 'myLibFontSize' will be updated after of before 'onFontSizeChange' is called.
    // So always use 'newFontSize' in this method, to be sure of the value used.
    console.log('myLibFontSize value changed !', newFontSize);
  }

}

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

Utilizing React Hooks efficiently with JSDoc annotations and destructuring arrays

Seeking guidance on how to properly JSDoc a React Typescript component that uses hooks, specifically when working with declared destructured arrays. Despite my efforts, I have not been able to find a solution that allows JSDoc to work seamlessly with destr ...

Enhancing nested structures in reducers

Currently, I am utilizing react, typescript, and redux to develop a basic application that helps me manage my ingredients. However, I am facing difficulties with my code implementation. Below is an excerpt of my code: In the file types.ts, I have declared ...

There are no HTTP methods being exported in this specific file. Remember to export a named export for each individual HTTP method

Currently, I am working on a React.js/Next.js project that incorporates Google reCAPTCHA. The frontend appears to be functioning properly as I have implemented print statements throughout the code. However, I am encountering an error in the backend display ...

Next.js is experiencing issues with the build process

I encountered an issue while working on a Next.js project with NextAuth.js. The problem arises when I try to define my authOptions, as a TypeScript error indicates that the object is not compatible with the expected type for AuthOptions. Here's the sn ...

Sorting and categorizing RxJS Observables

Learning about reactive programming is a new and sometimes challenging experience for me. If we have a list of events from a service called event[] The structure of an event is as follows: Event: { beginDate: Date, name: string, type: State } State: ...

Angular 2 encountered an issue trying to identify the module for the ManagersService class

Encountering an issue when attempting to build using ng build -prod. The error message is as follows: ERROR in Cannot determine the module for class ManagersService in C:/Test/src/app/shared/common/managers/managers.service.ts! Add ManagersService to the ...

Tips for showcasing a collection of interactive buttons (with each column as a button) utilizing mat-table within Angular 8

I am dealing with a situation where I need to implement dynamic buttons on a page using Angular 8. Furthermore, the buttons will change dynamically based on the selection made in a drop-down menu. ...

What is the best way to extract accurate information from an observable?

I'm having trouble retrieving the correct data from an observable in my project. Here is the code for my API call: getLastxScans(amount: number): Observable<Scan[]> { return this.http.get<Scan[]>(`${this.ROOT_URL}/Scan/amount/${amo ...

Encountered build problems after transferring Ionic2 app from Mac to PC

After transferring my ionic2 application from a Mac to a Windows PC along with the nodemodules, I attempted to run it using npm run android. However, an error appeared as detailed below: https://i.sstatic.net/K1LS0.png My current Ionic information is as ...

Sharing properties between components

While this topic has been discussed extensively, I am still struggling with my specific example. In my setup, I have a react-select component nested within another component, which is then part of the larger App component. SubjectSelect.tsx export default ...

Distinguishing between type assertion of a returned value and defining the return type of a function

What distinguishes between performing a type assertion on a function's return value and explicitly typing the return value in the function signature? Let's consider only simple functions with a single return statement. interface Foo { foo: numbe ...

An exploration of distributing union types within conditional type arrays in TypeScript

One interesting challenge I am facing involves a conditional type that utilizes a generic type T in order to determine an Array<T> type. For example: type X<T> = T extends string ? Array<T> : never; The issue arises when I input a union ...

strophe js is designed to handle the reception of individual messages specifically within the context of Angular

I am currently utilizing Strophe.js for establishing a connection with an XMPP server in an Angular 4 application. When using the connection.addHandler() method, I can successfully receive a single message within my listener function after the connection h ...

Demonstrate an angular animation triggered by a button click

I would like to initiate an animation when a button is clicked animations: [ trigger('simpleFadeAnimation', [ state('in', style({opacity: 1})), transition(':enter', [ style({opacity: 0}), animate(300 ) ]), ...

How can I take photos in bulk when I open the camera on Ionic 3?

Is there a way to capture multiple images at once using the camera? Currently, I am only able to capture one image when the user clicks. However, I would like to capture four images when the user clicks the success button. let options: CaptureImageOption ...

How to showcase the array object nested within an array of objects in Angular 2

Here is the content of my JSON file: country_id:String, name:String scholardetails:[{ country_id:String, scholarshipname:String, scholarshiplink:String }] ...

What is the best way to include multiple targets/executables within a single Node.js repository?

My React Native app is developed using TypeScript, and I want to create CLI tools for developers and 'back office' staff also in TypeScript. These tools should be part of the same monorepo. After attempting to do this by creating a subfolder wit ...

Is there a way to implement personalized error management in TypeScript with Express?

For a while now, I have been using JavaScript to create my APIs but recently made the switch to TypeScript. However, I keep encountering errors along the way. One particular error handler I have set up is for when a route cannot be found, as shown below: i ...

How to format dates with month names in various languages using the date pipe

In my HTML code, I have set up the date display like this: <span >{{ item.lastModified | date : 'MMM d, y' }}</span> As a result, the displayed date looks something like Jul 20, 2021. However, when I switch my browser's language ...

Efficiently process and handle the responses from Promise.all for every API call, then save the retrieved data

Currently, I am passing three API calls to Promise.all. Each API call requires a separate error handler and data storage in its own corresponding object. If I pass test4 to Promise.all, how can I automatically generate its own error and store the data in ...