简体   繁体   中英

ngFor Angular not showing array object sub object

So I've got a Array of Object.

0:
createdBy: null
createdDate: "2022-06-12T11:35:15.087"
description: null
moduleId: "b60d4fd5-7052-40e3-8abe-0f45ce1fc71e"
moduleName: "Factoring"
sectionId: "f17942f4-770f-42ea-bc3e-225bf15710ea"
updatedBy: null
updatedDate: null
1:
createdBy: null
createdDate: "2022-06-12T11:35:15.087"
description: null
moduleId: "0649f5db-8c9f-4641-8798-a0c9313e9824"
moduleName: "Location"
objModuleLevel: (2) [{…}, {…}] <-- this object is shown on console log
sectionId: "f17942f4-770f-42ea-bc3e-225bf15710ea"
updatedBy: null
updatedDate: null
userId: "fc3114ee-ef6a-442d-bec1-bff9fdfec2d1" <-- this id is also shown on console log

So as the data shown above this objModuleLevel: (2) [{…}, {…}] and this userId: "fc3114ee-ef6a-442d-bec1-bff9fdfec2d1" gets added on the above here is the typescript page.

          if (gP.filter(mo => mo.type === 'M')?.length > 0){
            levelData.moduleList.forEach(mL => {
              gP.filter(mo => mo.type === 'M').find((val, index) => {
                if (val.levelId === mL.moduleId) {
                  mL.objModuleLevel = val.objLevel;
                  mL.userId = val.userId;
                  return true;
                }
              });
            });
          }
          else {
            levelData.moduleList.forEach(mL => {
              mL.isTrue = false;
              mL.userId = this.editUserId;
            });
          }
        });
        
        this.moduleList = levelData.moduleList;
        this.subscriptions.push(getPermissionLevelPerUser);
        console.log(this.moduleList); <-- above complete data can be seen in this with objModuleLevel and userId
        this.ref.detectChanges();

Here is my HTML page.

<tr align="center" *ngFor="let module of moduleList ; let RowIndex = index;">
  <td>{{module.moduleName}}</td>
  <td>{{module.objModuleLevel}}</td> <-- this does not show as it is undefined
  <td>{{module.userId}}</td> <-- this does not show as it is undefined
</tr>

Even though I've used this.ref.detectChanges(); it shows data on *ngFor but does not show added data as objModuleLevel and userId .

The solution which I stumbled upon is this.

if (gP.filter(mo => mo.type === 'M')?.length > 0){
            levelData.moduleList.forEach(mL => {
              gP.filter(mo => mo.type === 'M').find((val, index) => {
                if (val.levelId === mL.moduleId) {
                  mL.objModuleLevel = val.objLevel;
                  mL.userId = val.userId;
                  this.ref.detectChanges(); <-- this would bind data on page
                  return true;
                }
              });
            });
          }
          else {
            levelData.moduleList.forEach(mL => {
              mL.isTrue = false;
              mL.userId = this.editUserId;
            });
          }
        });
        
        this.moduleList = levelData.moduleList;
        this.subscriptions.push(getPermissionLevelPerUser);
        console.log(this.moduleList); <-- above complete data can be seen in this with objModuleLevel and userId
        this.ref.detectChanges(); <-- this will not bind data on page load at first

As you can see in the code I put the this.ref.detectChanges(); inside the filter

gP.filter(mo => mo.type === 'M').find((val, index) => {
                    if (val.levelId === mL.moduleId) {
                      mL.objModuleLevel = val.objLevel;
                      mL.userId = val.userId;
                      this.ref.detectChanges(); <-- this would bind data on page
                      return true;
                    }
                  });

I don't truly understand the behaviour of binding inside a loop which has a filter works easily rather than binding outside the loop which sometimes work and sometimes don't.

Note that Even if you use the ChangeDetectorRef there is no change to be detected if you don't change the reference of the array used within the ngFor.

You could try change this line:

this.moduleList = levelData.moduleList;

for this one:

this.moduleList = [...levelData.moduleList];

Have you tried to use pipe async on *ngFor? But you need to change the type data of moduleList to become observable.

<tr align="center" *ngFor="let module of moduleList | async ; let RowIndex = index;">
  <td>{{module.moduleName}}</td>
  <td>{{module.objModuleLevel}}</td>
  <td>{{module.userId}}</td>
</tr>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM