What is the best way to eliminate an object from an array of objects that fulfills a specific condition?

Upon receiving an object in my function containing the information below:

{
  "name": "Grand modèle",
  "description": "Par 10",
  "price": 0,
  "functional_id": "grand_modele_par_10",
  "quantity": 2,
  "amount": 0
}

I must scan the next array of objects to locate and remove it.

[
  {
    "name": "Matériel crémation",
    "products": [
      {
        "file": "data:image/;base64,",
        "name": "Sacs bordeaux",
        "description": "Pour les crémations Référence",
        "id": 12,
        "path": "",
        "items": [
          {
            "name": "Petit modèle",
            "description": "Par 25",
            "price": 0,
            "functional_id": "petit_modele_par_25",
            "quantity": 2,
            "amount": 0
          },
          {
            "name": "Grand modèle",
            "description": "Par 10",
            "price": 0,
            "functional_id": "grand_modele_par_10",
            "quantity": 2,
            "amount": 0,
            "itemAdded": false
          }
        ]
      }
    ]
  },
  {
    "name": "Documents",
    "products": [
      {
        "file": "data:image/;base64,",
        "name": "Affiches procédure",
        "description": "De prise en charge",
        "id": 18,
        "path": "",
        "items": [
          {
            "price": 0,
            "functional_id": "affiches_procedure",
            "quantity": 1,
            "amount": 0
          }
        ]
      }
    ]
  }
]

I use a 'forEach' loop to find the item that matches the condition and remove it from the array of objects.

public deleteItem(item) {


        this.fullCartInfo.forEach(category => {
            category.products.forEach(product => {
                product.items.forEach(itemAdded => {
                    if (item.functional_id === itemAdded.functional_id) {
                        this.fullCartInfo.splice(itemAdded);
                    }
                });
            });
        });
        this.cartService.removeItem(item);
    }


However, instead of deleting only the matching item, the entire array gets emptied. What am I doing wrong here? Your help is much appreciated.

Answer №1

Array.prototype.splice(start[, deleteCount[, item1[, item2[, ...]]]])
function requires the index of the first element to be removed (start) and optionally specifies how many elements to remove (deleteCount).

Using the second argument of the Array.prototype.forEach() callback provides the start index, which is the index of the current element in the collection.

An example implementation involves:

  • a reduced dataset
  • a standard function instead of a class method, for easier manipulation. You can simply copy and paste the function body into your deleteItem method.

const objectToRemove = { "functional_id": "grand_modele_par_10" }

const objects = {
  fullCartInfo: [
    { "products": [{ "id": 12, "items": [{ "functional_id": "grand_modele_par_10" }] }] },
    { "products": [{ "id": 18, "items": [{ "functional_id": "affiches_procedure" }] }] }
  ]
}

function deleteItem(item) {
  this.fullCartInfo.forEach((category, index) => {  
    category.products.forEach(product => {
      product.items.forEach(itemAdded => {
        if (item.functional_id === itemAdded.functional_id) {
          this.fullCartInfo.splice(index, 1); 
        }
      });
    });
  });
}

deleteItem.apply(objects, [objectToRemove]);

console.log(objects);

However, this method only works when removing one item from the collection or removing items from the end. If you intend to remove multiple items, consider using .filter() or a reverse for loop.

.filter()

const objectToRemove = { "functional_id": "grand_modele_par_10" }

const objects = {
  fullCartInfo: [
    { "products": [{ "id": 12, "items": [{ "functional_id": "grand_modele_par_10" }] }] },
    { "products": [{ "id": 18, "items": [{ "functional_id": "affiches_procedure" }] }] }
  ]
}

function deleteItem(item) {
  this.fullCartInfo = this.fullCartInfo.filter((category, index) => {
    let keepCategory = true;
    
    category.products.forEach(product => {
      product.items.forEach(itemAdded => {
        if (item.functional_id === itemAdded.functional_id) {
          keepCategory = false;
        }
      });
    });
    
    return keepCategory;
  });
}

deleteItem.apply(objects, [objectToRemove]);
console.log(objects);

for loop in reverse

const objectToRemove = { "functional_id": "grand_modele_par_10" }

const objects = {
  fullCartInfo: [
    { "products": [{ "id": 12, "items": [{ "functional_id": "grand_modele_par_10" }] }] },
    { "products": [{ "id": 18, "items": [{ "functional_id": "affiches_procedure" }] }] }
  ]
}

function deleteItem(item) {
  for(let index = this.fullCartInfo.length - 1; index >= 0; index--) {
    this.fullCartInfo[index].products.forEach(product => {
      product.items.forEach(itemAdded => {
        if (item.functional_id === itemAdded.functional_id) {
          this.fullCartInfo.splice(index, 1);
        }
      });
    });
  }
}

deleteItem.apply(objects, [objectToRemove]);

console.log(objects);

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Error: The function m.easing[this.easing] is not defined

