0

I need a way to prevent showing duplicated content in angular template. I have an array of data, and some of those data share the same formId. In my template I am showing the name of the array, and if the formId is unique, then after there is a divider line, but if the array share the same formId the divider line is not shown until the formId is changed. So If I have the array:


[
  {
    id: 1,
    name: 'Test 1'
    formId: '8979f9879f'
  },
  {
    id: 2,
    name: 'Test 2'
    formId: '8979f9879f'
  },
  {
    id: 3,
    name: 'Test 3'
    formId: 'a8098981'
  },
]

The result should be:

Test 1
Test 2
_______
Test 3 ... and so on
The ones that share the same formId, I need to put in the same table layout, so I needed to group the data with same formId, getting the result like this:



    [
        8979f9879f: [
        {
          id: 1,
          name: Test 1,
          formId: 8979f9879f
        },
        {
          id: 2,
          name: Test 2,
          formId: 8979f9879f
        },
        ],
        a8098981: [
        {
          id: 3,
          name: Test 3,
          formId: a8098981
        }
      ]
    ]
Which is fine. But now in a template when I loop though this arrays: 


<ng-container *ngFor="let formItem of formListItems | async, index as i">
  <div *ngFor="let groupedItem of groupedFormListItems[formItem.formId]" ... 

I get the correct layout and result, only I get the duplicated result, because nested loop. So the layout on the page looks like this:

Test 1 Test 2


Test 1 Test 2


Test 3

I need somehow to check if the formId is already been looped through, but don't know how to do that.

SashaP
  • 19
  • 4
  • Seeing the items in the array, formId isn't unique. It's being repeated in the first and second items. You should check that and try your code again. – Eric Aig Nov 15 '22 at 21:11
  • No, so the formId should not be unique, the items can have same formId, that is why I need to group them, and show them as one column in layout. – SashaP Nov 15 '22 at 21:13

2 Answers2

2

you can use "reduce" to group elements

this.processFormData=this.formList.reduce((a:any,b:any)=>{
    const element=a.find(x=>x.formId==b.formId)
    if (element)
      element.items.push(b)
    else
      a.push({formId:b.formId,items:[b]})
      return a;
},[])

NOTE: The reduce return an array, has no sense return an abject if you want iterate over this

Eliseo
  • 50,109
  • 4
  • 29
  • 67
1

You need a better manipulation of the array, so that you can group same formId test together, but also keep them easily accessible via ngFor. Here's a quick and dirty solution.

Stackblitz Demo

export class AppComponent implements OnInit {
  formList = [
    {
      id: 1,
      name: 'Test 1',
      formId: '8979f9879f'
    },
    {
      id: 2,
      name: 'Test 2',
      formId: '8979f9879f'
    },
    {
      id: 3,
      name: 'Test 3',
      formId: 'a8098981'
    },
    {
      id: 4,
      name: 'Test 4',
      formId: 'g60c06'
    },
    {
      id: 5,
      name: 'Test 5',
      formId: 'a8098981'
    },
  ];

  processedData = [];


  ngOnInit() {
    this.processFormData();
  }

  processFormData() {
    this.formList.forEach(item => {
      if (this.processedData.length === 0) {
        this.insertProcessedData(item);
      } else {
        const existingForm = this.processedData.filter(x => x.formId === item.formId);
        if (existingForm && existingForm.length > 0) {
          existingForm[0]['data'].push(item);
        } else {
          this.insertProcessedData(item);
        }
      }
    });
  }

  insertProcessedData(item) {
    const obj = {};
    obj['formId'] = item.formId;
    obj['data'] = [item];
    this.processedData.push(obj);
  }
}

Result: enter image description here

Nehal
  • 13,130
  • 4
  • 43
  • 59
  • you can use reduce to group the array -it's more compact and better perfomance than your solution- – Eliseo Nov 16 '22 at 08:43