Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does two equal Objects shows 'not equal" in Angular 2

Tags:

angular

I Upload array from json file. every 1.5 second I check if there are any changes in file (at the moment I test on one file without any changes), but when I check if

    if ( this.itemsParentArray[i] !== this.itemInArray[i] )

it always shows that it's not equal, and console.log (""not equal")

Did I missed something in code??Here it is:

export class HomeComponent {
itemsParentArray = [];
itemInArray = [];
myRes: Content;
showAssigned:boolean = false;

constructor(private structureRequest: StructureRequestService) {
    setInterval(() => {
        this.timerGetStructure();
    }, 1500);
}
//  using with setInterval to get new data and sets into content Array with this.updateItems(result) if it's new

timerGetStructure() {
    this.structureRequest.sendRequest().subscribe((result) => this.updateItems(result));
}
updateItems(result) {
    this.myRes =  result;
    this.itemInArray = this.myRes.content;
    for ( let i = 0; i < this.itemInArray.length; i++) {
                if ( this.itemsParentArray[i] !== this.itemInArray[i] ) {
                   // this.itemsParentArray[i] = this.itemInArray[i];
                   console.log("not equal");
                }
            }
}

//
ngOnInit() {
    //makes http request and puts result into parentArray after 3 sec.
    this.structureRequest.sendRequest().subscribe((result) => this.viewNodes(result));
}
//view items
viewNodes(result) {
    setTimeout(() => {
        this.myRes =  result;
        this.itemsParentArray = this.myRes.content;
        this.showAssigned = true;
    }, 3000);
}
}

As you see it loads data from the same file (I do not change file data!!!):

this.itemsParentArray = this.myRes.content;

and (each 1.5 sec):

this.itemInArray = this.myRes.content;
like image 903
Serhiy Avatar asked Jun 13 '16 08:06

Serhiy


3 Answers

== and especially === don't check if the object contains the same properties with the same values. It just checks if it is the same object reference.

{} == {} 

or

{} === {}

also result in false.

See also Typescript: Avoid comparison by reference and How do I initialize a typescript object with a JSON object

Plunker example

like image 195
Günter Zöchbauer Avatar answered Oct 30 '22 05:10

Günter Zöchbauer


For me comparing two objects in Angular 2/4 I tried below code. which totally worked.

JSON.stringify(obj1) === JSON.stringify(obj2);

like image 43
Nirmal Kumar Sahoo Avatar answered Oct 30 '22 04:10

Nirmal Kumar Sahoo


I wrote this helper function in TypeScript:

export class Helper {
    private _recursiveProperties: string[] = ['RecursiveProperty', ...];

    public equals(obj1: any, obj2: any): boolean {
        if (typeof obj1 !== typeof obj2) {
            return false;
        }
        if ((obj1 === undefined && obj2 !== undefined) ||
            (obj2 === undefined && obj1 !== undefined) ||
            (obj1 === null && obj2 !== null) ||
            (obj2 === null && obj1 !== null)) {
            return false;
        }
        if (typeof obj1 === 'object') {
            if (Array.isArray(obj1)) {
                if (!Array.isArray(obj2) || obj1.length !== obj2.length) {
                    return false;
                }
                for (let i = 0; i < obj1.length; i++) {
                    if (!this.equals(obj1[i], obj2[i])) {
                        return false;
                    }
                }
            } else {
                for (let prop in obj1) {
                    if (obj1.hasOwnProperty(prop)) {
                        if (!obj2.hasOwnProperty(prop)) {
                            return false;
                        }
                        //Endless loop fix for recursive properties
                        if (this._recursiveProperties.indexOf(prop) >= 0) {
                            if (obj1[prop] !== obj2[prop]) {
                                return false;
                            }
                        } else if (!this.equals(obj1[prop], obj2[prop])) {
                            return false;
                        }
                    }
                }
                for (let prop in obj2) {
                    if (obj2.hasOwnProperty(prop)) {
                        if (!obj1.hasOwnProperty(prop)) {
                            return false;
                        }
                    }
                }
            }
            return true;
        }
        return obj1 === obj2;
    }
}

Where _recursiveProperties contains the names of the (if any) properties that cause an infinite loop. E.g. I had an object (obj1) with a property which contained a reference to another object (obj2) which in turn contained a reference to obj1.

If anyone has a better solution, please make a comment.

Usage would then be:

let helper = new Helper();
if (helper.equals(this.itemsParentArray[i], this.itemInArray[i]))
like image 2
Arg0n Avatar answered Oct 30 '22 06:10

Arg0n