0

Apologies for not really knowing how to phrase this question. The crux is that on redirect back to the app, the redirect handler needs to have access to the injected UserManager.

import { autoinject } from "aurelia-framework";
import { UserManager } from "oidc-client";
import { OpenIdConnectRouting } from "./open-id-connect-routing"; 

@autoinject
export class OpenIdConnect {

    constructor(
        private routerConfigurationService: OpenIdConnectRouting,
        public UserManager: UserManager) { }

    public Configure(routerConfiguration: RouterConfiguration) {

        this.routerConfigurationService.ConfigureRouter(
            routerConfiguration,
            this.PostLogoutRedirectHandler);
    }

    public PostLogoutRedirectHandler = (): Promise<any> => {
        return this.UserManager.signoutRedirectCallback(null);
    }
}

The above code passes the PostLogoutRedirectHandler to a routing service, so that, when the user returns from the authorization server, the handler will fire.

The above code works, but the handler is lamda only to capture the current object in this. When the handler is instead a function, this is not what we expect it to be and we lack access to the injected UserManager object.

Why does the above code work with a lambda but not with a function? Is using a lambda a reasonable approach? If not, is there a way to do this with a function?

Edits:

This is the function/method version of the above handler.

public PostLogoutRedirectHandler(): Promise<any> {
    this.logger.Debug("PostLogoutRedirectHandler");
    return this.UserManager.signoutRedirectCallback(null);
}

It throws the following error:

Cannot read property 'UserManager' of undefined

Of course, using the lambda arrow function works. Is this arrow function approach a reasonable pattern or an anti-pattern? What are its costs?

Shaun Luttin
  • 133,272
  • 81
  • 405
  • 467
  • I'm not sure I get the problem, but could you not just `bind` the function? – robbmj Sep 24 '16 at 16:57
  • What does it mean to `bind` the function? – Shaun Luttin Sep 24 '16 at 16:58
  • It will bind the `this` context to your `OpenIdConnect` instance: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_objects/Function/bind – robbmj Sep 24 '16 at 16:59
  • I think this post will clear things up for you: http://stackoverflow.com/questions/28371982/what-does-this-refer-to-in-arrow-functions-in-es6 – robbmj Sep 24 '16 at 17:02
  • I updated my question to clarify the problem: `Cannot read property 'UserManager' of undefined`. – Shaun Luttin Sep 24 '16 at 17:03
  • @robbmj So it sounds like the answer is that using a lambda is fine, and that binding the function is the way to do the same thing with a function. Is that right? – Shaun Luttin Sep 24 '16 at 17:06
  • 1
    I'm not exactly sure if it is right, but I suspect he means binding the function like this: `this.routerConfigurationService.ConfigureRouter( routerConfiguration, this.PostLogoutRedirectHandler.bind(this));` – Nicolai Ehemann Sep 24 '16 at 19:09

1 Answers1

3

You need to use .bind(this) to pass this object for outer execution function like callbacks or promises:

function(){
  //code what will be execute out from current object
}.bind(this)
JayDi
  • 1,037
  • 15
  • 24