0

I’m building an angular library (let’s consider it as ‘mylib’). In this library, I have used only the mylib.component.ts file. I added the html element codes inside the template variable of this file. And the functions that are used to do modifications to those html elements are also in the same component.ts file. I successfully built it and published to npm. But when I try to install and use it in a new project, it says that such functions doesn’t exist. What have I done wrong? All I want to know is, how to access the functions declared inside component.ts of an angular library. If it's not possible, then what should I do to access these functions after installing this 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';

And this is how i tried 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 doesn't work. it gives the error as "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 { }
4
  • 2
    Never inject a Module in the constructor. You should try using @ViewChild to get the component inside your HTML. But this is an anti-pattern, you should find an other way to change the color (a common service, or an @Input in your lib's component...) Commented Nov 5, 2020 at 21:01
  • @Random No actually changeColour is not an actual function. And my intention is not to change the colour too. I just used that function name here as an example. I just want to know how to access the functions declared inside the component.ts file of a library Commented Nov 6, 2020 at 2:02
  • 1
    The content of the method "changeColor" shouldn't matter for what I said. Can you give a real exemple of the function then ? Does the function returns something ? Does the function has an effect on the component itself ? Commented Nov 6, 2020 at 7:57
  • @Random There are many functions. For now lets consider a function which changes the font size of a certain html element in the 'template'. here's the code inside that function document.getElementById('timer').style.fontSize = fontSize+'px'; I know you can do this using an Input(). But I need to do this programmatically using a function. Cuz I need to apply the same logic for other functions as well. Those said functions doesn’t return anything. They just modify the html elements. Commented Nov 6, 2020 at 8:08

1 Answer 1

1

In Angular, a component should not call directly an other component's method. So from what I understand of what you try to do, I would use an @Input instead, which triggers 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);
  }

}
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for the support! lets say there's a counter in that html elements which is value can be changed using up and down buttons there. If I write a function to return the current value of that counter, how can I access that kind of a function when I'm using the library?
@SankhaRathnayake For this, you can use the "two ways binding", see my edit

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.