简体   繁体   中英

Problem in adding object properties to specific object inside array in JavaScript

I have an object in JavaScript that looks something like this

{
product_id: "2",
product_name: "Drinks"
}

The name of the object is product.

There is an array that contains entries of the above object. So, each array item is an entry of the above object.

On button click I check if an object entry with a particular product_id (that is being searched) exists in the array or not. If the object with the particular product_id does not exist in the array then I have to add this new object in to the array. Whereas if the object entry with the particular product_id exists then first I have add a new property named "qty" to the object and then this object is to be added as the new entry in to the array.

Below is the code on button click.

I console.log() the array to see the result.

When the button is clicked the first time then I get the array entry correctly where it shows the object inside the array.

When the button is clicked the second time then the code goes in to the else condition and a new property (by the name qty) is added to the object and then the object is added in to the array. So, now the array has two object entries (first one is added through if condition and the second one is added through the else condition).

Strangely, the problem is that when the second time button is clicked and the else condition is executed then the code modifies the previous existing object entry (which already is there in the array) and adds qty property in that object entry as well.

Ideally it should treat these two as separate entries and if I modify the second object entry then the first entry (which already exists in the array) should remain as it is (which means without qty property) whereas it modifies the previous entry too and adds new one too.

OnButtonClick() {
  if (array.length === 0) {
    array.splice(0, 0, product);
  }
  else {
    product.qty = 1;
    array.splice(0, 0, this.product);
  }
}

Below is the full code:

// First Page: categories.ts sets the existing product object using a service 
// then navigates to the second page product.ts
ButtonClick() {
    this.Service.setProduct(product);
    this.route.navigate(['products']);
}

// Service page: service.ts

export class ManageService {
    products: any;
    ProductArray: any = [];

    constructor() { }
    public setProduct(data) {
      this.products = data;
    }

    public getProduct() {
        return this.products;
    }
}

//Second page: products.ts
// First it gathers the product object details that were passed from previous 
// categories.ts using getProduct() method in the service.ts 

export class ProductsPage implements OnInit {
    product: any = [];

    ngOnInit() {
        this.product = this.Service.getExtras();
    }

    ButtonClick(searchid: any) {
        // searchid is passed on button click
        let findsearchidarr = FindItem(searchid);
        if (findsearchidarr[0] === true) {
            this.Service.ProductArray[findsearchidarr[1]].quantity = 
++this.Service.ProductArray[findsearchidarr[1]].quantity;
            this.router.navigate(['categories']);
        }
        else if (findsearchidarr[0] === false) {
            this.product.quantity = 1;
            this.Service.ProductArray.splice(0, 0, this.product);
            this.router.navigate(['categories']);
        }
    }
FindItem (searchid: any) {
        let i = 0;
        let foundarray: any = [];

        for (let items of this.Service.ProductArray) {
        if (items.search_id.toLowerCase().includes(searchid)) {
            foundarray[0] = true;
            foundarray[1] = i;
            foundarray[2] = items.product_id;
            return foundarray;
        }
        i++;
        }
        foundarray[0] = false;
        foundarray[1] = -1;
        foundarray[2] = 0;
        return foundarray;
    }
}

See the logic below. It adds the quantity property to already existing object otherwise adds a new object to array.

products: any[] = [{
    product_id: "2",
    product_name: "Drinks"
  },
  {
    product_id: "3",
    product_name: "Wafers"
  },
  {
    product_id: "4",
    product_name: "Chocolates"
  }
];

productIDToSearch:number = 4;
quantityToAdd: number = 20;
let foundIndex = products.findIndex((val) => val.product_id == productIDToSearch);

if(this.foundIndex >= 0) {
    this.products[this.foundIndex].quantity = this.quantityToAdd;
}
else {
    this.products.push({product_id:productIDToSearch, product_name:'Ice-cream', quantityToAdd: 33});
    console.log(products);
}

Equivalent javascript code

 var products = [{ product_id: "2", product_name: "Drinks" }, { product_id: "3", product_name: "Wafers" }, { product_id: "4", product_name: "Chocolates" } ]; let productIDToSearch = 5; let quantityToAdd = 20; let foundIndex = products.findIndex((val) => val.product_id == productIDToSearch); if(foundIndex >= 0) { products[foundIndex].quantity = quantityToAdd; console.log(products); } else { products.push({product_id:productIDToSearch, product_name:'Ice-cream', quantityToAdd: 33}); console.log(products); } 

The issue is that in JavaScript objects are treated by reference and so it creates confusion (at least in my case) when I try to add any property or modify any property inside the array of objects.

The solution I found was to first copy the object to another object so that the "by reference" possibility is ruled out, then use the new "copied" object to mark a new entry. This solved the issue.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM