Updating or adding items to an array using underscore library

A scenario involves an object with incoming data and an array that contains saved data. The goal is to check if the "cnName" from the new data already exists in the "savedData" array. If it does, then the object in "savedData" should be replaced with the new data object. If it does not exist, the new data should be pushed to the "cnData" array in "savedData."

newData = {
  "cnGroupName": "cnGroupName1",
  "cnData": [{
    "cnName": "cn3",
    "data": {
       "color": "blue",
       "size": "42",
       "position": "right"
    }
  }]
}

savedData = [{
  "cnGroupName": "cnGroupName1",
  "cnData": [{
    "cnName": "cn1",
    "data": {
      "color": "red",
      "size": "42",
      "position": "right"
    }
  }, {
    "cnName": "cn2",
    "data": {
      "color": "blue",
      "size": "11",
      "position": "top"
    }
  }]
}]

Underscore is being used in this implementation.

if(savedData.length){
    _.each(savedData, function(num, i){

        if(savedData[i].cnGroupName == newData.cnGroupName ){

            _.each(savedData[i].cnData, function(num, x){

               if(savedData[i].cnData[x].cnName == newData.cnData[0].cnName){

                    // Replace the existing object in savedData with newData
                    savedData[i].cnData[x] = newData.cnData[0] 

               }else{ 
                    // Push the new object to savedData as the cnName does not exist
                   savedData[i].cnData.push(newData.cnData[0])
                }
            })
        }else{
            // Push newData if the cnGroupName from newData is not in savedData
            savedData.push(newData)
        }
    })
}

The issue with this approach is that if the "cnName" does not exist in "savedData," the new data will be pushed multiple times based on the existing objects in "savedData."

Console logs in this plunker demonstrate that the new data is being duplicated.

http://plnkr.co/edit/GkBoe0F65BCEYiFuig57?p=preview

Two questions arise:

  1. Is there a more efficient method using underscore for this purpose?
  2. Is there a way to stop _.each() from proceeding to the next iteration?

Answer №1

If you need to find the first matching index and update it if not found, you can utilize the findIndex method.

if(savedData.length){
    var cnindex,
    index = _.findIndex(savedData, function (item) { return item.cnGroupName == newData.cnGroupName });
    if (index === -1)) {
        savedData.push(newData);
    } else {
        cnindex = _.findIndex(savedData[index].cnData, function (item) {return item.cnName == newData.cnData[0].cnName});
        if (cnindex === -1) {
            savedData[index].cnData.push(newData.cnData[0]);
        } else {
            savedData[index].cnData[cnindex] = newData.cnData[0];
        }
    }
}

It's important to note that when using each iteration, you can wrap it in a try-catch block and throw a custom error at the desired break point.

Answer №2

Why not try iterating through newData.cnData within the second _.each loop?

if(savedData.length > 0){

    _.each(savedData, function(num, i){

        if(savedData[i].cnGroupName == newData.cnGroupName ){

            _.each(newData.cnData, function(num, x){
           // ^ Change focus to this section


               if(savedData[i].cnData[x].cnName == newData.cnData[0].cnName){

                    // The cnName already exists in savedData, so replace
                    console.log("cn names are the same")
                    savedData[i].cnData[x] = newData.cnData[0] 


               }else{ 
                    // The cnName does NOT exist in savedData, so push
                    console.log("cn names are different")
                   savedData[i].cnData.push(newData.cnData[0])
                }
            })
        }else{
            // The cnGroupName from newData is not in savedData, so push newData
            savedData.push(newData)
        }
    })
}

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

Struggling to evenly separate users into groups with PHP

Hello everyone, I'm new to stack overflow and this is my first question here. My goal is to automatically assign students to random and equal (or mostly equal) groups. At the moment, I am focused on generating the group assignments only. In the futur ...

Dynamic image loading in React with custom properties

I'm facing an issue while trying to display an image using the source stored in this.props.src. The correct name of the image file I want to load, "koolImg", is being output by this.props.src. I have imported the file using: import koolImg from ' ...

Issue with locating JavaScript controller in Angular HTML file [Node.js/Angular]

Here are all the files and folders in my project located within the same directory. If you want to check out the project on Github, you can find it here: https://github.com/JohnsCurry/learnAngular. Just to confirm, they are all in the same folder. Unfortu ...

What is the best method for setting a session cookie securely while also using CSRF tokens?

