Open Closed

[Bug] User Edit Modal Role Tab Error In Identity Source Code #3654


User avatar
0
ldacnfinit created
  • ABP Framework version: v5.3.3
  • UI type: Angular
  • DB provider: EF Core
  • Tiered (MVC) or Identity Server Separated (Angular): Angular
  • Exception message and stack trace:

ERROR Error: Cannot find control with unspecified name attribute at _throwError (forms.mjs:1785:11) at setUpControl (forms.mjs:1574:13) at FormControlDirective.ngOnChanges (forms.mjs:5126:13) at FormControlDirective.rememberChangeHistoryAndInvokeOnChangesHook (core.mjs:1508:1) at callHook (core.mjs:2561:1) at callHooks (core.mjs:2520:1) at executeInitAndCheckHooks (core.mjs:2471:1) at selectIndexInternal (core.mjs:8416:1) at Module.ɵɵadvance (core.mjs:8399:1) at UsersComponent_ng_template_68_form_0_ng_container_12_ng_template_1_div_0_Template (users.component.html:181:49)

  • Steps to reproduce the issue:
  1. Add Identity module(version:5.3.0) to project with source-code by suite
  2. Solve build error
  3. Solve can't switch to role tab, I'll provide change detail if it needed
  4. The accident occur, error msg as it mentioned above, concrete in can't initial and edit user role, relation code like below: html:
<abp-modal [(visible)]="isModalVisible" [busy]="modalBusy" (disappear)="form = null">
 <ng-template #abpHeader>
   <h3>{{ (selected?.id ? 'AbpIdentity::Edit' : 'AbpIdentity::NewUser') | abpLocalization }}</h3>
 </ng-template>

 <ng-template #abpBody>
   <form
     *ngIf="form"
     [formGroup]="form"
     id="userForm"
     (ngSubmit)="save()"
     [validateOnSubmit]="true"
   >
     <ul
       id="user-nav-tabs"
       ngbNav
       #nav="ngbNav"
       class="nav-tabs"
       (navChange)="onNavChange($event)"
     >
       <li id="user-informations" [ngbNavItem]="1">
         <a ngbNavLink>{{ 'AbpIdentity::UserInformations' | abpLocalization }}</a>
         <ng-template ngbNavContent
           ><abp-extensible-form [selectedRecord]="selected"></abp-extensible-form
         ></ng-template>
       </li>
       <li id="user-roles" [ngbNavItem]="2">
         <a ngbNavLink>{{ 'AbpIdentity::Roles' | abpLocalization }}</a>
         <ng-container *ngIf="roleGroups != null">
           <ng-template ngbNavContent>
             <div
               *ngFor="let roleGroup of roleGroups; let i = index; trackBy: trackByFn"
               class="form-check mb-2"
             >
               <input
                 type="checkbox"
                 class="form-check-input"
                 [attr.id]="'roles-' + i"
                 [formControl]="roleGroup.get[roles[i].name]"
               />
               <label class="form-check-label" for="{{ 'roles-' + i }}">{{ roles[i].name }}</label>
             </div></ng-template
           ></ng-container
         >
       </li>
       <li id="user-organization-units" [ngbNavItem]="3">
         <a ngbNavLink>{{ 'AbpIdentity::OrganizationUnits' | abpLocalization }}</a>
         <ng-template ngbNavContent>
           <abp-tree
             *ngIf="organization.nodes?.length; else noDataMessage"
             [checkStrictly]="true"
             [checkable]="true"
             [nodes]="organization.nodes"
             [isNodeSelected]="organization.selectFn"
             [(checkedKeys)]="organization.checkedKeys"
             [(expandedKeys)]="organization.expandedKeys"
           ></abp-tree>

           <ng-template #noDataMessage>
             <p class="text-muted">
               {{ 'AbpIdentity::NoOrganizationUnits' | abpLocalization }}
             </p>
           </ng-template>
         </ng-template>
       </li>
     </ul>
     <div [ngbNavOutlet]="nav" class="mt-2 fade-in-top"></div>
   </form>
 </ng-template>

 <ng-template #abpFooter>
   <button type="button" class="btn btn-secondary" abpClose>
     {{ 'AbpIdentity::Cancel' | abpLocalization }}
   </button>
   <abp-button iconClass="fa fa-check" buttonType="submit" formName="userForm">{{
     'AbpIdentity::Save' | abpLocalization
   }}</abp-button>
 </ng-template>
