I have a need to run the JavaScript portion of one of my plugins on the server side. Ultimately it will be a .net core app executing a nodejs app that consumes my plugin.
I just have a simple wrapper in place where I’m trying to get dependency injection working. If I eliminate the injection of BindingEngine in the plugin my nodejs wrapper will inject the rest of the dependencies with no issues. I looked at the aurelia-validation plugin for assistance at configuring, but it was no help.
I know binding engine is for sure an issue, will event aggregator be as well. I know it actually got injected when I run without binding engine.
My wrapper class on the nodejs side looks like this
import { initialize } from "aurelia-pal-nodejs";
import "aurelia-polyfills";
import { Container, autoinject } from "aurelia-dependency-injection";
import { ControlFactory } from "custom-controls";
import { configure as configureBindingLanguage } from "aurelia-templating-binding";
import { configure as configureValidation } from "aurelia-validation";
@autoinject
export class ControlFactoryWrapper {
constructor(
private customControlFactory: ControlFactory,
private container: Container
) {
initialize();
configureBindingLanguage({ container });
configureValidation({ container });
}
procesJson() {
console.log("cfw class", this.customControlFactory);
return this.customControlFactory;
}
}
The console output
C:\source\node_apps\hello_world\node_modules\aurelia-dependency-injection\dist\commonjs\aurelia-dependency-injection.js:549
throw new aureliaPal.AggregateError("Error invoking " + fn.name + ". Check the inner error for details.", e, true);
^
Error: Error invoking SVGAnalyzer. Check the inner error for details.
------------------------------------------------
Inner Error:
Message: _aureliaPal.DOM.createElement is not a function
Inner Error Stack:
TypeError: _aureliaPal.DOM.createElement is not a function
at createElement (C:\source\node_apps\hello_world\node_modules\custom-controls\node_modules\aurelia-binding\dist\commonjs\aurelia-binding.js:4722:31)
at new SVGAnalyzer (C:\source\node_apps\hello_world\node_modules\custom-controls\node_modules\aurelia-binding\dist\commonjs\aurelia-binding.js:4731:11)
at Object.invoke (C:\source\node_apps\hello_world\node_modules\aurelia-dependency-injection\dist\commonjs\aurelia-dependency-injection.js:387:24)
at InvocationHandler.invoke (C:\source\node_apps\hello_world\node_modules\aurelia-dependency-injection\dist\commonjs\aurelia-dependency-injection.js:360:28)
at Container.invoke (C:\source\node_apps\hello_world\node_modules\aurelia-dependency-injection\dist\commonjs\aurelia-dependency-injection.js:546:28)
at StrategyResolver.get (C:\source\node_apps\hello_world\node_modules\aurelia-dependency-injection\dist\commonjs\aurelia-dependency-injection.js:104:39)
at Container.get (C:\source\node_apps\hello_world\node_modules\aurelia-dependency-injection\dist\commonjs\aurelia-dependency-injection.js:493:47)
at C:\source\node_apps\hello_world\node_modules\aurelia-dependency-injection\dist\commonjs\aurelia-dependency-injection.js:386:68
at Array.map (<anonymous>)
at Object.invoke (C:\source\node_apps\hello_world\node_modules\aurelia-dependency-injection\dist\commonjs\aurelia-dependency-injection.js:386:30)
End Inner Error Stack
------------------------------------------------
at new AggregateError (C:\source\node_apps\hello_world\node_modules\e[4maurelia-pale[24m\dist\commonjs\aurelia-pal.js:37:11)
at Container.invoke (C:\source\node_apps\hello_world\node_modules\e[4maurelia-dependency-injectione[24m\dist\commonjs\aurelia-dependency-injection.js:549:19)
at StrategyResolver.get (C:\source\node_apps\hello_world\node_modules\e[4maurelia-dependency-injectione[24m\dist\commonjs\aurelia-dependency-injection.js:104:39)
at Container.get (C:\source\node_apps\hello_world\node_modules\e[4maurelia-dependency-injectione[24m\dist\commonjs\aurelia-dependency-injection.js:493:47)
at C:\source\node_apps\hello_world\node_modules\e[4maurelia-dependency-injectione[24m\dist\commonjs\aurelia-dependency-injection.js:386:68
at Array.map (<anonymous>)
at Object.invoke (C:\source\node_apps\hello_world\node_modules\e[4maurelia-dependency-injectione[24m\dist\commonjs\aurelia-dependency-injection.js:386:30)
at InvocationHandler.invoke (C:\source\node_apps\hello_world\node_modules\e[4maurelia-dependency-injectione[24m\dist\commonjs\aurelia-dependency-injection.js:360:28)
at Container.invoke (C:\source\node_apps\hello_world\node_modules\e[4maurelia-dependency-injectione[24m\dist\commonjs\aurelia-dependency-injection.js:546:28)
at StrategyResolver.get (C:\source\node_apps\hello_world\node_modules\e[4maurelia-dependency-injectione[24m\dist\commonjs\aurelia-dependency-injection.js:104:39) {
innerError: TypeError: _aureliaPal.DOM.createElement is not a function
at createElement (C:\source\node_apps\hello_world\node_modules\e[4mcustom-controlse[24m\node_modules\e[4maurelia-bindinge[24m\dist\commonjs\aurelia-binding.js:4722:31)
at new SVGAnalyzer (C:\source\node_apps\hello_world\node_modules\e[4mcustom-controlse[24m\node_modules\e[4maurelia-bindinge[24m\dist\commonjs\aurelia-binding.js:4731:11)
at Object.invoke (C:\source\node_apps\hello_world\node_modules\e[4maurelia-dependency-injectione[24m\dist\commonjs\aurelia-dependency-injection.js:387:24)
at InvocationHandler.invoke (C:\source\node_apps\hello_world\node_modules\e[4maurelia-dependency-injectione[24m\dist\commonjs\aurelia-dependency-injection.js:360:28)
at Container.invoke (C:\source\node_apps\hello_world\node_modules\e[4maurelia-dependency-injectione[24m\dist\commonjs\aurelia-dependency-injection.js:546:28)
at StrategyResolver.get (C:\source\node_apps\hello_world\node_modules\e[4maurelia-dependency-injectione[24m\dist\commonjs\aurelia-dependency-injection.js:104:39)
at Container.get (C:\source\node_apps\hello_world\node_modules\e[4maurelia-dependency-injectione[24m\dist\commonjs\aurelia-dependency-injection.js:493:47)
at C:\source\node_apps\hello_world\node_modules\e[4maurelia-dependency-injectione[24m\dist\commonjs\aurelia-dependency-injection.js:386:68
at Array.map (<anonymous>)
at Object.invoke (C:\source\node_apps\hello_world\node_modules\e[4maurelia-dependency-injectione[24m\dist\commonjs\aurelia-dependency-injection.js:386:30)
}
I have to head to work, but that portion works. Thanks
the controlfactory wrapper is the simple entry point into the aurelia end. ControlFactory is where the complexity is and that has BindingEngine as one of the construction depenedencies. As I said above. I can load my ControlFactory as long as I don’t inject BindingEngine. Unfortunately I rely heavily on binding engine
Thanks, I’ll modify your sandbox later to reflect my application more closely. I’m not running in a web server, but I doubt that has anything to do with it. I’ll make a shell of my controlFactory class with just the dependencies (they are mostly aurelia modules)
I didn’t commit/push the work I was doing this morning, but I know my controlfactory class takes in
EventAggregator, TaskQueue, ValidationControllerFactory, BindingEngine, and one of my own classes which has no dependencies of its own and no constructor so nothing should be strange. Binding Engine seems to be the only issue just due to trial and error of removing the dep and running
I struggled to make progress on making it NOT work with your sample so I created a sample project where it’s broke. BindingEngine is the problem on the wrapper class. If I can’t get this to work with as a nodejs run, I’m going to have to rebuild what I’m trying to wrap without bindingEngine.
just compile the typescript and run: node scripts/app.js
You are injecting binding engine too early, before initializing the platform abstraction code. So if you move initialize call out of the constructor, it will work
I’m still having issues with my actual class. I’m getting
Reflect.defineMetadata(metadataKey, metadataValue, target, targetKey);
^
TypeError: Reflect.defineMetadata is not a function
at Object.define (C:\source\node_apps\hello_world\node_modules\e[4mcustom-controlse[24m\node_modules\e[4maurelia-metadatae[24m\dist\commonjs\aurelia-metadata.js:44:13)
at C:\source\node_apps\hello_world\node_modules\e[4mcustom-controlse[24m\node_modules\e[4maurelia-bindinge[24m\dist\commonjs\aurelia-binding.js:5231:33
at __decorate (C:\source\node_apps\hello_world\node_modules\e[4mcustom-controlse[24m\node_modules\e[4maurelia-validatione[24m\dist\commonjs\aurelia-validation.js:150:95)
at C:\source\node_apps\hello_world\node_modules\e[4mcustom-controlse[24m\node_modules\e[4maurelia-validatione[24m\dist\commonjs\aurelia-validation.js:748:31
at Object.<anonymous> (C:\source\node_apps\hello_world\node_modules\e[4mcustom-controlse[24m\node_modules\e[4maurelia-validatione[24m\dist\commonjs\aurelia-validation.js:752:2)
e[90m at Module._compile (internal/modules/cjs/loader.js:955:30)e[39m
e[90m at Object.Module._extensions..js (internal/modules/cjs/loader.js:991:10)e[39m
e[90m at Module.load (internal/modules/cjs/loader.js:811:32)e[39m
e[90m at Function.Module._load (internal/modules/cjs/loader.js:723:14)e[39m
e[90m at Module.require (internal/modules/cjs/loader.js:848:19)e[39m
I’ll try that later today. Thanks for all the help. Sadly what I’m trying to do with NodeJs has been deprecated by Microsoft but as long as the package is still available I see no reason not to use it. I have a lot of custom logic that builds forms built by 3rd parties. I don’t want to maintain a .net version and an aurelia version. Right now we are relying on client side work only, but having this run on the server would be very useful. Worst case scenario I’d have to write my own wrapper class around a node call
I’m still having issues. What I’m currently doing in my spare time is starting version 2 of this project that I’m trying to consume. I’ll create the skeleton that causes my issue . I"m fairly close to having that, but I don’t get much free time.
It’s been a little while since I worked on this. Practically a year ago. I’m finally revisiting this and I made progress but I’m now getting an error due to the way I’m trying to share code between the web and the server. I’m getting the friendly message ’ Did you forget to add “.plugin(‘aurelia-validation’)” to your main.js?’ How can I make that work in a node project? My code is actually running correctly up to this point if I pass in something that does not require validation.
(node:18088) UnhandledPromiseRejectionWarning: Error: Did you forget to add ".plugin('aurelia-validation')" to your main.js?
at FluentEnsure.assertInitialized (C:\source\control_set\node_modules\aurelia-validation\dist\commonjs\aurelia-validation.js:1779:15)
at FluentEnsure.ensure (C:\source\control_set\node_modules\aurelia-validation\dist\commonjs\aurelia-validation.js:1744:14)
at Function.ValidationRules.ensure (C:\source\control_set\node_modules\aurelia-validation\dist\commonjs\aurelia-validation.js:1812:58)
My rules are defined as such
ValidationRules.ensure((c: StringControlConfiguration) => c.value)
.required()
.when(() => control.validation.required && control.canValidate)
.withMessage(`${control.label || control.placeholder} is required`)
.satisfies((value: string) => {
return value !== null ? value.indexOf(control.promptChar) === -1 : true;
})
.when(() => control.mask !== null && control.promptChar !== null && control.canValidate)
.withMessage(`${control.label || control.placeholder} does not meet the format: ${control.mask}`)
.matches(control.validation.regEx)
.when(() => control.validation.regEx !== null && control.canValidate)
.withMessage(`${control.label || control.placeholder} is invalid (${control.validation.regEx})`)
.satisfies(control.isValidRegEx)
.when(() => control.inputType === 'regularExpression' && control.canValidate)
.withMessage(`${control.label || control.placeholder} is not a valid regular expression`)
.maxLength(control.validation.maxLength)
.when(() => control.validation.maxLength !== null && control.canValidate)
.withMessage(
`${control.label || control.placeholder} must be less than ${
control.validation.maxLength
} characters`
)
.minLength(control.validation.minLength)
.when(() => control.validation.minLength !== null && control.canValidate)
.withMessage(
`${control.label || control.placeholder} must be greater than ${
control.validation.minLength
} characters`
).satisfies((value: string) => {
return value !==null ? !control.validation.restrictedValues.some((x) => x.toLowerCase() === value.toLowerCase()): true
})
.when(() => control.validation.restrictedValues !== null)
.withMessage(`${control.label || control.placeholder || "Input"} cannot contain the current value`)
.on(control);
I may have solved the problem but I need to further test to make sure nothing weird is happening. If I pass the ValidationRules class to my existing code and set that as a property instead of relying on it being static, things seem to be working.