In my express application, I am working on setting the session cookie to be secure. Here is the code snippet I have tried so far: app.use(express.cookieParser()); sessionOptions = definitions.REDIS; sessionOptions.ttl = definitions.session.expiration; app ...

Unlocking the potential of Three.js with mouse picking

I am looking to implement object picking in the following code snippet: var Three = new function () { this.scene = new THREE.Scene() this.camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000) this.camera.po ...

Triggering transitionend event once with an added if condition

Currently, I have an application of an if statement that examines whether an element contains a style attribute. In the event that the style attribute is absent, it appends inline styling. Conversely, if the style attribute exists, it is removed. Furthermo ...

Exploring the Integration of Material UI DatePicker with Firestore in ReactJS: Converting Firestore Timestamps to Date Format

The database is correctly recording the date, however, when displayed, the DatePicker does not recognize the date from the database as it is in timestamp format (seconds and nanoseconds). <DatePicker margin="normal" label="Data do pedido" ...

The function findOne from Mongoose seems to be non-existent, all while utilizing the Passport library

Whenever I try to implement my local strategy using the passport lib, I keep encountering this error. TypeError: UserModel.findOne is not a function I've spent hours searching for a solution that addresses this issue but haven't been successful ...

Utilizing a Dependency Injection container effectively

I am venturing into the world of creating a Node.js backend for the first time after previously working with ASP.NET Core. I am interested in utilizing a DI Container and incorporating controllers into my project. In ASP.NET Core, a new instance of the c ...

Are the JQuery appended elements exceeding the width of the parent div?

I have an HTML div that is styled using the Bootstrap class span9. <div class="span9"> <div id = "selectedtags" class="well"> </div> <button class="btn" type="button" id="delegatecontent">Generate report</button&g ...

Looking for advice on using the ternary operator in your code? Let us

In my JS file, the code $scope.button = id ? "Edit" : "Add"; is functioning correctly. I am trying to implement it in the View like this: <button name="saveBtn" class="btn btn-primary" tabindex="10">{{person.id ? 'Edit' : 'Add&ap ...

PHP, jQuery, and MySQL combine to create a powerful autocomplete feature for your

I've implemented the source code from into my project, but I'm facing an issue where I can't retrieve any results when typing in the autocomplete textbox. Could someone point out where I might be making a mistake? This is the code I am us ...

What is the best way to ensure that text fields remain hidden upon page load until the appropriate drop down option is chosen?

Is it possible to initially hide text fields and only reveal them when a specific drop down option is selected? The current JavaScript code somewhat achieves this, but I would like the input fields to remain hidden by default. <script language=" ...

Perform an asynchronous request using a data variable retrieved from a previous asynchronous request

I have a function using ajax to parse XML data. Here is an example: $.ajax({ type: "GET", url: "the.xml", dataType: "xml", success: function parseXml(data){ $(data).find("ITEM").each(function(){ var x = $("URL", this).t ...

Sinon.js: How to create a mock for an object initialized with the new keyword

Here is the code that I am working with: var async = require('async'), util = require('util'); var Parse = require('parse/node'); function signup(userInfo, callback) { var username = userInfo.username, email ...

Troubleshoot: Why is fs.createReadStream in node.js only reading the last line of

Hello, I am currently facing some frustrating issues while trying to stream the contents of my CSV file. Below is the code snippet I am using, and my struggles are hidden in the comments. var fileReadStream = fs.createReadStream(inFile); // I&a ...

Error Encountered: Module Not Located

I am encountering an error in my Project where it keeps showing 'Cannot find module' even after numerous attempts to install and uninstall packages simultaneously. The problem persists, and I can't seem to resolve it. https://i.sstatic.net/Z ...

Identify changes in attributes on elements that are updated automatically

On my webpage, I want to have two select boxes that are connected so their values always match. Here's an example: Imagine a page with two selects: <select class="myselector"> <option value='1'>1 <br> < ...

Mastering the art of nested await functions in JavaScript

In my current Nodejs application using mongoose, I am implementing cache with MongoDB in-memory and MongoDB database. This setup is running on Nodejs 8.9 with async/await support enabled. let get_func = async(userId) => { let is_cached = await c ...

On what occasion is a DOM element considered "prepared"?

Here's a question that might make you think twice: $(document).ready(function() { }); Sometimes, the simplest questions lead to interesting discussions. Imagine having a list of elements like this: <body> <p>Paragraph</p> < ...