</abp-modal>

ts:

  roleGroups: FormGroup[];
  setRoleGroups(): FormGroup[] {
    return ((this.form.get('roleNames') as FormArray)?.controls as FormGroup[]) || [];
  }

  buildForm() {
    const data = new FormPropData(this.injector, this.selected);
    this.form = generateFormFromProps(data);

    this.service.getAssignableRoles().subscribe(({ items }) => {
      this.roles = items;
      this.form.addControl(
        'roleNames',
        this.fb.array(
          this.roles.map(role =>
            this.fb.group({
              [role.name]: [
                this.selected.id
                  ? !!this.selectedUserRoles?.find(userRole => userRole.id === role.id)
                  : role.isDefault,
              ],
            })
          )
        )
      );
    });
    this.service.getAvailableOrganizationUnits().subscribe(res => {
      this.organization.response = res;
      this.organization.nodes = new TreeAdapter(res.items as BaseNode[]).getTree();
      this.organization.expandedKeys = res.items.map(item => item.id);
      this.organization.checkedKeys = this.selectedOrganizationUnits.map(unit => unit.id);
    });
  }

  openModal() {
    this.buildForm();
    this.isModalVisible = true;
  }

  onNavChange(changeEvent: NgbNavChangeEvent) {
    if (changeEvent.nextId === 2) {
      this.roleGroups = this.setRoleGroups();
    }
  }

I think this error is because the form initial before all controls has initial completed, especial role controls. But I'm not sure how to fix this question. Please help me, thank you very much!