I have been working on creating anchor link scrolling and tooltip display using bootstrap, but I am encountering an issue. $(window).scroll(function(){ if ($(window).scrollTop() >= 100) { $('#header').addClass('fixed'); ...

Exploring Multidimensional Arrays

Looking at my array structure: { "stocks": { "0": { "name": "Stock Exchange", "current_price": 12843.973, "available_shares": 0, }, "1": { "acronym": "TSBC", "current_price": 503.106, "available_ ...

Uploading a file from a React contact form using Axios may result in S3 generating empty files

I have set up a test contact form that allows users to upload image attachments. The presignedURL AWS Lambda function is working properly After uploading, the image file (blob) appears as an image in the HTML, indicating successful addition Upon posting t ...

Issue with ng-selected when used alongside ng-options or ng-repeat in Angular

My application features a form where users can fill out their starting point and choose from 350 possible destinations to get directions using Google Maps. Users can select their destination by either clicking on a pin on the map or choosing from a drop-do ...

Tips for extracting information from a website with Selenium using Python

I am currently working on a project that requires me to extract certain information using Selenium from a webpage. The elements I need are not directly visible in the page's code, indicating they may be generated by JavaScript. Here is a snippet of my ...

PHP: Receiving notification if $_GET variable is void

When retrieving the array data, I use this code: $tags = $_GET['item']['tags']; if ($tags){ foreach ($tags as $tag){ The tags data is received from an input field, and it may be empty. If $tags does not receive any data, I enco ...

What is preventing the click event on this dynamically generated checkbox using jQuery?

Check out the jsFiddle Currently, I am utilizing a jQuery plugin that enables users to draw boxes within a designated area. Using jQuery, I have incorporated a checkbox (alongside a dropdown list) into the box that appears when the user releases the mouse ...

Toggle the visibility of table rows using checkboxes

I'm working with checkboxes to toggle the visibility of specific rows in a table based on their content matching the selected checkbox values. Checkboxes: <input type='checkbox' name='foo1' value='foo1' v-model="sele ...

"Customize the number of items displayed per page with Bootstrap Vue's perPage

I am currently working on a Vue project which you can view on codesandbox and utilizing bootstrap-vue. Within the project, there are multiple columns containing cards along with pagination: <template> <b-container> <b-row :cu ...

Discovering identical objects in two arrays in Angular using TypeScript is a breeze

I've hit a roadblock with a TypeScript problem in my Angular service. I have an array of ingredients: private ingredients: Ingredient[] = [ new Ingredient('farina', 500), new Ingredient('burro', 80), new Ingredient('ucc ...

Double trouble: Knockout validation errors displayed twice

Currently, I am using the knockout validation plugin to validate a basic form field. The validation functionality is working as expected, however, it seems to be displaying the same error message twice under the text box. The code snippet that I am using ...

What is the best way to save information from an ng-repeat loop into a variable before sending it to an API?

My goal is to store the selected value from ng-repeat in UI (user selection from dropdown) and assign it to a variable. function saveSelection() { console.log('inside function') var postToDatabase = []; vm.newApplicant.values ...

Modification of window size using jQuery animations

Currently, I am working on creating a sidebar that slides in from the left side of the screen. To achieve this effect, I have set the menu element to float left with a width of 40% and a margin-left of -40%. However, when I try to reveal the sidebar by sw ...

Responsive screen sizing in Vue.js

https://i.stack.imgur.com/8qwpn.png I added a margin-left to my component due to it being blocked by the side-bar and the "Roles" table. Is there a way to shift my table to the right when the screen width is less than 992? I need it to be responsive acro ...

The button's status changes to disabled until I click outside the input field in Angular

I am currently facing an issue with a form (heat index calculator) that requires 2 inputs - a dropdown and a button. The button is disabled when there are no inputs or if the inputs are invalid. Everything works correctly, except for the fact that even whe ...

Comparison Between Angular and Web API in Regards to Racing Condition with Databases

Currently, I am working on an Angular service that iterates through a list and makes web API calls to add or modify records in the database. The service operates on a small record set with a maximum of 10 records to update. After the loop completes, Angula ...

Shade within the autocomplete

Is there a way to make the color property warning work on my autocomplete element at all times, rather than just on focus? Any suggestions or workarounds? Check out this code sandbox for reference. I really want the warning color to be visible constantly ...

Unable to save cookies on mobile browsers, but functioning properly on desktop computers

Currently, I am facing an issue with my ExpressJS app hosted on Heroku and a frontend React app hosted on Netlify. The problem arises when a user logs in successfully and is directed to the home page showing personalized content. Upon landing on the home p ...

The Vue CLI build is displaying a blank page when hosted on an Apache server

I encountered an issue with vue cli. Running npm run serve went smoothly, but when I tried dev mode using npm run build-dev, the build process finished with a blank page displayed. The error message received was "Uncaught SyntaxError: Unexpected token &ap ...

What is the best way to link this information to access the data attribute?

Currently, I am looking to streamline the data retrieved from firebase so that it can be easily displayed in a FlatList component. How can I transform my data into a simple array that can be iterated over in the FlatList? UPDATE! I have multiple other coi ...