Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Call Angular web component method (CustomElement)

I have these two examples:

Example 1:

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html'
})

export class AppComponent {
  options:any = {isOpen: false };

  logOptions() {
    console.log(this.options);
  }

}

Example 2:

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html'
})

export class AppComponent {
  options:any = {isOpen: false };

  @Input() logOptions() {
    console.log(this.options);
  }

}

in html:

<app-root></app-root>

<script>
  document.querySelector('app-root').logOptions();
</script>

In Example 1 returns error: document.querySelector(...).logOptions is not a function

In Example 2 returns: undefined

Does anyone have any ideas?

like image 626
ferhado Avatar asked Sep 07 '25 00:09

ferhado


1 Answers

It's a bit late, but in case you still need this, there are couple of ways you could get it to work.

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html'
})

export class AppComponent {

    // @Input() << see comments below
    options: any = {isOpen: false };
    
    // This will NOT be available outside the component, in plain JS
    logOptions() {
        console.log(this.options);
    }

    // This will work ONLY if options is @Input()
    @Input()
    logOptions2() {
        console.log(this.options);
    }
    
    // This property will always provide correct data
    // Ideally a getter should not be @Input() though
    @Input()
    get logOptions3() {
        return this.options;
    }
}

You can access them in plain JavaScript code as

const logComponentOptions = () => {
    const el = document.querySelector('app-root');
    // el.logOptions(); << Error
    el.logOptions2(); // works ONLY if options is @Input()
    console.log(el.logOptions3); // WORKS
    console.log(el.options); // if options is @Input()
}
  1. So the logOptions3 property can always be used to get the options from plain javaScript code. But semantically not correct (a getter as @Input())
  2. The first logOptions() method is not accessible from outside as it is NOT marked @Input()
  3. The logOptions2() method is accessible but can only print correct value IF options is also marked @Input()
  4. But if you mark the options property as @Input(), you can directly access that itself, rather than wrapping that in another method
  5. Lastly, if you simply make @Input() options = false, you can also access it as a simple attribute from the HTML as well
<app-root options="false"></app-root>

Update

If you want to pass data into the component, you can simply expose a setter property with @Input. Then you can set the value from outside the component, with JavaScript

@Input()
public set myData(value: MyDataType) {
    // validation & logic if any
    this._myData = value;
}

// Then in JavaScript
const el = document.querySelector('app-root');
el.myData = {a: 10, b: true, c: 'my data object' }
like image 158
Arghya C Avatar answered Sep 09 '25 05:09

Arghya C