I've inherited a typescript react project and I'm unfamiliar with some of the concepts of TS. There is a class being exported like:
export class SomeGateway {
constructor(private url: string){}
public someMethod() {}
}
but whenever i do
const whatever = new SomeGateway('www.google.com');
and try to access whatever.someMethod() it says it doesn't exist, I can see whatever.url though. What's the proper way to access someMethod?
bind the method
export class SomeGateway {
constructor(private url: string){
this.someMethod = thi.someMethod.bind(this);
}
public someMethod() {}
}
I want to capture the emit event from one component into other component
export class modifyController implements angular.IComponentController {
static $inject = ['$scope','$state'];
constructor(public $scope:ng.IScope,public $state: ng.ui.IStateService) {
this.sendMessage();
};
public sendMessage(): void {
let tempObj = { 'title': 'name', 'id': '1234' }
this.$scope.$emit('modify',tempObj);
}
}
In Other component's controller
constructor(public $scope:ng.IScope) {
//need to write this outside constructor
this.$scope.$on('modify', (event: ng.IAngularEvent, data: any) => {
console.log('from ON event...',data);
});
}
In angularjs1.4 i can directly use $scope.$on() like any other function , but while using this in same way in angularjs1.7 with typescript, i am getting error -[ts] Unexpected token. A constructor, method, accessor, or property was expected.
How to use this.$scope.$on in typescript,AngularJS1.7?
Thanks
I'm in the process of learning Angular 2 using TypeScript. So far I've written a little API service that uses HTTP get method to feed me json data using observables. Everything is working fine, I can use the data in my view, I can also use the data in my component, but only while I'm subscribed to the getData() method.
Why is that and what other possibilities do I have to make the object array available to all methods in my component for easy iteration and management?
Example component:
export class SomeComponent implements OnInit {
public someData: DataObject[];
public constructor(private service: SomeService) {}
public ngOnInit(): void {
this.loadData();
this.useData();
}
private loadData(): void {
this.service.getData().subscribe(data=> {
this.someData = data;
this.someData.forEach(dataObject => {
// this works fine
});
});
}
private useData(): void {
this.someData.forEach(dataObject => {
// dataObject is (of type?) undefined, why?
});
}
}
It's because http calls are async. Your this.useData(); does not wait this.loadData(); to finish. This should work:
private loadData(): void {
this.service.getData().subscribe(data=> {
this.someData = data;
this.useData();
});
}
With this TypeScript (based on some online course):
interface IProduct {
productName: string
}
interface IProductResource extends ng.resource.IResource<IProduct> {
}
interface IDataAccessService {
getProductService(): ng.resource.IResourceClass<IProductResource>
}
class DataAccessService implements IDataAccessService {
static $inject = ['$resource'];
constructor(private $resource:ng.resource.IResourceService) {
}
getProductService():ng.resource.IResourceClass<IProductResource> {
return this.$resource("sampleUrl");
}
}
angular.module('app').service('dataAccessService', DataAccessService);
I have a code that uses dataAccessService:
var obj : IProductResource = dataAccessService.getProductService().get();
obj has all angular's REST helper methods like $save/$delete, but I don't have access to interface obj.productName. What is wrong with this code?
I think I got it. It should be:
interface IProductResource
extends ng.resource.IResource<IProduct>, IProduct {
}
Any comments on that?
Thanks!
I am using AngularJS and TypeScript. I want to implement an AngularJS service using a Typescript class, like this:
class HelloService {
public getWelcomeMessage():String {
return "Hello";
}
}
angular.module('app.services.helloService', []).factory('helloService', () => {
return new HelloService();
});
This compiles to the following javascript code:
var HelloService = (function () {
function HelloService() {
}
HelloService.prototype.getWelcomeMessage = function () {
return "Hello";
};
return HelloService;
})();
angular.module('app.services.helloService', []).factory('helloService', function () {
return new HelloService();
});
This pollutes the global namespace with the variable HelloService, which I obviously don't want. (Using Chrome's console I verified that HelloService was an object.) How can I solve/avoid this problem?
I tried the obvious:
angular.module('app.services.helloService', []).factory('helloService', function () {
class HelloService { ...}
return new HelloService();
});
but that gives me a compile error ("Unexpected token; 'statement' expected.").
One possible solution I can think of is using TypeScript's import and export somehow, which in turn will use RequireJS. This probably will wrap the HelloService within a define function, thus avoiding pollution of the global scope with HelloService. However, I don't want to use RequireJS in my AngularJS application for now, as I think AngularJS is good enough for my use, and it adds complexity.
So, my question is, how can I define an AngularJS service using a TypeScript class that doesn't pollute the global scope?
2016-05-06: New example using ES6-style modules
The static $inject array and constructor remain unchanged from the previous example.
The only change is to split the classes into multiple files and use ES6 modules to pull in the class definitions.
/lib/HelloService.ts:
export class HelloService {
public getWelcomeMessage():String {
return "Hello from HelloService";
}
}
/lib/AnotherService.ts:
import {HelloService} from './HelloService';
/**
* Service that depends on HelloService.
*/
export class AnotherService {
// Define `HelloService` as a dependency.
static $inject = ['HelloService'];
constructor(
// Add the parameter and type definition.
public HelloService: HelloService
){}
public getWelcomeMessage():String {
// Access the service as: `this.HelloService`
// Enjoy auto-completion and type safety :)
var helloMsg = this.HelloService.getWelcomeMessage();
return "Welcome from AnotherService, " + helloMsg;
}
}
/index.ts:
// Using the services.
import {HelloService} from './lib/HelloService';
import {AnotherService} from './lib/AnotherService';
angular.module('HelloApp', [])
.service('HelloService', HelloService)
.service('AnotherService', AnotherService)
.run(['AnotherService', function(AnotherService: AnotherService){
console.log(AnotherService.getWelcomeMessage());
}]);
Previous answer: using namespaces
Building from Steve Fenton's answer:
To allow dependency injection, add a static $inject array on your class.
See the Angular $injector documentation on how the $inject array works.
The dependencies will be injected into your constructor in the order given by the array (and makes it work with minification).
Dependency Injection Example:
namespace MyModule {
/**
* Angular Service
*/
export class HelloService {
public getWelcomeMessage():String {
return "Hello from HelloService";
}
}
/**
* Service that depends on HelloService.
*/
export class AnotherService {
// Define `HelloService` as a dependency.
static $inject = ['HelloService'];
constructor(
// Add the parameter and type definition.
public HelloService: MyModule.HelloService
){}
public getWelcomeMessage():String {
// Access the service as: `this.HelloService`
// Enjoy auto-completion and type safety :)
var helloMsg = this.HelloService.getWelcomeMessage();
return "Welcome from AnotherService, " + helloMsg;
}
}
}
// Using the services.
angular.module('app.services.helloService', [])
.service('HelloService', MyModule.HelloService)
.service('AnotherService', MyModule.AnotherService)
.run(['AnotherService', function(AnotherService: MyModule.AnotherService){
console.log(AnotherService.getWelcomeMessage());
}]);
I should provide what I actually ended doing:
module MyModule {
export class HelloService {
public getWelcomeMessage():String {
return "Hello";
}
}
angular.module('app.services.helloService', []).factory('helloService', () => {
return new HelloService();
});
}
In this way I can use
return new HelloService();
instead of
return new MyModule.HelloService();
I have two solutions, the first gives you class-based syntax, the second leaves absolutely nothing in the global scope...
You could compromise slightly by only adding a single handle to the global scope (this really applies if you have multiple classes that you want to avoid placing in the global scope as currently you only have one class).
The following code leaves only the module in the global scope.
module MyModule {
export class HelloService {
public getWelcomeMessage():String {
return "Hello";
}
}
export class AnotherService {
public getWelcomeMessage():String {
return "Hello";
}
}
}
angular.module('app.services.helloService', []).factory('helloService', () => {
return new MyModule.HelloService();
});
angular.module('app.services.anotherService', []).factory('anotherService', () => {
return new MyModule.AnotherService();
});
Alternatively, to leave not a single thing in global scope, you could avoid the class syntax and use "plain old JavaScript":
angular.module('app.services.helloService', []).factory('helloService', () => {
var HelloService = (function () {
function HelloService() {
}
HelloService.prototype.getWelcomeMessage = function () {
return "Hello";
};
return HelloService;
})();
return new HelloService();
});
This is the method that I'm following:
module HelperServices {
export class helloService {
sayHelloWorld: () => string;
constructor() {
this.sayHelloWorld = () => {
return "Hello World";
}
}
}
}
As simple as that..