modelEvents() not getting called - backbone.js

Using MarionetteJS, for some reason modelEvents() is not getting called:
export class MyView extends Marionette.ItemView<MyModel> {
constructor(public model: MyModel) {
super();
}
public events(): Backbone.EventsHash {
// This gets called by the framework
const events: Backbone.EventsHash = {};
return events;
}
public modelEvents() {
// This does not
return {};
}
}
I'm using TypeScript, and the model is passed into the constructor with a dependency injection framework (aurelia-dependency-injection).

You forgot to pass a model to the super constructor, so your model is being lost. Try:
constructor(public model: MyModel) {
super(model);
}

Related

Cannot access public method in type Typescript class

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() {}
}

How to use this.$scope.$on in typescript,AngularJS1.7

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

Angular 2 TS object array only defined while subscribed to service

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();
});
}

How to use angular's $resource with TypeScript and d.ts

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!

How can I define an AngularJS service using a TypeScript class that doesn't pollute the global scope?

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..

Resources