Skip to content

Commit

Permalink
update post
Browse files Browse the repository at this point in the history
  • Loading branch information
alisaduncan committed Feb 27, 2023
1 parent 8f10b4a commit 021fda1
Showing 1 changed file with 55 additions and 7 deletions.
62 changes: 55 additions & 7 deletions _source/_posts/2023-02-20-angular-forroot.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,64 @@ communities: [javascript]
description: ""
tags: [angular]
tweets:
- "Straightforward is best! Add your Okta configuration to Angular apps quickly!"
- "Follow best patterns to add your Okta configuration to Angular apps quickly!"
image: blog/angular-forroot/social.jpg
type: awareness
---

The Okta Angular SDK library supports a new configuration method. This improved way to pass in the required Okta configuration properties in Angular applications follows a common approach for adding modules.

The Okta Angular SDK supports a new and improved configuration method to pass in the required properties for incorporating Okta in your Angular applications. Now, you can add Okta to your Angular application using the `forRoot` pattern!

## The `forRoot` pattern in Angular

The `forRoot` pattern helps ensure services defined in `NgModules` aren't duplicated across the application. This is especially noteworthy if you have a module that both provides services and also has component and directive declarations. The intention for the `forRoot` static method is for importing and configuration to happen at the root module. This is good practice and recommended patterns for an authentication module! It can make configuring the `NgModule` more straightforward too!

The Okta Angular SDK now has more streamlined configuration options and helps promote good practices of importing the `OktaAuthModule` at the application root. Let's look at this configuration change.
Let's take a look at an example case, such as a cupcake e-commerce application with a module containing a service and view for supporting denoting your favorite treats with a heart. 😋🧁💜

Your service code might look like this with the `@Injectable()` decorator:

```ts
@Injectable()
export class FavoriteCupcakeService {
addCupcakeToFavorites(cupcake: Cupcake): Observable<Cupcake> {
// make HTTP call to add a cupcake to favorite for this user
}

getFavoriteCupcakes(): Observable<Cupcake[]> {
// make HTTP call to get all the favorite cupcakes for this user
}
}
```

Additionally, you have a component that supports the favorite cupcakes feature in the favorite cupcake module:

```ts
@NgModule {
declarations: [FavoriteCupcakeComponent],
exports: [FavoriteCupcakeComponent],
providers: [FavoriteCupcakeService]
}
export class FavoriteCupcakeModule {}
```

In your application module, you might import the `FavoriteCupcakeModule`, making the declared `FavoriteCupcakeComponent` and provided `FavoriteCupcakeService` available throughout your application.

But what if you don't import the `FavoriteCupcakeModule` in the `AppModule` or if you want to use the `FavoriteCupcakeComponent` in a lazy-loaded feature module in your app? You'll have to reimport the `FavoriteCupcakeModule` in that lazy-loaded module. Each lazy-loaded module has an injector instance, so you may have multiple instances of the `FavoriteCupcakeService` in your application, which we don't want.

One option is to amend the `@Injectable()` decorator to add the metadata that determines where in the application the service is provided using the `providedIn` property:

```ts
@Injectable({
providedIn: 'root'
})
```

This declaration within the decorator is preferable over providing the service within a module's `providers` array because it supports tree-shaking.

Another option is adding the `forRoot()` static method to the `FavoriteCupcakeModule` and providing the `FavoriteCupcakeService`instead of through the `providers` array. The `FavoriteCupcakeService` can and should be a singleton instance for the application, and the `forRoot()` static method sets the module up to do so.

Following in the steps of this best practice, the Okta Angular SDK now has more streamlined configuration options and helps promote good practices of importing the `OktaAuthModule` at the application root. Authentication applies to the entire application and should not depend on where you imported the `OktaAuthModule` in the application.

Let's look at this configuration change.

## Configuring the Okta Angular SDK using OAuth 2.0 and OpenID Connect (OIDC)

Expand All @@ -43,7 +87,9 @@ const oktaAuth = new OktaAuth({
export class AppModule { }
```

This method will continue to work. However, you can now change your configuration to look like this instead:
This method will continue to work, and you can continue using the module as you have it now without any changes.

However, you can now change your configuration to pass in your Okta config directly into the `forRoot()` method of the `OktaAuthModule`. Not only is this more straightforward, it sets your application up to practice better architecture:

```ts
const oktaAuth = new OktaAuth({
Expand All @@ -63,7 +109,9 @@ The `OktaAuthModule` handles setting the `OKTA_CONFIG` injection token for you,

## Configuring Okta Angular application going forward

Since it is the most straightforward, we recommend using the `OktaAuthModule.forRoot()` static method when configuring Okta in new Angular applications. You're still covered with backward-compatibility support if you have more complex needs, such as requiring a factory method to provide the `OKTA_CONFIG` injection token.
Since authentication-related services should be application-wide, we recommend using the `OktaAuthModule.forRoot()` static method when configuring Okta in new Angular applications. You're still covered with backward-compatibility support if you have more complex needs, such as requiring a factory method to provide the `OKTA_CONFIG` injection token.

The Okta Angular SDK team plans to improve this in the future. They recognize the current `OktaAuthModule` can improve, and to truly support `forRoot()`, they will have to remove auth services from the `providers` array of the module, which breaks backward compatibility. The Okta Angular SDK team also is preparing to support the latest Angular features, which will become the Angular recommended patterns going forward, such as stand-alone components, module-less architecture, and functional route guards. If you have thoughts or input, or want to share how you use the Okta Angular SDK so the team can make sure they consider it, feel free to drop a note in the comment below.

## Learn more about Angular, Dependency Injection, and OpenID Connect

Expand All @@ -72,4 +120,4 @@ If you liked this post, you might want to check out the following.
* [Three Ways to Configure Modules in Your Angular App](/blog/2022/02/24/angular-async-config)
* [Add OpenID Connect to Angular Apps Quickly](/blog/2022/02/11/angular-auth0-quickly)

Remember to follow us on [Twitter](https://twitter.com/oktadev) and subscribe to our [YouTube channel](https://www.youtube.com/c/OktaDev/) for more exciting content. We also want to hear from you about what tutorials you want to see. Leave us a comment below.
Remember to follow us on [Twitter](https://twitter.com/oktadev) and subscribe to our [YouTube channel](https://www.youtube.com/c/OktaDev/) for more exciting content. We also want to hear about what tutorials you want to see. Leave us a comment below.

0 comments on commit 021fda1

Please sign in to comment.