Methodician Methodician - 25 days ago 11
TypeScript Question

How can I use a service or global function in the @Component declaration?

I have a service that helps with some routing issues related to my environment and now I need to cope with template routing issues

Ideally I would be able to do something like this:

import { PathSvc } from './globals/path.svc';
@Component({
templateUrl: this.pathSvc.alias + '/app/my.comp.html'
})
export class MyComp {
constructor(private pathSvc: PathSvc) { }
}


Of course that doesn't work because the service isn't made to be used in the component declaration so I get a runtime console error:


requests:38 Error: TypeError: Cannot read property 'pathSvc' of
undefined(…)


Typescript and modular JS in genaral is a new thing to me. Maybe there's a more direct way to import my function to a bunch of modules and use it anywhere I want?

I realize this isn't an optimal approach and I should be getting these results using the

<base href="/{alias}" />


methodology but that's not happening right now.

The short of it is that somehow all that stopped working while I tried to make my ASP.Net MVC + Angular 2 app more dynamically aware of its hosting environment and handle back end and front end routing conflicts. I'd like to get this working in more of a "right way" but at the moment, I just need it to work so my boss is happy and a global routing script seems like the way.

Answer

if i correctly understood, you want to create a service that can act as an helper out of the angular's DI process.

Like @Günter_Zöchbauer said, an Injectable can't be used outward of an instance of an Ng2 object (Component, Injectable...) but in your case, create an injectable is irrelevant. Create an angular app doesn't mean that all your files must contain angular objects, you can also create basic classes/constants..

For example, if you want an helper that build an url for you, you can create a class and use it in a component declaration simply by importing it.

//urlbuilder.ts
const host:string = 'http://foo.bar.com';
export class UrlBuilder {
    static generate(file:string = '') {
        return host + file;
    }
}

// component.ts
import {UrlBuilder} from './urlbuilder';

@Component({
    templateUrl: UrlBuilder.generate('/foo.html')
})
export class FooComponent {}

You can even export a function instead of the class, it will work too. The following code show the same code as above but with a function and an es6 tag.

//urlbuilder.ts
const host:string = 'http://foo.bar.com';
export const UrlBuilder = urlBuilderFn;

//basic tag function that build a template string with potential variables
function urlBuilderFn(strs, ...raws) {
    let builtStr = '', length = strs.length;

    for(let i = 0; i < length; i++)
        builtStr = strs[i] + (raws[i] !== undefined && raws[i] !== null ? raws[i] : '');

    return host + builtStr;
}


// component.ts
import {UrlBuilder as url} from './urlbuilder';

@Component({
    templateUrl: url`/foo.html`
})
export class FooComponent {}

However, if wanna use your helper with the DI too (for whatever reasons, need for angular deps..) you can make an injectable class with a static method.

//urlbuilder.ts
const host:string = 'http://foo.bar.com';

@Injectable()
export class UrlBuilder {

    constructor(private http:Http) {}

    static generate(file:string = '') {
        return host + file;
    }

    doSomething() {
        return this.http.get(UrlBuilder.generate('/foo/bar'))
    }
}

// component.ts
import {UrlBuilder} from './urlbuilder';

@Component({
    templateUrl: UrlBuilder.generate('/foo.html')
})
export class FooComponent {

    constructor(private builder:UrlBuilder) {}

    ngOnInit() {
        this.builder.doSomething()
    }

}

On the other hand, if your only issues are with the templates why don't you write them directly as template string or just import them with your task manager (webpack..). Generally, if you don't have dynamic view and so, have to generete them from your server, prefer to avoid http calls to retrieve them and load them directly in the javascript files.

Comments