10

I am attempting to import a variable from one type script file into another.

the variable I want to import is cityListUrl

the type script file it is in is coded like this:

export class backendUrls{

  // root url
  rooturl:string= 'http://127.0.0.1:8000';

//get a list of all cities
  cityListUrl:string = this.rooturl + '/api/city/';


}

the file I want to import it into looks like this:

import {Injectable} from '@angular/core';
import {Http} from '@angular/http';
import {backendUrls} from 'app/backendUrls';

@Injectable()
export class cityGetService{
  constructor(private http: Http){}

  cityGet(){
    this.http.get(backendUrls.cityListUrl)
  }
}

the cityListUrl in my pycharm editor is currently red. with the message

TS2339: 'cityListUrl' does not exist on type 'typeof backendUrls'.

has anyone had this issue before? How would I fix this? Thank you

2 Answers 2

3

The best way to handle server api urls is to use the angular environment files. There are two main advantages of its usage:

  • It's available in all your application
  • You can handle multiples platform (localhost, dev, stating, prod) without modifing your code

in app/environments you can create differents files, like:

  • environments.prod.ts
  • environments.ts
  • environement.test.ts

In each file you define your global variables:

For localhost change your code into:

export const environment = {
  production: false,
  apiHost: 'http://localhost',
  recaptchaKey: '6LeWzxQUeazeAAPpR0gZFezaeazL5AvUP3moN1U4u',
  fileHost: 'http://file.localhost',
};

For prod example, do instead:

export const environment = {
  production: true,
  apiHost: 'http://prod',
  recaptchaKey: '6LeWzxQUeazeAAPpR0gZFezaeazL5AvUP3moN1U4u',
  fileHost: 'http://file.prod',
};

To use it in your scripts you only need to import:

import { environment } from './environments/environment' //relative path from where your file is
export class Service {
    protected cityListUrl = '/api/city/';

    constructor(protected http: Http) { }

    get() {
      this.http.get(environment.apiHost + this.cityListUrl).map(response => response.json());
    }
}

When you build your project with angular-cli, you have to specify which environment you want to use. For example, you can execute either

ng build --environment=prod

or

ng serve --environment=test

Which it is cool because you can easily integrate this command line in a continuous integration tool.

Sign up to request clarification or add additional context in comments.

Comments

2

The easiest way would be to just define and export each variable independently. This way you can also import them independently as well.

export const rooturl = 'http://127.0.0.1:8000';
export const cityListUrl = rooturl + '/api/city/'

And import them this way.

import {Injectable} from '@angular/core';
import {Http} from '@angular/http';
import {cityListUrl} from 'app/backendUrls';

@Injectable()
export class cityGetService{
  constructor(private http: Http){}

  cityGet(){
    this.http.get(cityListUrl)
  }
}

If you need them all together in an object just export them like that as well.

export const rooturl = 'http://127.0.0.1:8000';
export const cityListUrl = rooturl + '/api/city/'

export const all = {
    rooturl, cityListUrl
}

The way you have it now it's a class, that must be instantiated in order to get access to it's instance properties.

The generated code for your class looks like this.

define(["require", "exports"], function (require, exports) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    var backendUrls = (function () {
        function backendUrls() {
            // root url
            this.rooturl = 'http://127.0.0.1:8000';
            //get a list of all cities
            this.cityListUrl = this.rooturl + '/api/city/';
        }
        return backendUrls;
    }());
    exports.backendUrls = backendUrls;
});

If you need a class you will first have to make an instance of it using the new keyword.

import {Injectable} from '@angular/core';
import {Http} from '@angular/http';
import {backendUrls} from 'app/backendUrls';

@Injectable()
export class cityGetService{
  constructor(private http: Http){}

  cityGet(){
    this.http.get(new backendUrls().cityListUrl)
  }
}

If you need to use a class but want to have this in a static manner you can make the properties static then they'll get defined as properties on the class itself instead of an instance.

export class backendUrls {
    // root url
    static rooturl: string = 'http://127.0.0.1:8000';

    // need to use the class to access the root since we don't have an instance.
    static cityListUrl: string = backendUrls.rooturl + '/api/city/';

}

8 Comments

interestingly the ; at the end of each variable is now red with the warning expected , whats going on with that?
well i have no more errors in the cityGetService.ts file which means your solution worked thank you. Its the silly ; , issue I commented above. I am thinking its just pycharm complaining for no reason. I'll accept your answer and thank you oh your updating yay thank you
actually the first solution doesn't really work, since this.rootUrl is not defined because does not point to backendUrl. and cityurl will end up as "undefined/api/city/"
darn ok walk me through sensei
does this mean I can get rid of the export const backendUrls? That the only thing I need to have in this file are the two variables with the exports on them?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.