1

Below are duplicated fields i want to filter and just display one instead of both:

"release_dates":[ {"certification":"PG-13","iso_639_1":"","note":"Telluride Film Festival","release_date":"2018-08-31T00:00:00.000Z","type":1},

{"certification":"PG-13","iso_639_1":"","note":"","release_date":"2018-09-28T00:00:00.000Z","type":2}]}]}

component below display both records from above json:

import { Component, OnInit } from '@angular/core';
import { DomSanitizer } from '@angular/platform-browser';
import { ActivatedRoute } from '@angular/router';
import { MoviesService } from '../movies.service';

@Component({
  selector: 'app-movie',
  templateUrl: './movie.component.html',
  styleUrls: ['./movie.component.css']
})
export class MovieComponent implements OnInit {
  movie: Object;
  certification: Array<Object>;
  video: Object;
  constructor(
    private _moviesServices: MoviesService,
    private router: ActivatedRoute
  ) {

  }

  ngOnInit() {
    this.router.params.subscribe((params) => {
      const id = params['id'];
      this._moviesServices.getMovie(id).subscribe(movie => {
        this.movie = movie;
      });
      this._moviesServices.getCertification(id).subscribe((res: any) => {
        const usCertifications = res.results.filter((result: any) => {
          return result.iso_3166_1 === "US";
          // return this.certification === result.certificationAll;
        });
        this.certification = usCertifications;
      });

    })

  }

}

html:

<div class="mr-3" *ngIf="certification"><span *ngFor="let cert of certification">
          <span *ngFor="let release of cert.release_dates">
            <span class="badge badge-pill badge-warning" *ngIf="release.certification">{{release.certification}}</span>
          </span>
        </span>
      </div>
RRPANDEY
  • 235
  • 4
  • 15
  • 1
    Well those two are not duplicate values. They are different. One has a `note`, other does not, also release date is different. So based on what should they be filtered? – AT82 Aug 21 '19 at 17:22
  • 1
    And what is the actual response you get initially from `getCertification`, can you add a sample? – AT82 Aug 21 '19 at 17:56
  • yes i tried filtering by note keeping in mind but some of the places it's not available. – RRPANDEY Aug 22 '19 at 15:04

4 Answers4

2

You can add a function to remove duplicates in your component or use a pipe to do the same thing Something similar to this

result:any=[];
removeDuplicates(): any{
   this.certification.forEach((item)=>{
        if(this.result.indexOf(item) < 0) {
            this.result.push(item);
        }
   });
return this.result;
} 

And then call it in template

<div class="mr-3" *ngIf="certification"><span *ngFor="let cert of removeDuplicates(certification)">
          <span *ngFor="let release of cert.release_dates">
            <span class="badge badge-pill badge-warning" *ngIf="release.certification">{{release.certification}}</span>
          </span>
        </span>
      </div>
Barkha
  • 702
  • 3
  • 8
  • @ user8351493 I have added the full component code and tried but getting some error – RRPANDEY Aug 21 '19 at 15:55
  • 1
    What is the error? I have edited function inside forEach to use arrowNotation. Try if that works – Barkha Aug 21 '19 at 15:58
  • i have just added that function after ngOnInit() and again added your update but getting the same duplicates. after addeing arrowNotation no error but again same duplicates PG-13 twice – RRPANDEY Aug 21 '19 at 16:04
1

You can write a pipe where in it takes the array and returns the non duplicate items.

@Pipe({ name: 'duplicate' })
export class DuplicatePipe implements PipeTransform {
  transform(elements: any[]) {
     let result = [];
     elements.forEach(element => {
      if (!elements.find(fEle => fEle.certification === element.certification)) {
        result.push(element);
      }
    });
  return result;
  }
}

and in the template:

<div class="mr-3" *ngIf="certification"><span *ngFor="let cert of certification">
          <span *ngFor="let release of cert.release_dates | duplicate">
            <span class="badge badge-pill badge-warning" *ngIf="release.certification">{{release.certification}}</span>
          </span>
        </span>
</div>
Kaushik
  • 114
  • 2
1

I'm assuming you want to remove duplicates based on just certification property.

Component:

Add below removeDuplicates() function in your component.

We are using JavaScript Map object to keep track of duplicates.

removeDuplicates(certification): any {
    certification.forEach((item) => {
      var filteredResults = new Map();

      item['release_dates'].forEach((value) => {
        if (!filteredResults.has(value.certification)) {
          filteredResults.set(value.certification, value);
        }
      });

      item['release_dates'] = [];

      filteredResults.forEach((value, key) => {
        item['release_dates'].push(value);
      });
    });

    return certification;
  }

HTML:

In your HTML call removeDuplicates() function in *ngFor as shown below.

<div class="mr-3" *ngIf="certification">
    <span *ngFor="let cert of removeDuplicates(certification)">
    <span *ngFor="let release of cert.release_dates">
      <span class="badge badge-pill badge-warning" *ngIf="release.certification">{{release.certification}}<br></span>
    </span>
  </span>
</div>

You can see it live on StackBlitz: https://stackblitz.com/edit/angular-4yklwe

Nikhil
  • 6,493
  • 10
  • 31
  • 68
1

Taking a leap and assume you want to filter out the duplicates based on the certification property, so we can use filter() to do that. If it's not that property, just change the property you want to filter by in below code. Also I would assume that from the original response you get, you only want one object (US certificates), so no need to make an array with filter(), instead use find(). With that we get only one object. So I suggest the following:

certifications = [];

// ...

this._moviesServices.getCertification(id).subscribe((res: any) => {
  const uscerts = this.results.find((result: any) => (result.iso_3166_1 === "US"));

  if (uscerts && uscerts.release_dates && uscerts.release_dates.length) {
    this.certifications = uscerts.release_dates.filter((item, i, arr) =>
      // filter by what prop you want, here we use certification
      arr.findIndex((x) => (x.certification === item.certification)) === i);
  } else {
    this.certifications = [];
  }
});

Now you can iterate the array you have in this.certifications:

<span *ngFor="let release of certifications">
  {{release.certification}}
</span>

DEMO: StackBlitz

Also I would suggest you actually use a model for your data, not use any. Makes your life so much easier, when the IDE can warn you if you try to do something wrong ;)

AT82
  • 71,416
  • 24
  • 140
  • 167
  • 1
    Thank you for the help i think this was the easiest solution for me to fix this. I just added ngIf in case if no data it should restrict the badge(designer ui badge) to apear in view. Yes i will use the model. currently struggling with migrating from angularjs to latest. :) – RRPANDEY Aug 22 '19 at 14:59