1

I am trying to remove duplicate entries in my array of objects where the infoPageId occurs more than once.

Now the logic worked when I used static data but since calling my API the array is empty when console logging.

The array of objects is pretty large therefore I thought wrapping my call in a promise would fix the issue, ensuring the array is fully loaded before tasks are performed on it.

Yet I still produce an empty array after the removal of duplicates. The array is populated after this function is carried out getBuyingGuides.

JSON DATA CALLED FROM SERVER:

this.infos = [ 
    {
        InfoPageId: 8, 
        DepartmentId: 1, 
        Name: "Pitched Roof Window Buying Guide", 
        Url: "buying-guide-pitched", 
        Html: "<div class="background-grey" style="position: rela….&nbsp;</p></div></div></div></div></div></div>"
    },
    {
        InfoPageId: 8, 
        DepartmentId: 1, 
        Name: "Pitched Roof Window Buying Guide", 
        Url: "buying-guide-pitched", 
        Html: "<div class="background-grey" style="position: rela….&nbsp;</p></div></div></div></div></div></div>"
    },
    {
        InfoPageId: 8, 
        DepartmentId: 1, 
        Name: "Pitched Roof Window Buying Guide", 
        Url: "buying-guide-pitched", 
        Html: "<div class="background-grey" style="position: rela….&nbsp;</p></div></div></div></div></div></div>"
    },
    {
        InfoPageId: 8, 
        DepartmentId: 1, 
        Name: "Pitched Roof Window Buying Guide", 
        Url: "buying-guide-pitched", 
        Html: "<div class="background-grey" style="position: rela….&nbsp;</p></div></div></div></div></div></div>"
    },
    ...
    {
        InfoPageId: 8, 
        DepartmentId: 1, 
        Name: "Pitched Roof Window Buying Guide", 
        Url: "buying-guide-pitched", 
        Html: "<div class="background-grey" style="position: rela….&nbsp;</p></div></div></div></div></div></div>"
    },
    {
        InfoPageId: 8, 
        DepartmentId: 1, 
        Name: "Pitched Roof Window Buying Guide", 
        Url: "buying-guide-pitched", 
        Html: "<div class="background-grey" style="position: rela….&nbsp;</p></div></div></div></div></div></div>"
    }
]
infos: Array<{InfoPageId: number, DepartmentId: number, Name: string, Url: string, Html: string, Title: string, Keywords: string, Description: string, InfoTypeId: number, DateCreated: Date, DateUpdated: Date, Hidden: boolean, AMPhtml: string, UseAmp: boolean, UseAmpVideo: boolean, UseCarousel: boolean, TradeOnly: boolean, TagId: number}> = [];

ngOnInit(): void {
    this.getBuyingGuides().then(() => this.getUniqueValues(this.infos));
}

getBuyingGuides() {
    this.infos = [];

    var promise = new Promise((resolve, reject) => {
        setTimeout(() => {
            this._SharedService.getAll().subscribe((data: any[]) => {
                data.forEach(e => {
                    if(e.InfoTypeId = 12) {
                        this.infos.push(
                            new infoPage(
                                e.InfoPageId, 
                                e.DepartmentId, 
                                e.Name, 
                                e.Url, 
                                e.Html,
                                e.Title, 
                                e.Keywords,
                                e.Description, 
                                e.InfoTypeId, 
                                e.DateCreated, 
                                e.DateUpdated, 
                                e.Hidden, 
                                e.AMPhtml,
                                e.UseAmp, 
                                e.UseAmpVideo, 
                                e.UseCarousel,
                                e.TradeOnly,
                                e.TagId
                            )
                        );
                    }     
                })
          })

          resolve();
        }, 
        1000
      );

      });

     return promise;
}

getUniqueValues(infos: Array<infoPage>) {      
    const out = infos.reduce(
        (acc, cur) => acc.some(
            x => x.InfoPageId === cur.InfoPageId
            ) ? acc : acc.concat(cur), 
        []
    )

    console.log(out)
}
KodeFor.Me
  • 13,069
  • 27
  • 98
  • 166
