Reputation: 16837
For some reason authenticationProvider
seems to be missing.
@autoinject()
export class ProviderManager implements AuthenticationManager {
constructor( private container: Container ){
}
public authenticate( creds: Credentials ): Promise<Authentication> {
var provider = creds.authenticationProvider();
return this.container.get( provider ).authenticate( creds );
}
}
Credentials
export interface Credentials {
authenticationProvider(): { new(): AuthenticationManager };
}
the implementation UsernamePasswordCredentials
export class UsernamePasswordCredentials implements Credentials {
public authenticationProvider(): {new(): AuthenticationManager} {
return HttpBasicAuthentication;
}
user: String;
pass: String;
}
AuthenticationManager
export interface AuthenticationManager {
authenticate( creds: Credentials ): Promise<Authentication>;
}
Login
@autoinject()
export class Login {
private log: Logger = LogManager.getLogger( Login );
creds: UsernamePasswordCredentials;
constructor( private am: AuthenticationManager, private router: Router ) {
}
public signIn(): void {
this.log.debug( `authenticating ${ this.creds.user }` );
this.am.authenticate( this.creds ).then( auth => {
var route = Route.MANAGE_CONTENT;
this.log.debug( `navigating to ${ route }` );
var router = this.router;
router.navigate( route );
} ).catch( error => {
this.log.error( error );
} );
}
}
Here's Chrome's stacktrace
VM802:1 Uncaught TypeError: creds.authenticationProvider is not a function(…)(anonymous function) @ VM802:1
authenticate @ ProviderManager.ts:13
signIn @ login.ts:22evaluate @ aurelia-binding.js:1522
callSource @ aurelia-binding.js:4963
(anonymous function) @ aurelia-binding.js:4987
handleDelegatedEvent @ aurelia-binding.js:3176
Upvotes: 1
Views: 546
Reputation: 1444
Thanks for sharing the Login
code.
You're on the right lines, but it appears that this.creds
was previously undefined.
The code
class Login {
creds: UsernamePasswordCredentials;
}
just tells Typescript that it expect creds to be of type UsernamePasswordCredentials
. But it does nothing to initialize the creds field... in particular, no javascript will get emitted for the line when the above gets transpiled (https://www.typescriptlang.org/play/ might be helpful to look at what the transpiler does).
That means that, in the signIn
method, this.creds
will be undefined.
This is similar to, say, in C#, where if you don't initialize a field, it defaults to null
.
Whilst Typescript can catch a lot of things, it cannot (always) catch when a variable has an undefined/null value at run-time, just as a statically typed language like C# can still end up generating compiled code which triggers null reference exceptions.
EDIT: Ahh, my apologies. Had creds
been undefined, you would have received a ReferenceError: creds is not defined
. The TypeError
should have made clear creds
was populated elsewhere, but of the wrong type.
Upvotes: 1