Angular 2 typescript invoke javascript function - javascript

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

Instantiate a JavaScript object in TypeScript

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

unable to call javascript function from angular 13 component

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.

Call a javascript function registered using c# from typescript

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:

Typescript module export not work when import something

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?

Angular 2 with TypeScript and Input decorator generate bad javascript ids

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.).

Categories