ashley g
  • 857
  • 3
  • 11
  • 21
  • If you are happy with my solution, don't forget to click the checkmark under the rating buttons :) Thank you in advance !! :) – KodeFor.Me May 27 '20 at 11:32

2 Answers2

1

Your problem seems to be in the following line of code:

if(e.InfoTypeId = 12) {

What you do is to assign the value 12 to the e.InfoTypeId and not making a logical comparison.

Try to change your code to if(e.InfoTypeId === 12) { and maybe this way you will solve your problem.

The rest of your architecture I don't know if it is correct, as I am not an Angular developer.

Hope my solution helps :)

KodeFor.Me
  • 13,069
  • 27
  • 98
  • 166
1

You don't necessarily have to convert it to a promise. The data is already asynchronous. You could apply both the filtering (InfoTypeId === 12 and removing duplicates) within the subscription. Try the following

infos: Array < {
  InfoPageId: number,
  DepartmentId: number,
  Name: string,
  Url: string,
  Html: string,
  Title: string,
  Keywords: string,
  Description: string,
  InfoTypeId: number,
  DateCreated: Date,
  DateUpdated: Date,
  Hidden: boolean,
  AMPhtml: string,
  UseAmp: boolean,
  UseAmpVideo: boolean,
  UseCarousel: boolean,
  TradeOnly: boolean,
  TagId: number
} > = [];

ngOnInit(): void {
  this.getBuyingGuides().then(() => this.getUniqueValues(this.infos));

  this._SharedService.getAll().subscribe(
    data => {
      console.log(data);       // <-- console log here
      this.infos = data.filter((item, index) => {
        const _item = JSON.stringify(item);
        return (
          (item.InfoPageId === 12) &&      // <-- filter by `InfoPageId === 12`
          (index === data.findIndex(obj => { return JSON.stringify(obj) === _item }))          // <-- filter duplicates
        );
      })
    },
    error => {
      // handle error
    }
  )
}

Filtering duplicates credit: https://stackoverflow.com/a/36744732/6513921

Working example: Stackblitz

Update

It seems there is an issue in the Html property of the response.

Eg. one Html property is assigned value

"<div class="background-grey" style="position: rela"><p>&nbsp;</p></div></div></div></div></div></div>"

The double quotes are mixed between property value definition and the HTML tag attribute definition. It could also be visualized from the coloring schmein the question. The attribute values must be enclosed in single quotes

"<div class='background-grey' style='position: rela'><p>&nbsp;</p></div></div></div></div></div></div>"

Update: filter duplicates only by InfoPageId

this.filtered = infos.filter((info, index) => 
  info.InfoTypeId === 12 &&
  infos.findIndex(obj => (obj.InfoPageId === info.InfoPageId)) === index
);

Working example: Stackblitz

Community
  • 1
  • 1
ruth
  • 29,535
  • 4
  • 30
  • 57
  • hmm i still seem to be returning an empty array can we continue in chat – ashley g May 27 '20 at 12:37
  • Then I've included a `console.log` in the answer immediately after the subscription. Please try it in your code and post the results in the question. – ruth May 27 '20 at 12:43
  • 0: {InfoPageId: 8, DepartmentId: 1, Name: "Pitched Roof Window Buying Guide", Url: "buying-guide-pitched", Html: "
    – ashley g May 27 '20 at 12:50
  • i put a console log after the data.filter line and it never seems to be hit – ashley g May 27 '20 at 12:56
  • I see an issue in the definition of the `Html` value definition. But I don't think that is the cause of the error. – ruth May 27 '20 at 12:59
  • no that's not the issue, im so stumped can we continue in chat – ashley g May 27 '20 at 13:00
  • Ok there was an issue in the answer. I was wrongfully using `InfoTypeId` instead of `InfoPageId`. I've the updated the answer. – ruth May 27 '20 at 13:04
  • no you was correct in using infoTypeId, i want to filter it where InfoTypeId is equal to 12 and then assure that there is no duplicate entries with the same infoPageId – ashley g May 27 '20 at 13:06
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/214741/discussion-between-michael-d-and-ashley-g). – ruth May 27 '20 at 13:07