Add new JS class and template to aurelia project - javascript

I am new to Aurelia, but am working on an existing project and learning as I go.
I want to add a javascript class file and have NPM include it in the build, but I cannot find clear documentation on how to do that.
It is not a complex class and does not require an html template.

Just add the .js file containing your class to your src folder and add the following to import it in the file you intend to use the class.
import * as MyClass from './my-classs';

following the convention, you can create a class with the below...
export class MyClass {
myProperty = 'foo';
myOtherProperty = { key:'value' };
constructor() {
// constructor stuff (optional of course)
}
myMethod() {
// do something
}
}
Then in your ViewModel, for example...
import { inject } from 'aurelia-framework';
import { MyClass } from 'path/to/my-class';
#inject(MyClass)
export class MyViewModel {
constructor(myClass){
this.myClass = myClass;
}
attached() {
console.log(this.myClass.myProperty);
this.myClass.myMethod();
}
}
The way you import your class does depend on whether it's written as a module or not. If it's not a module, you'll have to write it out as #john-little mentioned.
The MyClass will automatically be a singleton until you make it transient (see https://aurelia.io/docs/fundamentals/dependency-injection#object-lifetime-child-containers-and-default-behavior)

Related

EmberJS: Injecting owner to native class from component

The thing i'm trying to do, is to inject owner to my JS native class in Ember(3.15.0).
It looks something like this:
component.ts
export default class ClassOne extends Component {
constructor() {
super(...arguments);
const myClass = new ClassTwo();
...
}
}
ClassTwo.ts
export default class ClassTwo {
#service() someService: ServiceType;
...
}
Because of that, on someService, i'm getting expectable Attempting to lookup an injected property on an object without a container, ensure that the object was instantiated via a container
I've seen similar questions that were solved by using getOwner(this).ownerInjection() but those were all based on Class.create() that was extended by Ember.Object.
Is there any way to do that?
Thanks in advance for any help.
The way to do this in modern Ember is to use setOwner.
import { setOwner } from '#ember/application';
import { inject as service } from '#ember/service';
export default class MyClass {
#service myService;
constructor(owner) {
setOwner(this, owner);
this.appName = this.myService.appName;
}
}
See it working here: https://ember-twiddle.com/e6481c33c3150e3418606e79decaed78?openFiles=classes.my-class%5C.js%2C
See documentation for setOwner here:
https://api.emberjs.com/ember/3.22/functions/#ember%2Fapplication/setOwner
This answer should work in Ember 3.15+ and is current as of Ember 3.23.
By the way, that error message could really use an update from container -> owner

Javascript import of Typescript - exporting default object

This may have been answered somehow already, but wasn't sure how to ask it.
I have a Typescript file that exports a single class:
export class MyClass {
...
}
I have a Javascript file that imports the transpiled version of that typescript and uses it:
define('random-source', ['src/my-class'], function(MyClassMod) {
...
var myClass = new MyClassMod.MyClass();
...
});
My question is this: Is there a way to write the Typescript file so that the only object exported is that 'MyClass' definition? As you see from the define in the Javascript, it's imported as a module name, but I have to say '.MyClass' to access it. When I have a lot of Typescript files with a single class defined like this, it makes the Javascript code a bit messy. Ideally I'd like something like:
define('random-source', ['src/my-class'], function(MyClass) {
...
var myClass = new MyClass();
...
});
Is that possible? Thanks in advance!
Actually you are looking for an export assignment, which will make MyClass the value of the entire module:
class MyClass {
// ...
}
export = MyClass;
Seems like you are looking for a default export:
export default class MyClass {
...
}

Import namespace so prefix is not used

I have a library that is in a name space, somewhat like this:
namespace MyLib {
export class MyClass {}
}
I then have another class that is not in the namespace that looks like this:
class Test extends MyLib.MyClass {}
Is there a way for me to access MyClass without having to prefix the namespace? Maybe something like this:
import MyLib;
class Test extends MyClass {}
Edit
I found out that I can do this:
import MyClass = MyLib.MyClass;
Which is okay, but based on that is there anyway for me to import all classes in the namespaces?
The namespacing convention is a C#-ism that doesn't translate very well to JavaScript. My suggestion would be to stop using it altogether because it'll cause more headaches than solve actual problems.
Instead, you should treat your modules themselves as namespace "things". You could do this:
// MyLib.ts
class MyClassA {}
class MyClassB {}
export {
MyClassA,
MyClassB,
};
// Your code
import { MyClassA, MyClassB } from "./MyLib.ts";
Or in separate files:
// MyClassA.ts
export class MyClassA {}
// MyClassB.ts
export class MyClassB {}
// MyLib.ts
import MyClassA from "./MyClassA";
import MyClassB from "./MyClassB";
export {
MyClassA,
MyClassB,
};
// Your code
import { MyClassA, MyClassB } from "./MyLib.ts";
You can't "import all names" though, not in the way you'd need in C# where things are just magically scoped. They need to be declared somehow. On your example code, there's no way to tell that Test comes from MyLib - indeed, even though you could make it work (through global variables, e.g. window.Test = Test), TypeScript wouldn't be happy about it as it wouldn't be able to find a definition for Test, you'd need to declare var it somewhere.

Typescript, require module as class

I'm using an existing js library that uses AMD modules in my typescript code. I want to use a Javascript class as the base for my Typescript class. This is what I'm trying to do:
famous.js
define('famous/core/View',['require','exports','module'],function(require, exports, module) {
function View() {
...
}
...
module.exports = View;
});
View.d.ts
declare module "famous/core/View" {
}
AppView.ts
import View = require('famous/core/View');
class AppView extends View {
}
export = AppView;
But it says "Cannot find name 'View'". I suppose it's logical it doesn't work since a module is not a class, but I don't know another way.
You need to define a class and use export = in View.d.ts. For example:
declare module "famous/core/View" {
class View {
// TODO define members of View
}
export = View;
}
On further analysis it seems like purely a require configuration problem. It shouldn't have anything to do with class vs module. Are you sure your paths are correct and you have a config.ts require configuration file?

Import object in class using TypeScript

I am new to Javascript and TypeScript and I am wondering if it is possible to do some kind of dependency injection (maybe using require.js)
I have two classes in same module
module MyWebApp {
export class ViewRouter {
... some class methods
}
}
module MyWebApp {
export class MyViewModel{
private router: ViewRouter;
constructor(router:ViewRouter router) {
this.router = router;
}
}
}
Every time I need MyViewModel I have to instantiate ViewRouter
var vm = new MyViewModel(new ViewRouter());
Is there any way around this? I thought that Require.js could help me solve my problem but I don't know how to use it with TypeScript.
Thank you.
If you want a new instance every time you should probably do:
class MyViewModel{
private router: ViewRouter;
constructor() {
this.router = new ViewRouter();
}
}
Now if you want a "single" shared instance you can do:
module MyWebApp {
export class ViewRouter {
... some class methods
}
export var router = new ViewRouter();
}
and use router
Using RequireJS can do the same thing for your, but the principal idea will not change there. RequireJS is not an IOC container.
There are bunch of javascript IOC containers out there and I don't have a recommendation on that : Google search

Categories