Is there a correct way to invoke a JavaScript function from a component in Angular 2 (TypeScript) ?
Here is my component :
import { ElementRef, AfterViewInit } from '#angular/core';
export class AppComponent implements AfterViewInit {
constructor(private _elementRef: ElementRef) {
}
ngAfterViewInit() {
/**
* Works but i have this error :
* src/app.component.ts(68,9): error TS2304: Cannot find name 'MYTHEME'.
* src/app.component.ts(69,9): error TS2304: Cannot find name 'MYTHEME'.
*/
MYTHEME.documentOnLoad.init();
MYTHEME.documentOnReady.init();
/**
* Works without error, but doesn't seem like a right way to do it
*/
var s = document.createElement("script");
s.text = "MYTHEME.documentOnLoad.init(); MYTHEME.documentOnReady.init();";
this._elementRef.nativeElement.appendChild(s);
}
}
Calling the JavaScript function directly result in an compilation error, but the syntax in the "compiled" JavaScript file (app.component.js) is correct :
AppComponent.prototype.ngAfterViewInit = function () {
MYTHEME.documentOnLoad.init();
MYTHEME.documentOnReady.init();
};
The 2nd way (appendChild) works without error, but i don't think (altering the DOM from typescript/angular) is the correct way to do it.
I found this : Using a Javascript Function from Typescript I tried declaring the interface :
interface MYTHEME {
documentOnLoad: Function;
documentOnReady: Function;
}
But the TypeScript doesn't seem to recognize it (no error in the interface declaration).
Thanks
Edit :
Following the answer by Juan Mendes this is what i ended with :
import { AfterViewInit } from '#angular/core';
interface MYTHEME {
documentOnLoad: INIT;
documentOnReady: INIT;
}
interface INIT {
init: Function;
}
declare var MYTHEME: MYTHEME;
export class AppComponent implements AfterViewInit {
constructor() {
}
ngAfterViewInit() {
MYTHEME.documentOnLoad.init();
MYTHEME.documentOnReady.init();
}
}
You have to tell TypeScript about external (JavaScript) declarations using declare. See https://www.typescriptlang.org/docs/handbook/writing-declaration-files.html
interface MyTheme {
documentOnLoad: Function;
documentOnReady: Function;
}
declare var MYTHEME: MyTheme;
Or anonymously
declare var MYTHEME: {documentOnLoad: Function, documentOnReady: Function};
Related
I tried to instantiate a javascript object in a typescript file, basically in an Angular Application but there is an error as object is not defined.
My JavaScript file:
import { EventEmitter } from 'events';
export default class Cursor extends EventEmitter {
constructor(el) {}
//some methods
}
My typescript file
First alternative :
declare var Cursor:any;
export class HomeComponent implements OnInit {
ngOnInit(): void {
const cursor = new Cursor();
console.log(cursor.emit('enter'))
}
}
=> ERROR ReferenceError: Cursor is not defined
Second alternative (importing js file)
import Cursor from '../utils/js/cursor';
export class HomeComponent implements OnInit {
ngOnInit(): void {
const cursor = new Cursor();
console.log(cursor.emit('enter'))
}
}
=> Property 'emit' does not exist on type 'Cursor'.
In that case there is an inheritance problem with class Cursor extending EventEmitter
Can someone give me an hand with that problem ?
Thanks
There is a recent change introduced in Angular 13 where the old way of calling javascript functions from angular components isn't working anymore.
I am facing an issue with calling a javascript function from a specific component.
I already tried the usual way and here is my approach.
FILE: src\assets\js\main.js
(function($) {
"use strict";
function animatedProgressBar () {
$(".progress").each(function() {
var skillValue = $(this).find(".skill-lavel").attr("data-skill-value");
$(this).find(".bar").animate({
width: skillValue
}, 1500, "easeInOutExpo");
$(this).find(".skill-lavel").text(skillValue);
});
}
})(jQuery);
FILE: src\app\about-me\about-me.component.ts
import { Component, OnInit } from '#angular/core';
declare function animatedProgressBar(): any;
#Component({
selector: 'app-about-me',
templateUrl: './about-me.component.html',
styleUrls: ['./about-me.component.css']
})
export class AboutMeComponent implements OnInit {
//declare animatedProgressBar: any;
constructor() {}
ngOnInit(): void {
animatedProgressBar();
}
}
This code snippet throws an error: ERROR ReferenceError: animatedProgressBar is not defined
I checked the answer on This StackOverflow topic but it didn't work for me.
Looking forward to some valuable inputs on this issue.
I have added a function call from C# using RegisterStartupScript as follows:
Page.ClientScript.RegisterStartupScript(this.GetType(), "PrintWindowJScript", "<script type=\"text/javascript\">OpenNewWindow() { Reports_OpenWindowNamed(URL, 350, 250, \"PrintAttachPopupWindow\"); }</script>");
The above code will add it into the DOM, so when i call OpenNewWindow(), it should call the function from my angular component.
Now in my angular component i have a dropdown change function in Typescript (Angular). I need to call the OpenNewWindow() from here as mentioned below.
interface IMyWindow {
OpenNewWindow: Function;
}
declare var v_MyWindow: IMyWindow ;
export class MyComponent implements OnInit {
ngOnInit() {
}
attachChange(attachDropDown: any) {
if(attachDropDown.value && attachDropDown.value.id == "MyValue"){
v_MyWindow.OpenNewWindow();
}
}
}
The above code gives me "v_MyWindow" as undefined.
I have tried refering to this article, but not working.
Can anyone let me know if i am missing anything? What should i do to call the function?
You've already created the interface and declared the variable v_MyWindow, you only need to assign the property OpenNewWindow.
change:
Page.ClientScript.RegisterStartupScript(this.GetType(), "PrintWindowJScript", "<script type=\"text/javascript\">OpenNewWindow() { Reports_OpenWindowNamed(URL, 350, 250, \"PrintAttachPopupWindow\"); }</script>");
to:
Page.ClientScript.RegisterStartupScript(this.GetType(), "PrintWindowJScript", "<script type=\"text/javascript\">v_MyWindow.OpenNewWindow = function() { Reports_OpenWindowNamed(URL, 350, 250, \"PrintAttachPopupWindow\"); }</script>");
where do you assign a value to v_MyWindow? Maybe you first want to get a reference to the native window object in Angular.
An approach to that is explained here:
https://juristr.com/blog/2016/09/ng2-get-window-ref/
Basically you define an injectable wrapper around the window import:
import { Injectable } from '#angular/core';
function _window(): any {
// return the global native browser window object
return window;
}
#Injectable()
export class WindowRef {
get nativeWindow(): any {
return _window();
}
}
Then you import it into your application like this:
import { WindowRef } from './WindowRef';
#NgModule({
...
providers: [ WindowRef ]
})
export class AppModule{}
Consume you depency in your component like that:
export class MyComponent implements OnInit {
constructor(
private nativeWindow: WindowRef) { }
ngOnInit(): void {
console.debug('Native window inner width: ', this.nativeWindow.nativeWindow.innerHeight);
}
}
This should give you a console output like this:
I trying to create PowerBI custom visual and i must use typescript for that. I'm not too familiar with typescript. So I got 2 ts files under same namespace(I using VS Code editor):
visual.ts
module powerbi.extensibility.visual {
export class Visual implements IVisual {
private target: HTMLElement;
private updateCount: number;
constructor(options: VisualConstructorOptions) {
console.log('Visual constructor', options);
this.target = options.element;
this.updateCount = 0;
}
public update(options: VisualUpdateOptions) {
console.log('Visual update', options);
console.log(testFunc());
$('#datepicker').datepicker();
this.target.innerHTML = `<p>Update count: <em>${(this.updateCount++)}</em></p>`;
}
public destroy(): void {
//TODO: Perform any cleanup tasks here
}
}
}
test.ts
import React=require('react');
import ReactDOM=require('react-dom');
module powerbi.extensibility.visual {
export function testFunc():String{
return "Test string";
}
export class TestClass{}
}
Problem is when there is no imports in test.ts i can see and use exported function "testFunc()"(VS Code see that function) but when i add imports i cant user that function(also VS Code don't recognize that function)? Is there any way to have imports and to use that function?
Hello guys,
I'm learning angular2 with Typescript and developing a new example I found some weird behaviour that maybe you can explain.
TypeScript Version:
1.8.10
Angular Version:
2.0.0-rc.1
Code
When I'm adding the #Input to a field, the generated js has errors in the generated ids:
This is the Typescript class I'm working on:
import { Component, Input, OnInit } from '#angular/core';
import { Event } from '../../model/event';
import { EventService } from '../../services/event-service';
#Component({
selector: "event-detail",
templateUrl: "event-detail.html",
providers: [EventService],
moduleId: module.id
})
export class EventDetailComponent {
#Input()
event: Event;
eventTypes : string[];
constructor(private service: EventService){
}
ngOnInit(){
this.loadEventTypes();
}
save(){
this.service.create(this.event).then(
event => this.event = event
);
}
cancel(){
this.event = null;
}
loadEventTypes(){
let response = this.service.listEventTypes()
.then(eventTypes => this.eventTypes = eventTypes);
}
}
And this is the error:
The following javascript code generated by the compiler is throwing the error because the event_1 doesn't exist.
__decorate([
core_1.Input(),
__metadata('design:type', event_1.Event)
], EventDetailComponent.prototype, "event", void 0);
Do you know what could be happen? Could a configuration be in conflict?
It looks like you did not load '../../model/event' module (perhaps it contains error, wrong path etc.).