[英]Event in (selectionChange) returns error Cannot read properties of undefined (reading 'value')
[英]Okta Component giving error at runtime Cannot read properties of undefined (reading '_oktaUserAgent')
我在我的項目中使用 OKTA 授權,但在運行時遇到錯誤
嘗試用谷歌搜索,但找不到任何相關的解決方案
這是錯誤
TypeError: Cannot read properties of undefined (reading '_oktaUserAgent')
at new OktaAuthModule (okta-angular.js:236)
at Object.OktaAuthModule_Factory [as factory] (okta-angular.js:260)
at R3Injector.hydrate (core.js:11354)
at R3Injector.get (core.js:11175)
at core.js:11212
at Set.forEach (<anonymous>)
at R3Injector._resolveInjectorDefTypes (core.js:11212)
at new NgModuleRef$1 (core.js:24308)
at NgModuleFactory$1.create (core.js:24362)
at core.js:28101
這是我的 Appmodule.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { HttpClientModule } from '@angular/common/http';
import { ProductListComponent } from './components/product-list/product-list.component';
import { ProductService } from './service/product.service';
import { Router, RouterModule, Routes } from '@angular/router';
import { ProductCategoryMenuComponent } from './components/product-category-menu/product-category-menu.component';
import { SearchComponent } from './components/search/search.component';
import { ProductDetailsComponent } from './components/product-details/product-details.component';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { CartStatusComponent } from './components/cart-status/cart-status.component';
import { CartDetailsComponent } from './components/cart-details/cart-details.component';
import { CheckoutComponent } from './components/checkout/checkout.component';
import { ReactiveFormsModule } from '@angular/forms';
import { LoginComponent } from './components/login/login.component';
import {
OKTA_CONFIG,
OktaAuthModule,
OktaCallbackComponent
} from '@okta/okta-angular';
import myAppConfig from './config/my-app-config';
import { LoginStatusComponent } from './components/login-status/login-status.component';
const oktaConfig = Object.assign({
onAuthRequired: (injector) =>{
const router = injector.get(Router);
router.navigate(['/login']);
}
}, myAppConfig.oidc);
const routes: Routes = [
{path: 'login/callback', component: OktaCallbackComponent},
{path: 'login', component: LoginComponent},
{path: 'checkout', component: CheckoutComponent },
{path: 'cart-details', component: CartDetailsComponent },
{path: 'products/:id', component: ProductDetailsComponent },
{path: 'search/:keyword', component: ProductListComponent },
{path: 'category/:id', component: ProductListComponent},
{path: 'category', component: ProductListComponent},
{path: 'products', component: ProductListComponent},
{path: '', redirectTo: '/products', pathMatch: 'full'},
{path: '**', redirectTo: '/products', pathMatch: 'full'}
];
@NgModule({
declarations: [
AppComponent,
ProductListComponent,
ProductCategoryMenuComponent,
SearchComponent,
ProductDetailsComponent,
CartStatusComponent,
CartDetailsComponent,
CheckoutComponent,
LoginComponent,
LoginStatusComponent
],
imports: [
RouterModule.forRoot(routes),
BrowserModule,
HttpClientModule,
NgbModule,
ReactiveFormsModule,
OktaAuthModule
],
providers: [ProductService, {provide: OKTA_CONFIG, useValue: oktaConfig}],
bootstrap: [AppComponent]
})
export class AppModule { }
這是我對okta myAppConfig的配置
export default {
oidc: {
clientId: '<your client id>',
issuer: 'https:<your url>/oauth2/default',
redirectUri: 'http://localhost:4200/login/callback',
scopes: ['openid', 'profile', 'email']
}
}
這是我的登錄狀態組件在應用程序開始時加載
import { Component, OnInit } from '@angular/core';
import { OktaAuthStateService } from '@okta/okta-angular';
import { OktaAuth } from '@okta/okta-auth-js';
@Component({
selector: 'app-login-status',
templateUrl: './login-status.component.html',
styleUrls: ['./login-status.component.css']
})
export class LoginStatusComponent implements OnInit {
isAuthenticated: boolean = false;
userFullName: string;
constructor(private oktaAuth: OktaAuth,private authstateService: OktaAuthStateService) { }
ngOnInit(): void {
this.oktaAuth.authStateManager.subscribe(
(result)=>{
this.isAuthenticated = result
this.getUserDetails()
}
)
}
getUserDetails() {
if(this.isAuthenticated){
this.oktaAuth.getUser().then(
(res)=>{
this.userFullName = res.name
}
)
}
}
logout(){
this.oktaAuth.signOut();
}
}
這是我的登錄組件
import { Component, OnInit } from '@angular/core';
import { OktaAuthStateService } from '@okta/okta-angular';
//import { OktaAuthService } from '@okta/okta-angular';
import * as OktaSignIn from '@okta/okta-signin-widget';
import myAppConfig from 'src/app/config/my-app-config';
import { OktaAuth } from '@okta/okta-auth-js';
@Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit {
oktaSignin: any;
constructor(private oktaAuthService: OktaAuthStateService,private oktaAuth: OktaAuth) {
this.oktaSignin = new this.oktaSignin({
baseUrl: myAppConfig.oidc.issuer.split('/oauth2')[0],
clientId: myAppConfig.oidc.clientId,
redirectUri: myAppConfig.oidc.redirectUri,
authParams: {
pkce: true,
issuer: myAppConfig.oidc.issuer,
scopes: myAppConfig.oidc.scopes
}
})
}
ngOnInit(): void {
this.oktaSignin.remove();
this.oktaSignin.renderEl(
{
el: '#okta-sign-in-widget' // this name should be same as div tag id in login.component.html
},
(response) =>{
if (response.status === 'SUCCESS') {
this.oktaAuth.signInWithRedirect();
}
},
(error) => {
throw error;
}
)
}
}
問題是您的源代碼 Okta Angular 與新版本 Okta Angular 不兼容...按照說明遷移: https ://github.com/okta/okta-angular/blob/master/MIGRATING.md
我已經解決了這個問題,因為這個源代碼來自與我在 udemy 上的同一門課程:D。
我正在使用 Okta 5
更改app.module.ts
:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { ProductListComponent } from './components/product-list/product-list.component';
import { HttpClientModule } from '@angular/common/http';
import { ProductService } from './services/product.service';
import { RouterModule, Routes } from '@angular/router';
import { ProductCategoryMenuComponent } from './components/product-category-menu/product-category-menu.component';
import { SearchComponent } from './components/search/search.component';
import { ProductDetailsComponent } from './components/product-details/product-details.component';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { CartStatusComponent } from './components/cart-status/cart-status.component';
import { CartDetailsComponent } from './components/cart-details/cart-details.component';
import { CheckoutComponent } from './components/checkout/checkout.component';
import { ReactiveFormsModule } from '@angular/forms';
import { LoginComponent } from './components/login/login.component';
import { LoginStatusComponent } from './components/login-status/login-status.component';
import {
OKTA_CONFIG,
OktaAuthModule,
OktaCallbackComponent
} from '@okta/okta-angular';
import { OktaAuth } from '@okta/okta-auth-js';
import appConfig from './config/app-config';
// create routes
const routes: Routes = [
{ path: 'login/callback', component: OktaCallbackComponent },
{ path: 'login', component: LoginComponent },
{ path: 'checkout', component: CheckoutComponent },
{ path: 'cart-details', component: CartDetailsComponent },
{ path: 'products/:id', component: ProductDetailsComponent },
{ path: 'search/:keyword', component: ProductListComponent },
{ path: 'category/:id/:name', component: ProductListComponent },
{ path: 'category', component: ProductListComponent },
{ path: 'products', component: ProductListComponent },
{ path: '', redirectTo: '/products', pathMatch: 'full' },
{ path: '**', redirectTo: '/products', pathMatch: 'full' }
];
const oktaAuth = new OktaAuth(appConfig.oidc); // the name variable must oktaAuth
@NgModule({
declarations: [
AppComponent,
ProductListComponent,
ProductCategoryMenuComponent,
SearchComponent,
ProductDetailsComponent,
CartStatusComponent,
CartDetailsComponent,
CheckoutComponent,
LoginComponent,
LoginStatusComponent
],
imports: [
RouterModule.forRoot(routes),
BrowserModule,
HttpClientModule,
NgbModule,
ReactiveFormsModule,
OktaAuthModule
],
providers: [ProductService, {provide: OKTA_CONFIG, useValue: {oktaAuth}}],
bootstrap: [AppComponent]
})
export class AppModule { }
文件login.component.ts
:
import { Component, Inject, OnDestroy, OnInit } from '@angular/core';
import OktaSignIn from '@okta/okta-signin-widget';
import { OKTA_AUTH } from '@okta/okta-angular';
import appConfig from '../../config/app-config';
import { OktaAuth } from '@okta/okta-auth-js';
/**
* for more information: https://github.com/okta/okta-angular
* for change/migration version future read: https://github.com/okta/okta-angular/blob/master/MIGRATING.md
*/
@Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit, OnDestroy {
oktaSignin: any;
constructor(@Inject(OKTA_AUTH) private oktaAuth: OktaAuth) {
this.oktaSignin = new OktaSignIn({
logo: 'assets/images/angular-logo.svg',
baseUrl: appConfig.oidc.issuer.split('/oauth2')[0],
clientId: appConfig.oidc.clientId,
redirectUri: appConfig.oidc.redirectUri,
authParams: {
pkce: true,
issuer: appConfig.oidc.issuer,
scopes: appConfig.oidc.scopes
}
});
}
ngOnInit(): void {
this.oktaSignin.remove(); // remove all to clean
this.oktaSignin.renderEl({
el: '#okta-sign-in-widget' // this name should same as div tag id in component.html
},
(response) => {
if (response.status === 'SUCCESS') {
this.oktaAuth.signInWithRedirect();
}
},
(error) => {
throw error;
}
);
}
ngOnDestroy(): void {
this.oktaSignin.remove();
}
}
文件login-status.component
:
import { Component, Inject, OnInit } from '@angular/core';
import { OKTA_AUTH } from '@okta/okta-angular';
import { OktaAuth } from '@okta/okta-auth-js';
@Component({
selector: 'app-login-status',
templateUrl: './login-status.component.html',
styleUrls: ['./login-status.component.css']
})
export class LoginStatusComponent implements OnInit {
isAuthenticated: boolean = false;
userFullName: string = "";
constructor(@Inject(OKTA_AUTH) private oktaAuth: OktaAuth) {
this.oktaAuth.authStateManager.subscribe(
isAuth => this.isAuthenticated = isAuth
);
}
async ngOnInit() {
this.isAuthenticated = await this.oktaAuth.isAuthenticated();
if (this.isAuthenticated) {
const userClaim = await this.oktaAuth.getUser();
this.userFullName = userClaim.name || "";
}
console.log("Autentication = " + this.isAuthenticated);
console.log("Username = " + this.userFullName);
}
async logout() {
// terminates the session
await this.oktaAuth.signOut();
}
}
我也更新文件:
文件tsconfig.json
/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
"compileOnSave": false,
"compilerOptions": {
"baseUrl": "./",
"outDir": "./dist/out-tsc",
"forceConsistentCasingInFileNames": true,
"strict": true,
"noImplicitOverride": true,
"noPropertyAccessFromIndexSignature": true,
"noImplicitReturns": true,
"noImplicitAny": false,
"noFallthroughCasesInSwitch": true,
"sourceMap": true,
"declaration": false,
"downlevelIteration": true,
"experimentalDecorators": true,
"moduleResolution": "node",
"importHelpers": true,
"target": "es2017",
"module": "es2020",
"lib": [
"es2020",
"dom"
]
},
"angularCompilerOptions": {
"enableI18nLegacyMessageIdFormat": false,
"strictInjectionParameters": true,
"strictInputAccessModifiers": true,
"strictTemplates": true,
"esModuleInterop": true, // <- add this
"allowSyntheticDefaultImports": true // <-- add this
}
}
我更新到angular.json
部分:
...
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"allowedCommonJsDependencies": [
"lodash",
"@babel/runtime-corejs3"
],
...
您在 app.module.ts 的 provider 行中缺少一組圍繞 oktaAuth 的花括號
{ provide: OKTA_CONFIG, useValue: { oktaAuth } },
來自[https://gitmemory.cn/repo/okta/okta-angular/issues/71][1]
在“LoginStatusComponent”和“LoginComponent”的“構造函數”中的“private oktaAuth: OktaAuth”之前使用@Inject(OKTA_AUTH)
我有同樣的問題。 嘗試降級節點版本並重新安裝okta/angular
包:
npm i @okta/okta-angular
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.