15 Answer(s)
  • User Avatar
    0
    alper created
    Support Team Director

    thanks for the feedback. we're testing it...

  • User Avatar
    0
    mahmut.gundogdu created

    The problem is roleGroups field that was added by you.

    roleGroups: FormGroup[]; // <-- here your code
      setRoleGroups(): FormGroup[] {
        return ((this.form.get('roleNames') as FormArray)?.controls as FormGroup[]) || [];
      }
    

    but still the users.component.ts already has a getter that name is roleGroups

      get roleGroups(): FormGroup[] {
        return ((this.form.get('roleNames') as FormArray)?.controls as FormGroup[]) || [];
      }
    

    I think, if you change the variable name, it will be fixed.

  • User Avatar
    0
    ldacnfinit created

    Hi, I have discarded the roleGroups getter for sole the role tab render error question, if I use setter then I'll got the error msg like below:

    ERROR Error: NG0100: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value for 'id': 'undefined'. Current value: 'ngb-nav-1-panel'. It seems like the view has been created after its parent and its children have been dirty checked. Has it been created in a change detection hook?. Find more at https://angular.io/errors/NG0100 at throwErrorIfNoChangesMode (core.mjs:6744:1) at bindingUpdated (core.mjs:12747:1) at Module.ɵɵhostProperty (core.mjs:18461:1) at NgbNavPane_HostBindings (ng-bootstrap.mjs:6771:1) at processHostBindingOpCodes (core.mjs:9262:1) at refreshView (core.mjs:9541:1) at refreshEmbeddedViews (core.mjs:10646:1) at refreshView (core.mjs:9519:1) at refreshEmbeddedViews (core.mjs:10646:1) at refreshView (core.mjs:9519:1)

    The role tab even can't render, I think your code work well, maybe this question is because ng version, our ng version is ~13.3.11, I think your are not, can you switch ng version and have a try or any other advise for us? thank you again!

  • User Avatar
    0
    mahmut.gundogdu created

    Here, it is my package.json that I've tested. Could you send your code mahmut.gundogdu@volosoft.com

      "dependencies": {
        "@abp/ng.components": "~5.3.4",
        "@abp/ng.core": "~5.3.4",
        "@abp/ng.setting-management": "~5.3.4",
        "@abp/ng.theme.shared": "~5.3.4",
        "@volo/abp.commercial.ng.ui": "~5.3.4",
        "@volo/abp.ng.account": "~5.3.4",
        "@volo/abp.ng.audit-logging": "~5.3.4",
        "@volo/abp.ng.gdpr": "~5.3.4",
        "@volo/abp.ng.identity": "~5.3.4",
        "@volo/abp.ng.identity-server": "~5.3.4",
        "@volo/abp.ng.language-management": "~5.3.4",
        "@volo/abp.ng.saas": "~5.3.4",
        "@volo/abp.ng.text-template-management": "~5.3.4",
        "@volo/abp.ng.theme.lepton": "~5.3.4",
        "@angular/animations": "~13.3.3",
        "@angular/common": "~13.3.3",
        "@angular/compiler": "~13.3.3",
        "@angular/core": "~13.3.3",
        "@angular/forms": "~13.3.3",
        "@angular/localize": "~13.3.3",
        "@angular/platform-browser-dynamic": "~13.3.3",
        "@angular/platform-browser": "~13.3.3",
        "@angular/router": "~13.3.3",
        "rxjs": "~6.6.0",
        "tslib": "^2.1.0",
        "zone.js": "~0.11.4"
      },
    
  • User Avatar
    0
    ldacnfinit created

    Hello, I've send a email to you.

  • User Avatar
    0
    mahmut.gundogdu created

    Hello, I've send a email to you.

    I checked my email, but I didn't see anything about your email.

  • User Avatar
    0
    ldacnfinit created

    Sorry, I made a mistake about your email, I resend again, pleas have a look.

  • User Avatar
    0
    mahmut.gundogdu created

    Sorry, I made a mistake about your email, I resend again, pleas have a look.

    I have checked still I did not see anything. Does the problem still continue or is it fixed?

  • User Avatar
    0
    ldacnfinit created

    Yes, The question is still exist, I'll resend again, but I worried about you still can't receive the email from me, so I'll comment it.

    "dependencies": {
        "@abp/ng.components": "~5.3.3",
        "@abp/ng.core": "~5.3.3",
        "@abp/ng.setting-management": "~5.3.3",
        "@abp/ng.theme.shared": "~5.3.3",
        "@angular/animations": "~13.3.11",
        "@angular/common": "~13.3.11",
        "@angular/compiler": "~13.3.11",
        "@angular/core": "~13.3.11",
        "@angular/forms": "~13.3.11",
        "@angular/localize": "~13.3.11",
        "@angular/platform-browser": "~13.3.11",
        "@angular/platform-browser-dynamic": "~13.3.11",
        "@angular/router": "~13.3.11",
        "@uppy/core": "^1.13.2",
        "@uppy/dashboard": "^1.12.6",
        "@uppy/xhr-upload": "^1.6.4",
        "@volo/abp.commercial.ng.ui": "~5.3.3",
        "@volo/abp.ng.account": "~5.3.3",
        "@volo/abp.ng.audit-logging": "~5.3.3",
        "@volo/abp.ng.identity": "~5.3.3",
        "@volo/abp.ng.identity-server": "~5.3.3",
        "@volo/abp.ng.language-management": "~5.3.3",
        "@volo/abp.ng.saas": "~5.3.3",
        "@volo/abp.ng.text-template-management": "~5.3.3",
        "@volo/abp.ng.theme.lepton": "~5.3.3",
        "codelyzer": "^6.0.2",
        "flag-icon-css": "^4.1.7",
        "rxjs": "~6.6.0",
        "tslib": "^2.1.0",
        "tslint": "^6.1.3",
        "zone.js": "~0.11.4"
      },
      "devDependencies": {
        "@abp/ng.schematics": "~5.3.3",
        "@angular-devkit/build-angular": "^13.3.7",
        "@angular-eslint/builder": "~13.2.1",
        "@angular-eslint/eslint-plugin": "~13.2.1",
        "@angular-eslint/eslint-plugin-template": "~13.2.1",
        "@angular-eslint/schematics": "~13.2.1",
        "@angular-eslint/template-parser": "~13.2.1",
        "@angular/cli": "^13.3.7",
        "@angular/compiler-cli": "~13.3.11",
        "@angular/language-service": "~13.3.11",
        "@types/jasmine": "~3.6.0",
        "@types/node": "^12.11.1",
        "@typescript-eslint/eslint-plugin": "5.3.0",
        "@typescript-eslint/parser": "5.3.0",
        "eslint": "^8.2.0",
        "jasmine-core": "~3.7.0",
        "karma": "~6.3.0",
        "karma-chrome-launcher": "~3.1.0",
        "karma-coverage": "~2.1.0",
        "karma-jasmine": "~4.0.0",
        "karma-jasmine-html-reporter": "^1.7.0",
        "ng-packagr": "^13.1.2",
        "typescript": "~4.5.4"
      }
    
  • User Avatar
    0
    mahmut.gundogdu created

    Yes, The question is still exist, I'll resend again, but I worried about you still can't receive the email from me, so I'll comment it.

    "dependencies": { 
        "@abp/ng.components": "~5.3.3", 
        "@abp/ng.core": "~5.3.3", 
        "@abp/ng.setting-management": "~5.3.3", 
        "@abp/ng.theme.shared": "~5.3.3", 
        "@angular/animations": "~13.3.11", 
        "@angular/common": "~13.3.11", 
        "@angular/compiler": "~13.3.11", 
        "@angular/core": "~13.3.11", 
        "@angular/forms": "~13.3.11", 
        "@angular/localize": "~13.3.11", 
        "@angular/platform-browser": "~13.3.11", 
        "@angular/platform-browser-dynamic": "~13.3.11", 
        "@angular/router": "~13.3.11", 
        "@uppy/core": "^1.13.2", 
        "@uppy/dashboard": "^1.12.6", 
        "@uppy/xhr-upload": "^1.6.4", 
        "@volo/abp.commercial.ng.ui": "~5.3.3", 
        "@volo/abp.ng.account": "~5.3.3", 
        "@volo/abp.ng.audit-logging": "~5.3.3", 
        "@volo/abp.ng.identity": "~5.3.3", 
        "@volo/abp.ng.identity-server": "~5.3.3", 
        "@volo/abp.ng.language-management": "~5.3.3", 
        "@volo/abp.ng.saas": "~5.3.3", 
        "@volo/abp.ng.text-template-management": "~5.3.3", 
        "@volo/abp.ng.theme.lepton": "~5.3.3", 
        "codelyzer": "^6.0.2", 
        "flag-icon-css": "^4.1.7", 
        "rxjs": "~6.6.0", 
        "tslib": "^2.1.0", 
        "tslint": "^6.1.3", 
        "zone.js": "~0.11.4" 
      }, 
      "devDependencies": { 
        "@abp/ng.schematics": "~5.3.3", 
        "@angular-devkit/build-angular": "^13.3.7", 
        "@angular-eslint/builder": "~13.2.1", 
        "@angular-eslint/eslint-plugin": "~13.2.1", 
        "@angular-eslint/eslint-plugin-template": "~13.2.1", 
        "@angular-eslint/schematics": "~13.2.1", 
        "@angular-eslint/template-parser": "~13.2.1", 
        "@angular/cli": "^13.3.7", 
        "@angular/compiler-cli": "~13.3.11", 
        "@angular/language-service": "~13.3.11", 
        "@types/jasmine": "~3.6.0", 
        "@types/node": "^12.11.1", 
        "@typescript-eslint/eslint-plugin": "5.3.0", 
        "@typescript-eslint/parser": "5.3.0", 
        "eslint": "^8.2.0", 
        "jasmine-core": "~3.7.0", 
        "karma": "~6.3.0", 
        "karma-chrome-launcher": "~3.1.0", 
        "karma-coverage": "~2.1.0", 
        "karma-jasmine": "~4.0.0", 
        "karma-jasmine-html-reporter": "^1.7.0", 
        "ng-packagr": "^13.1.2", 
        "typescript": "~4.5.4" 
      } 
    

    Sorry I couldn't produce the issue with your information. I've created An abp angular app with 5.3.3 add source code of identity module. Copied your code on my role.component.ts Adding missing variables and I have couldn't see the error. Could you sent whole role.component.ts and role.component.html ?

  • User Avatar
    0
    ldacnfinit created

    I send the user.component file to you by email, please have a look. Thank you!

  • User Avatar
    0
    mahmut.gundogdu created

    I send the user.component file to you by email, please have a look. Thank you!

    This time, I got the email . I am looking. I will inform you soon

  • User Avatar
    0
    mahmut.gundogdu created

    I send the user.component file to you by email, please have a look. Thank you!

    I've added the user component to my project. It works as well as expected. There is no error in cli or browser console. The component can edit and create a new user.

  • User Avatar
    0
    ldacnfinit created

    Can you switch tab in edit modal?

  • User Avatar
    0
    mahmut.gundogdu created

    Can you switch tab in edit modal?

    I did notice the error, but it is an Angular-related problem. Neither the module system nor the abp have any bugs. We apologize, but we do not provide help for angular or programming concerns.

Made with ❤️ on ABP v9.1.0-preview. Updated on December 05, 2024, 12:19