I noticed in github that 9.3 final has been closed already week ago but no release yet. https://github.com/abpframework/abp/milestone/128
When are you going to release it? I need this fix https://abp.io/support/questions/10081/Abp-button-is-not-working-inside-abp-modal-when-abp-modal-is-used-inside-non-standalone-component
Is it possible to configure how angular proxies are generated? Now with newer angular versions it is preferred way to use inject() instead of constructor injection. So generate tool is still generating this to proxy services:
constructor(private restService: RestService) {}
Instead preferred way would be
private restService = inject(RestService);
If proxy generation is no possible to configure that way, could you update your abp-generate script to generate proxies with inject?
And I will once again tell you that this support form has weird question at end. "Tiered (MVC) or Auth Server Separated (Angular)" and only options is yes and no. What does yes mean? Does it mean MVC or Separated.
I assume this problem is related to standalone change. My application is still using module based system. I have notice that all abp-buttons that are inside abp-modal are not working. There is no exception or error, click just doesn't work. I tested that if I changed abpClick to click it start to work but I assume that this is not inteded. Should abp-button inside abp-modal work with abpClick when used inside non-standalone component? Is there some service used inside abp-button or inside abp-modal that needs to be provided?
I ahve similar problem with this one https://abp.io/support/questions/8997/NullInjectorError-No-provider-for-InjectionToken-undefined-in-Standalone-Component But those suggested solutions didn't work for me.
Here is version that I'm using at frontend: node version 22.20.0 yarn 1.22.22 abp 9.3.6 angular 20.3.7
I updated from 8.3.4 to 9.3.6 and followed your migration guides.
We will stay with module based structure because our application is quite big. Maybe later but not now.
So problem occures when I'm trying to navigate to 'saas/tenants' page. Page stays empty and I got console error that says: No provider found for InjectionToken undefined. Source: Standalone[_TenantsComponent].
I have tried to clean all places: node_modules, .angular and yarn.lock.
Am I missing some module or provider in my app module.
Here is my app.module.ts(I cleaned away our own modules):
import { PAGE_RENDER_STRATEGY } from '@abp/ng.components/page';
import {
CoreModule,
LazyLocalizationPipe,
LocalizationPipe,
LocalizationService,
NAVIGATE_TO_MANAGE_PROFILE,
provideAbpCore,
withOptions,
} from '@abp/ng.core';
import { provideSettingManagementConfig, SettingManagementConfigModule } from '@abp/ng.setting-management/config';
import {
CUSTOM_ERROR_HANDLERS,
DEFAULT_VALIDATION_BLUEPRINTS,
provideAbpThemeShared,
ThemeSharedModule,
withHttpErrorConfig,
} from '@abp/ng.theme.shared';
import { registerLocaleData } from '@angular/common';
import { provideHttpClient, withInterceptorsFromDi, withXsrfConfiguration } from '@angular/common/http';
import localeFi from '@angular/common/locales/fi';
import { ErrorHandler, LOCALE_ID, NgModule, importProvidersFrom, isDevMode } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { VALIDATION_BLUEPRINTS } from '@ngx-validate/core';
// https://www.telerik.com/kendo-angular-ui/components/globalization/internationalization/locale-changes/
import { IntlService } from '@progress/kendo-angular-intl';
import '@progress/kendo-angular-intl/locales/en/all';
import '@progress/kendo-angular-intl/locales/fi/all';
import { MessageService } from '@progress/kendo-angular-l10n';
import { CommercialUiConfigModule, provideCommercialUiConfig } from '@volo/abp.commercial.ng.ui/config';
import { AccountAdminConfigModule, provideAccountAdminConfig } from '@volo/abp.ng.account/admin/config';
import { AccountPublicConfigModule, provideAccountPublicConfig } from '@volo/abp.ng.account/public/config';
import { AuditLoggingConfigModule, provideAuditLoggingConfig } from '@volo/abp.ng.audit-logging/config';
import { provideOpeniddictproConfig } from '@volo/abp.ng.openiddictpro/config';
import { IdentityConfigModule, provideIdentityConfig } from '@volo/abp.ng.identity/config';
import { registerLocale } from '@volo/abp.ng.language-management/locale';
import { provideSaasConfig, SaasConfigModule } from '@volo/abp.ng.saas/config';
import { HttpErrorComponent, ThemeLeptonModule } from '@volo/abp.ng.theme.lepton';
import { MenuSearchModule } from '@volo/abp.ng.theme.lepton/extensions';
import { AngularSvgIconModule } from 'angular-svg-icon';
import { environment } from '../environments/environment';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { KendoFormsModule } from './common/kendo-forms/kendo-forms.module';
import { HelpComponent } from './components/help/help.component';
import { ControlsConfigModule } from './controls/controls-config.module';
import { ComponentsConfigModule } from './demo/components/components-config.module';
import { TablesConfigModule } from './demo/tables/tables-config.module';
import { ItemPlanningConfigModule } from './item-planning/item-planning-config.module';
import { APP_ROUTE_PROVIDER } from './route.provider';
import { ScmPageRenderStrategy } from './scm-page-render-strategy';
import { SettingsConfigModule } from './settings/settings-config.module';
import { ApplicationInsightsErrorHandler } from './shared/services/application-insights-service/application-insights-error-handler';
import { KendoMessagesService } from './shared/services/kendo-messages-service/kendo-messages.service';
import { TawkService } from './tawk-service';
import { provideAbpOAuth } from '@abp/ng.oauth';
import { BeamerService } from './beamer.service';
import { ServiceWorkerModule } from '@angular/service-worker';
import { SCMCustomErrorHandlerService } from './shared/services/custom-error-handler-service/scm-custom-error-handler.service';
import { ForecastingConfigModule } from 'projects/SCM.Forecasting/config/src/forecasting-config.module';
import { USER_MENU_ADDED_ITEMS } from './account/user-menu-extended.routes';
import { AccountConfigModule } from './account/account-config.module';
import { Router } from '@angular/router';
import { KendoIntlService } from './shared/services/kendo-intl.service';
import { XmasModule } from './shared/components/special-events/xmas/xmas.module';
import { provideLanguageManagementConfig } from '@volo/abp.ng.language-management/config';
import { provideTextTemplateManagementConfig } from '@volo/abp.ng.text-template-management/config';
import { provideAnimations } from '@angular/platform-browser/animations';
// Finnish locale needs to be registered always since we have scm currency pipe that might use different locale from localization service.
// If it is not registered fi-FI locale is not found if the language is not fi
registerLocaleData(localeFi);
const dev = environment.production ? [] : [ComponentsConfigModule.forRoot(), TablesConfigModule.forRoot()];
@NgModule({
declarations: [AppComponent, HelpComponent],
bootstrap: [AppComponent],
imports: [
AngularSvgIconModule.forRoot(),
BrowserModule,
AppRoutingModule,
CoreModule,
ThemeSharedModule,
AccountAdminConfigModule,
IdentityConfigModule,
SaasConfigModule,
AuditLoggingConfigModule,
SettingManagementConfigModule,
MenuSearchModule.forRoot({ limit: 3 }),
ThemeLeptonModule.forRoot({
// DISABLED Search and Help main navigation items, left here for easy re-enabling:
// contentBeforeRoutes: [MenuSearchComponent],
// contentAfterRoutes: [HelpComponent]
// If this customStyle is true, the style selection box is not included in the theme
// settings form and ThemeLeptonModule does not load its own styles. In this case,
// a custom style file must be added to the styles array in angular.json or must be imported by style.scss.
// https://docs.abp.io/en/commercial/7.1/themes%2Flepton%2Fcustomizing-lepton-theme?UI=NG
customStyle: true,
}),
CommercialUiConfigModule,
ItemPlanningConfigModule.forRoot(),
ControlsConfigModule.forRoot(),
SettingsConfigModule.forRoot(),
AccountConfigModule.forRoot(),
KendoFormsModule,
...dev,
ServiceWorkerModule.register('ngsw-worker.js', {
enabled: !isDevMode(),
// Register the ServiceWorker as soon as the application is stable
// or after 30 seconds (whichever comes first).
registrationStrategy: 'registerWhenStable:30000',
}),
XmasModule,
],
providers: [
APP_ROUTE_PROVIDER,
USER_MENU_ADDED_ITEMS,
KendoIntlService,
provideAbpCore(
withOptions({
environment,
registerLocaleFn: registerLocale(),
}),
),
provideHttpClient(
withInterceptorsFromDi(),
withXsrfConfiguration({
cookieName: 'XSRF-TOKEN',
headerName: 'RequestVerificationToken',
}),
),
provideAbpThemeShared(
withHttpErrorConfig({
errorScreen: {
component: HttpErrorComponent,
forWhichErrors: [401, 403, 404, 500],
hideCloseIcon: true,
},
}),
),
importProvidersFrom(
AccountPublicConfigModule.forRoot(),
AccountAdminConfigModule.forRoot(),
IdentityConfigModule.forRoot(),
SaasConfigModule.forRoot(),
),
provideAnimations(),
provideAbpOAuth(),
provideIdentityConfig(),
provideSettingManagementConfig(),
provideAccountAdminConfig(),
provideAccountPublicConfig(),
provideCommercialUiConfig(),
provideSaasConfig(),
provideAuditLoggingConfig(),
provideOpeniddictproConfig(),
provideTextTemplateManagementConfig(),
provideLanguageManagementConfig(),
{
provide: LocalizationPipe,
useExisting: LazyLocalizationPipe,
},
{
provide: IntlService,
useExisting: KendoIntlService,
},
{
provide: LOCALE_ID,
deps: [LocalizationService],
useFactory: (localizationService: LocalizationService) => localizationService.currentLang,
},
{ provide: MessageService, useExisting: KendoMessagesService },
{ provide: PAGE_RENDER_STRATEGY, useClass: ScmPageRenderStrategy },
{
provide: VALIDATION_BLUEPRINTS,
useValue: {
...DEFAULT_VALIDATION_BLUEPRINTS,
pattern: 'AbpValidation::InvalidPatternPleaseReviewYourInput',
min: 'AbpValidation::ThisFieldMustBeGreaterThanOrEqualTo{0}[{{ min }}]',
max: 'AbpValidation::ThisFieldMustBeLessThanOrEqualTo{0}[{{ max }}]',
calculationPeriodStartDate: 'AbpValidation::StartDateCanNotBeInFuture',
duplicatePriority: 'AbpValidation::PriorityIsAlreadyInUse',
duplicateName: 'AbpValidation::NameIsAlreadyInUse',
dateIsInPast: 'AbpValidation::DateCanNotBeInPast',
maxDecimals: 'AbpValidation::ThisFieldMustContainLessThanOrEqualDecimals{0}[{{ maxDecimals }}]',
greaterThanField: 'AbpValidation::ThisFieldMustBeGreaterThan{0}[{{ field }}]',
greaterThanZero: 'AbpValidation::ThisFieldMustBeGreaterThan{0}[0]',
lessThanField: 'AbpValidation::ThisFieldMustBeLessThan{0}[{{ field }}]',
invalidValues: 'AbpValidation::InvalidValues{0}ValidValues{1}[{{ invalidField }},{{ validField }}]',
missingRequiredValues: 'AbpValidation::MissingRequiredValues{0}[{{ field }}]',
dateIsNotInPastOrToday: 'AbpValidation::DateCanNotBeInPastOrToday',
},
},
{ provide: CUSTOM_ERROR_HANDLERS, useExisting: SCMCustomErrorHandlerService, multi: true },
{ provide: ErrorHandler, useClass: ApplicationInsightsErrorHandler },
{
provide: NAVIGATE_TO_MANAGE_PROFILE,
deps: [Router],
useFactory: (router: Router) => () => router.navigate(['/account/manage']),
},
TawkService,
BeamerService,
],
})
export class AppModule {}
We are using lepton theme with angular. Angular is updated to 20 when Abp was updated to 9.3.4. Now after updates I managed to get UI open there is no side bar at left. I noticed in browser that there is empty layout inside dynamic layout instead of application layout which contains all necessary things. Do you have experience with Abp 9 with lepton theme?
When tenant has only one third party auth provider set to use and local login is not in use user is forwarded to thrid party login page automatically as you know. If that user click logout, user is redirected to logged-out page in our application after user is logged out. In that page I added button which user can click and return to application. What if user wants to change Tenant to other. Like our user suppport. They use impersonator so they can go any tenant. Now if they go to any tenant which have local login disabled and azure login is used for example they cannot change tenant anymore in login page because auth server is remembering tenant and redirecting to microsoft login page before user can change tenant.
In local environment with ng serve both applications are in same domain, localhost. In that scenario it was enough to clear __tenant cookie from cookie. But now it is not working in our Azure environemnt where application is in application-test.ab.app and auth server is auth.application-test.ab.app. When I'm in application I see this cookie.
Currently I am trying this to forget tenant when user is logging out:
cookieService.delete('__tenant', '/');
sessionStateService.setTenant(undefined);
I use ngx-cookie-service to delete cookie. I also tried to set tenant to undefined.
I know that I cannot delete cookie from another domain. So do you have any solution to forget selected tenant. I only need to do this for tenants which are not using local login.
If user select his own tenant but not have yet registered into it. After user has logged in for example in microsoft login page user is returned to register page. In register page user can change his username and email but also can change tenant. If user knows any other tenant which have self registration in use user can change to that tenant and then click register button. This way it is possible to go into wrong tenant. User can for example go to host tenant by clearing tenant in dialog.
Is this real problem and can you reproduce it?
Auth server is separated.
Angular version is 18.2.13 as suggested in 8.3 upgrade guide. I got error in browser console but everything seems to be working. Original error:
Cannot find the fi-FI locale file. You can check how can add new culture at https://abp.io/docs/latest/framework/ui/angular/localization#adding-a-new-culture
original related code:
import { registerLocaleData } from '@angular/common';
import { registerLocale } from '@volo/abp.ng.language-management/locale';
registerLocaleData(localeFi);
provideAbpCore(
withOptions({
environment,
registerLocaleFn: registerLocale(),
}),
)
After I read this guide https://abp.io/docs/latest/framework/ui/angular/localization#adding-a-new-culture I added this code.
import { differentLocales } from '@abp/ng.core';
export function registerLocale(locale: string) {
return import(
/* webpackChunkName: "_locale-[request]"*/
/* webpackInclude: /[/\\](/docs/latest/framework/ui/angular/en%7Cfi).js/ */
/* webpackExclude: /[/\\]global|extra/ */
`@angular/common/locales/${differentLocales[locale] || locale}.js`
);
}
and I also tried to add localization through angular.json polyfills array like this.
"polyfills": [
"src/polyfills.ts",
"@angular/localize/init",
"@angular/common/locales/fi"
],
Exception what I get in browser console is this:
TypeError: Failed to resolve module specifier '@angular/common/locales/fi.js'
at registerLocale (app.module.ts:74:60)
74 line is @angular/common/locales/${differentLocales[locale] || locale}.js
I also tried this compination.
import { registerLocale } from '@abp/ng.core/locale';
provideAbpCore(
withOptions({
environment,
registerLocaleFn: registerLocale({
cultureNameLocaleFileMap: {
'fi-FI': 'fi',
},
errorHandlerFn: error => {
console.error('Error registering locale:', error);
},
}),
}),
),
but no luck.
So how those localizations should be loaded?
ps. this makes no sence in abp support form. Which one is yes, MVC or Angular?

