How to declare a singelton in typescript

295 Views Asked by At

I would like to integrate an existing library into my typescript project. There is a (external) singleton object which i want to declare and use.

Example: Within xyz.js, following object will be declared:

var mxUtils = {
    /* some fancy code */
    findNode: function(node, attr, value)
    {
        // even more fancy code
        return node;
    }
};

During runtime, there is a global single instance of mxUtils. Since this is an external library, I don't want to implement or rewrite the whole library in typescript.

Now I tried to declare this singleton, but I failed.

I tried this code, to declare the Object as global var.

Utils.d.ts:

declare interface ImxUtils { 
    findNode(node:any, attr:string, value:string):any;
}

declare var mxUtils: ImxUtils;

My compiler is completely satisfied with this, but during runtime, mxUtils is undefined

main.ts:

// some fancy things
export class fancyComponent implements OnInit {
    // some magic here...
    var tmpNode = mxUtils.findNode(aNode, aString1, aString2);    
}

Even though my debugger lists a global mxUtils Object.

Can anyone help me on this?

Please remark: * xyz.js is already referenced and is present. e.g.

xyz.js

function mxEventObject(name)
{
//
}

mxEventObject.prototype.getName = function()
{
    return this.name;
};

Utils.d.ts

declare class mxEventObject {
    constructor(name: string);
    getName: () => string;
}

main.ts

export class fancyComponent implements OnInit {
    // some magic here...
    var tmpEvent = new mxEventObject(aSampleString);

}

will work as expected.

Since there is a global object named mxUtils, but i can not access this object within my export of fancyComponent, i suppose there is a scope problem.

1

There are 1 best solutions below

2
On

In angular in better to relay on DI ( Dependency Injection) system to handle object creation and inject theses object to component , you need to create an angular service and add this service to providers list in AppModule component decorator.

mx-utils.service.ts

export class MxUtilsService {

  /* some fancy code */
  public findNode(node:any, attr:any, value:any) {
    // even more fancy code
    return node;
  }
}

app.module.ts

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

app.compoennet.ts

import { Component } from '@angular/core';
import { MxUtilsService } from './mx-utils.service';

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

  constructor(private _mxUtilsService: MxUtilsService) {
    console.log(this._mxUtilsService);
    console.log(this._mxUtilsService.findNode({node:1},'node',1));
  }
}

any service add to providers list in appModule(root) is considered a singleton , MxUtilsService will create ones and will be the same object when you inject to another components

stackblitz demo

Why your object is undefined you need to add xyz.js to scripts list in .angular-cli.json