-
Notifications
You must be signed in to change notification settings - Fork 61
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
App State Observable #168
App State Observable #168
Conversation
92634ae
to
a57086f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the PR, Keep in mind it is encourages to open an issue first so we can discuss this before the work is done.
I do want to add that appState
is already available to your application today, but I agree it's not clear on how to do so:
- Start with importing AuthModule and setting
skipRedirectCallback
totrue
. This will ensure our SDK will not handle the redirect for you.
imports: [
AuthModule.forRoot({ skipRedirectCallback: true })
]
- Call
handleRedirectCallback
yourself where appropriate, be sure this is only on the configured/callback
route:
constructor(private authService: AuthService) {
this.authService.handleRedirectCallback()
.pipe(map(result => result?.appState))
.subscribe(appState => /* use appState here */);
}
As you can see, calling handleRedirectCallback
yourself gives you access to the appState
without introducing any new code.
That said, I agree this is not convenient and I would prefer for people to not have to need to call handleRedirectCallback
themselves if all they need is access to the appState
.
README.md
Outdated
} | ||
``` | ||
|
||
> This method of saving application state will save it in Session Storage which is capable of holding multiple MBs worth of data, so you should have more than enough space for your needs |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is only true by default, but it could as well be cookies if useCookiesForTransactions
is used. Might also make sense to ensure it's clear that this data is only persisted temporarily and will be removed again once being redirected back to your application.
I also believe this message makes it sounds like you can just use this to track any appState you like (as we have storage for multiple MBs worth of data anyway), while I still believe your application should not solely rely on Auth0's SDK to persist your state, you could as well implement something yourself outside of our SDK which gives you more control.
I think it makes more sense to drop the last part and only mention it get stored in Session Storage by default, but can be stored into a cookie when setting useCookiesForTransactions
.
Because of the fact that we can also use cookies, I would (as mentioned earlier) remove any emphasis on deeply nested objects (which is also who I would prefer to not have this end up in the readme, as there are limitations to using appState and this SDK is not a state persisting library).
@@ -333,7 +340,10 @@ export class AuthService implements OnDestroy { | |||
if (!isLoading) { | |||
this.refreshState$.next(); | |||
} | |||
const target = result?.appState?.target ?? '/'; | |||
const appState = result.appState; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any reason why we changed result?.appState
to be result.appState
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pardon me, this was just a simple oversight on my part
@@ -36,6 +38,12 @@ export class AppComponent { | |||
ignoreCache: new FormControl(false), | |||
}); | |||
|
|||
ngOnInit(): void { | |||
this.auth.appState$.subscribe((appState) => { | |||
this.appState = appState.deeply.nested.value; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am confused with this example. The appState
is the appState
, and not some deeply nested value.
So I would either use this.appState = appState
or this.someOtherProperty = appState.deeply.nested.value
;
That said, even though it's good knowing this is possible, I would reduce the nesting here as I believe we want to avoid people using appState to track too much complexity. I would personally stick to a single property on the appState
.
value: this.loginOptionsForm.value.appState, | ||
}, | ||
}, | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here, it confuses me that we are using appState.deeply.nested.value = this.loginOptionsForm.value.appState
, it should either be appState: appState
or appState.deeply.nested.value = this.loginOptionsForm.value.someValue
.
However, I said before I would prefer to reduce the nesting.
const appState = result.appState; | ||
const target = appState?.target ?? '/'; | ||
|
||
this.appStateSubject$.next(appState); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Even though the comments on the appState$
mention it emits (if any), yet it emits even if appState
is null
or undefined
.
README.md
Outdated
loginWithRedirect(): void { | ||
this.auth.loginWithRedirect({ | ||
appState: { | ||
// Specify which application state you would like to preserve here (yes, objects ARE allowed) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would be a bit more explicit on the sample and drop the emphasis on objects here.
appState: {
myValue: 'My State to Track'
}
README.md
Outdated
|
||
ngOnInit() { | ||
this.auth.appState$.subscribe((appState) => { | ||
// Your value will be available here |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would show what this means instead of the comment:
this.auth.appState$.subscribe((appState) => {
console.log(appState.myValue);
});
README.md
Outdated
@@ -121,6 +121,56 @@ On your template, provide a button that will allow the user to log in to the app | |||
</button> | |||
``` | |||
|
|||
### Preserve application state through redirects |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would move this to our FAQ as I believe this is not a main feature of our SDK. We want to avoid that people rely to heavily on our SDK for tracking application state.
@frederikprijck Sorry for not opening a discussion request first. I'll be sure to do that if I do any more work on this repo. As far as the build issues go: the Cypress tests keep failing, because somewhere
|
Thanks for making the changes 🚀 🔥 |
No problem. Let me know if I missed anything or if there is anything else you want changed |
Cypress tests run fine locally. The reason they fail here is because we do not allow running them on forks. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for this PR 🔥
No problem. It was my pleasure |
Description
My changes enable direct access to the
appState
that is returned from thehandleRedirectCallback
method.This
appState
is made available through a newappState$
observable on theAuthService
class.References
The need for this feature has been voiced by a few other developers: https://community.auth0.com/t/handle-appstate-and-redirect-to-dynamic-url-after-successful-login-auth0-angular/50982
Testing
You can run both the unit tests and the e2e tests the normal way
Checklist
master