1 logger) at Microsoft.EntityFrameworkCore.Infrastructure.ModelValidator.Validate(IModel model, IDiagnosticsLogger1 logger)
at Microsoft.EntityFrameworkCore.Infrastructure.RelationalModelValidator.Validate(IModel model, IDiagnosticsLogger1 logger) at Microsoft.EntityFrameworkCore.SqlServer.Infrastructure.Internal.SqlServerModelValidator.Validate(IModel model, IDiagnosticsLogger1 logger)
at Microsoft.EntityFrameworkCore.Infrastructure.ModelRuntimeInitializer.Initialize(IModel model, Boolean designTime, IDiagnosticsLogger1 validationLogger) at Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.GetModel(DbContext context, ModelCreationDependencies modelCreationDependencies, Boolean designTime) at Microsoft.EntityFrameworkCore.Internal.DbContextServices.CreateModel(Boolean designTime) at Microsoft.EntityFrameworkCore.Internal.DbContextServices.get_Model() at Microsoft.EntityFrameworkCore.Infrastructure.EntityFrameworkServicesBuilder.<>c.<TryAddCoreServices>b__8_4(IServiceProvider p) at ResolveService(ILEmitResolverBuilderRuntimeContext, ServiceProviderEngineScope) at ResolveService(ILEmitResolverBuilderRuntimeContext, ServiceProviderEngineScope) at ResolveService(ILEmitResolverBuilderRuntimeContext, ServiceProviderEngineScope) at ResolveService(ILEmitResolverBuilderRuntimeContext, ServiceProviderEngineScope) at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType) at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider) at Microsoft.EntityFrameworkCore.DbContext.get_ChangeTracker() at Volo.Abp.EntityFrameworkCore.AbpDbContext1.Initialize(AbpEfCoreDbContextInitializationContext initializationContext)
at Volo.Abp.Uow.EntityFrameworkCore.UnitOfWorkDbContextProvider1.CreateDbContextAsync(IUnitOfWork unitOfWork, String connectionStringName, String connectionString) at Volo.Abp.Uow.EntityFrameworkCore.UnitOfWorkDbContextProvider1.GetDbContextAsync()
at Volo.Abp.Domain.Repositories.EntityFrameworkCore.EfCoreRepository2.GetDbSetAsync() at Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo) at Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue1.ProceedAsync()
at Volo.Abp.Uow.UnitOfWorkInterceptor.InterceptAsync(IAbpMethodInvocation invocation)
at Volo.Abp.Castle.Dyn2025-01-16 13:12:43.260 +02:00 [INF] Loaded ABP modules:_mLOutputStorageService.ConnectToOutputStorage();
string currentTenantName = _currentTenant.Name!;
IList<BaselineDemandForecast> baselineDemandForecasts = await _mLOutputStorageService.DownloadForecastDataAsync(currentTenantName);
//remove all old forecasts from same run and insert new ones
var newRunIdFromDownloadedData = baselineDemandForecasts[0]?.RunId;
var query = await _baselineDemandForecastRepository.GetQueryableAsync();
var oldForecasts = query.Where(x => x.RunId == newRunIdFromDownloadedData);
await _baselineDemandForecastRepository.DeleteFromQueryAsync(oldForecasts);
foreach (var item in baselineDemandForecasts)
{
item.TenantId = _currentTenant.Id;
}
await _sqlBulkOperationsBaselineDemandForecastRepository.BulkInsert(baselineDemandForecasts);
and spesific line is:
var query = await _baselineDemandForecastRepository.GetQueryableAsync();
Weird thing is that I haven't touched this part of code.
I have some changes is in some Repositories.
Here is original code from there.
public EfCoreCalculatedSeasonalityProfileRepository(IDbContextProvider<ForecastingDbContext> dbContextProvider)
and we changed to use interface like this:
public EfCoreCalculatedSeasonalityProfileRepository(IDbContextProvider<IForecastingDbContext> dbContextProvider)
but changes were into different repositories than what I'm using where probelm seems to be.
I found that in some other your customers have same kind of issues that they were missing module dependeces but I didn't found samekind of deficiencies in our code.
Here is definiton of that entity:
public class BaselineDemandForecast : Entity<Guid>, IMultiTenant
And here is builder configuration:
public class BaselineDemandForecastModelCreatingExtensions : IModuleEntityTypeConfiguration<BaselineDemandForecast>
{
public bool IsApplicationDbContext { get; set; }
public bool IsSqlite { get; set; }
public void Configure(EntityTypeBuilder<BaselineDemandForecast> builder)
{
builder.ToTable(ForecastingDbProperties.DbTablePrefix + "BaselineDemandForecasts", ForecastingDbProperties.DbSchema);
builder.ConfigureByConvention();
builder.ConfigureByConventionSCM(IsSqlite);
//here is ton of field definitions.
}
}
Now I made test what is running this part of code. I only mock MLOutputStorageService to give me spesific list of items. And no exception.
Any idea what could be creating this issue?
I logged in into tenant with user. Navigated to Account/manage and there I go to Personal information. There I click confirm button next to email field. I receive email. Confirmation link contains only account/EmailConfirmation?userId=1111111-7777-1111-6666-77777777&__tenant=666666-4444-7777-ec6a-99999999&confirmationToken=SOME_TOKEN&returnUrl=https://our.url//account/login So it is missing domain part. Reseting password is working as it should and link is complete and working. I checked text template and they are similar between password reset and email confirmation.
div>
a> href="{{model.link}}">{{L "ConfirmMyEmail"}} a>
div>
We have these in configuration:
Configure<AppUrlOptions>(options =>
{
options.Applications["Angular"].RootUrl = configuration["App:AngularUrl"];
options.Applications["Angular"].Urls[AccountUrlNames.PasswordReset] = "account/reset-password";
options.Applications["Angular"].Urls[AccountUrlNames.EmailConfirmation] = "account/email-confirmation";
});