mp9007
mp9007

Reputation: 79

Typescript - Application wide state (Singleton?)

I'm a beginner in typescript and I have read a lot about typescript & singletons, and I still can get it work.

I have the same problem as this: Node.js & Typescript Singleton pattern : seems like singleton is not shared between singleton users.

I have read this article too: https://fullstack-developer.academy/singleton-pattern-in-typescript/ and this one: http://www.codebelt.com/typescript/typescript-singleton-pattern/

In the end, when i go from a module to another, its seems like my singleton class is always at is default state.

When calling getInstance(), since the value is set to new Path(), it seems obvious to me that the singleton is always at is default state, but in many sources online (like the previous two provided) it is the way to do it.

What am I doing wrong ? Thanks.

Here is my singleton (Path.ts):

class Path{
    private static _instance: Path = new Path();
    private _nodes: NodeModel[];
    private _links: LinkModel[];

    public static getInstance(): Path{
        if(Path._instance)
            return Path._instance;
        else
            throw new Error("Path is not initialized.");
    }

    public setPath(nodes: NodeModel[], links: LinkModel[]){
        this._nodes = nodes;
        this._links = links;
    }

    public nodes(){ return this._nodes; }
  [...]
}
export = Path;

PathDefinition.ts

module PathDefinition{
    export function defaultDefinition(){
        var nodes = [
            new NodeModel(...),
            new NodeModel(...)
        ];
        var links = [
            new LinkModel(...),
            new LinkModel(...)
        ];
        Path.getInstance().setPath(nodes, links);
    }
}
export = PathDefinition;

controller.ts

module Controller{
    export function init(){
        console.log(Airflow.getInstance().nodes());
        //console.log => undefined
    }
}

EDIT

As a C# developer, I thought that wrapping each file content into a "module" (or namespace as mentioned by Paleo) was the best way to organize my code. After reading provided links by Paleo and especially this one : How do I use namespaces with TypeScript external modules? , I understand why my above code is not the best way to do with Typescript.

Upvotes: 3

Views: 6426

Answers (1)

Fenton
Fenton

Reputation: 251062

Here is a cut down example that results in re-using the same instance of your Path class. I have removed most code to just show things working.

module.ts

class Path {
    public nodes: string[] = [];
}

export const PathSingleton = new Path();

The const here is only going to exist once, even though we're going to import this module in a few places...

othermodule.ts

import { PathSingleton } from './module';

PathSingleton.nodes.push('New OtherModule Node');
console.log(PathSingleton.nodes);

export const example = 1;

We have added to the node list in this module...

app.ts

import { PathSingleton } from './module';
import { example } from './othermodule';

PathSingleton.nodes.push('New Node');
console.log(PathSingleton.nodes);

const x = example;

We are also adding to it here.

Running this simple app results in the following output...

From othermodule.js
[ 'New OtherModule Node' ]
From app.js
[ 'New OtherModule Node', 'New Node' ]

That last line is the "proof" that all the interactions are occurring against the same instance.

Upvotes: 7

Related Questions