0

I have a component that is subscribed to a subject which is returning employee records and putting them into an array.

importResults: ImportResults[] = [];

constructor(
    private _massEmpService: MassEmpService
) {
}

ngOnInit() {
    // Subscribe to our subject that lets us know about the added employees
    this._massEmpService.importedData.subscribe(obj => {
        if (obj) {
            // Ensure that we have unique results in our imported data
            this.importResults.push(_.uniqBy(obj, 'QID'));
        }
    });
}

My issue is that each time my button is clicked and this subscription receives data, its pushing the new data along side what is already there instead of ONLY adding records that don't exist.

Here is an example on a single record received (I entered one user name and clicked search)

enter image description here

Here is an example when I add one additional user, leaving the previous one in the search field.

enter image description here

As you can see, the first array is the original search result. The second array contains the first employee AND the new employee.

My expected outcome here is that there is a single array with unique objects. This would mean there should be 2 records from my example since the first employee was searched two times, he shouldnt be pushed or included into the array since that object already exists.

Am i using this lodash function incorrectly? QID is a unique valid key in the object as well (not pictured).

4
  • Have a look at using RxJS' distinct operator. Commented Jul 13, 2017 at 21:12
  • you can use union fron underscorejs: underscorejs.org/#union Commented Jul 14, 2017 at 4:36
  • @KetanAkbari - Any chance you could provide some type of example based on my scenario ? Commented Jul 14, 2017 at 4:41
  • you can also find find functions of underscorejs. first you can find similar object that you want to push if found then it will not push otherwise it will do. you can see example in below @Shailesh Ladumor answer. Commented Jul 14, 2017 at 4:58

6 Answers 6

2

You could try something like this using RxJS' distinct operator instead of manually checking for uniqueness yourself:

this._massEmpService.importedData
   .filter(obj => obj)
   .distinct(src => src.QID)
   .subscribe(obj => this.importResults.push(obj));
Sign up to request clarification or add additional context in comments.

2 Comments

When I try this, I get an error that src.QID (my unique value) is undefined due to this subscribe function not yet having data. This subscribe call is wrapped in an ngOnInit so its trying to checked for data it doesn't have yet.
Really hard to diagnose your problem as there's not enough code in the snippet and how it's used in the template. Try adding a filter before the distinct.
2

you can find first uoy object whatever you want push if not found then push it. for example

importResults: ImportResults[] = [];
import * as _ from 'lodash';
constructor(
    private _massEmpService: MassEmpService
) {
}

ngOnInit() {
    // Subscribe to our subject that lets us know about the added employees
    this._massEmpService.importedData.subscribe(obj => {
        if (obj) {
            // Ensure that we have unique results in our imported data
            const keyExists= this._find((obj);
                if(keyExists){
                   this.importResults.push(obj);
                }
        }
    });
   }

create find function into component

  private _find(cur_obj: any): any{
                return _.find(this.importResults, function (importResult: any): boolean {
                   return importResult.QID === cur_obj.QID;
                });
 }

this is example. you can change it based on your objects

5 Comments

I tried to use this solution and the change I made was to the function to change my unique value to QID. return importResult.QID === cur_obj.setting_key.QID;. No errors occur but nothing is pushed to the importResults array as expected.
I also tried changing this to if(!keyExists){ and when I try to push data after there is already a user, I get an error on this line return importResult.QID === cur_obj.setting_key.QID; saying that QID is undefined.
i have update answer based on your comment and check now
just remove setting_key from return importResult.QID === cur_obj.setting_key.QID;
you need to compare based on your object. i give you just example.
1

A simple way to remove the duplicates items in the array is by: Here I remove items that with duplicate names

var myArray= [ { 'name': 'Mac'}, {'name': 'Mac'}, {'name': 'John'} ,{'name': 'Edward'}];

console.log('----------------Before removing-------------');
console.log(myArray);
 myArray.forEach((item, index) => {
            if (index !== myArray.findIndex(i => i.name === item.name)) {
                myArray.splice(index, 1);
            }
            
        });
console.log('---------------After removing------------------');
console.log(myArray);

Comments

0

You can reset the importResults variable every time the subscription runs. Just replace the {} in the subscription() with this:

{
  if (obj) {
    this.importResults = [];
    // Ensure that we have unique results in our imported data
    this.importResults.push(_.uniqBy(obj, 'QID'));
  }

2 Comments

The issue is though, any records that have been selected will be reset correct? This component contains employee records with checkboxes next to them which allows them to pick ones they want to modify. From another component, they can add more employees to this list. If I am replacing the array each time, it will lose the state of any employees that are "checked". Due to this, I only wanted to push new data, not replace the whole thing.
You could copy the selected employee to a separate variable and use that instead. I use Lodash lodash.com to clone one variable to another. If you needed
0

This code doesn't really apply to all the object properties scenarios. I tried adding more properties to the array, and it didn't really remove the duplicacy.

var myArray= [ { 'name': 'Mac', 'id': '1', 'group_id': 66}, 
{'name': 'Mac', 'id': '2',  'group_id': 55},
{'name': 'John', 'id': '3',  'group_id': 66} ,
{'name': 'Edward', 'id': '4',  'group_id': 55}, 
{'name': 'Edward', 'id': '5',  'group_id': 70}];

console.log('----------------Before removing-------------');
console.log(myArray); myArray.forEach((item, index) => {
            if (index !== myArray.findIndex(i => i.group_id === item.group_id)) {
                myArray.splice(index+1, 1);
            }

        });
 console.log('---------------After removing------------------');
 console.log(myArray);

So I tried this code and this actually worked:

const data = [{name: 'AAA'}, {name: 'AAA'}, {name: 'BBB'}, {name: 'AAA'}];
function removeDuplicity(datas){
    return datas.filter((item, index,arr)=>{
    const c = arr.map(item=> item.name);
    return  index === c.indexOf(item.name)
  })`enter code here`
}

console.log(removeDuplicity(data))

Comments

0

You can try below code which worked for me.

1st example to identify whether array has duplicate object or not.

let hasDuplicate = false;
this.items.forEach((el) => {
            if (this.items.filter(x => x === el).length > 1) {
                this.hasDuplicate = true;
                return;
            }
        });

2nd example to get unique object from array.

let uniqueArr = [];
this.items.forEach((el) => {
            if (this.items.filter(x => x === el).length === 1) {
                this.uniqueArr.push(el);
            }
        });

I hope it will help someone.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.