0

I tried to do basic things. I have an array that contains multiple objects. I want to add new key-value pair in every array object.

I tried this by following code.

exports.addBuyOption = (arr) => {
    var newArr=arr;
    return new Promise((resolve, reject) => {
        for (let i = 0; i < newArr.length; i++) {
            newArr[i].name="new name" //updating the existing key value
            newArr[i].canBuy=true //new key value 
        }

        setTimeout(() => {
            resolve(newArr);
        }, 2000)
    })
}

I added set timeout as I just wanted to confirm whether the promise returned after the loop operation or not. Also when code does not run with the origin array then I make a new variable with newArr name but the code also does not work.

exports.addBuyOption = (arr) => {
    return new Promise((resolve, reject) => {
        for (let i = 0; i < arr.length; i++) {
            arr[i].name="new name" //updating the existing key value
            arr[i].canBuy=true //new key value 
        }

            resolve(arr);
    })
}

With this code, I was able to update my existing key-value but was not able to add any new key value. What am I doing wrong? I tried to change the method of adding key from dot operator to array indexing to Object.assign but none of them worked for me.

8
  • 1
    Why the timeout and promise? Is this not just straight forward object manipulation? Also please post a minimal reproducible example using the [<>] snippet editor Commented Feb 21, 2022 at 11:00
  • That code will definitely add the new property to the objects if updating the existing property works, unless those are very unusual objects that have had preventExtensions applied to them (in which case you can't add new properties). Please update your question with a minimal reproducible example demonstrating the problem, ideally a runnable one using Stack Snippets (the [<>] toolbar button); here's how to do one. Commented Feb 21, 2022 at 11:00
  • Side note: newArr is a misleading name for that variable. It isn't a new array, it's just another variable pointing at the same array arr does. There's no reason for that variable, you could just be using arr. If you actually wanted to make a copy of the array, you'd have to do that intentionally, and if you wanted to make a copy of the objects in the array, you'd have to do that too. Commented Feb 21, 2022 at 11:03
  • Also, your question has nothing whatsoever to do with html. Commented Feb 21, 2022 at 11:05
  • "I added set timeout as I just wanted to confirm whether the promise returned after the loop operation or not." Without the timeout, there's no purpose whatsoever to that promise. Commented Feb 21, 2022 at 11:07

1 Answer 1

1

With this code, I was able to update my existing key-value but was not able to add any new key value.

The only explanation for that would be that the objects in the array have had Object.preventExtensions applied to them. Here's an example:

function addBuyOption(arr) {
    for (let i = 0; i < arr.length; i++) {
        arr[i].name="new name" //updating the existing key value
        arr[i].canBuy=true //new key value 
    }
    return arr;
}

const arr = [
    {name: "old name 1"},
    {name: "old name 2"},
    {name: "old name 3"},
].map(Object.preventExtensions);
console.log("Before:");
console.log(JSON.stringify(arr, null, 4));
addBuyOption(arr);
console.log("After:");
console.log(JSON.stringify(arr, null, 4));
.as-console-wrapper {
    max-height: 100% !important;
}

(Note I did away with the promise, it doesn't do anything useful in this code.)

If that's what's going on, you can't add properties to the objects. But you can create a new array with copies of the objects with the new property:

function addBuyOption(arr) {
    return arr.map(obj => ({
        ...obj,           // Copy existing properties
        name: "new name", // Set new value for existing property
        canBuy: true,     // Set new property
    }));
}

const arr = [
    {id: 1, name: "old name 1"},
    {id: 2, name: "old name 2"},
    {id: 3, name: "old name 3"},
].map(Object.preventExtensions);
console.log("Before:");
console.log(JSON.stringify(arr, null, 4));
const newArr = addBuyOption(arr);
console.log("After:");
console.log(JSON.stringify(newArr, null, 4));
.as-console-wrapper {
    max-height: 100% !important;
}

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks. I checked some more answers and by using JSON stringify and parse method over the array, I was able to add a new key-value in the array. no problem in the code, it is actually mongoose that restricts the array to get updated(don't know why).
@Pranaykumar - "...and by using JSON stringify and parse method over the array, I was able to add a new key-value in the array..." You'll see people doing that, but my strongly recommendation is: Don't. JSON.parse(JSON.stringify(x)) is lossy and slow, it's an awful way to copy things. There's no reason to make a round-trip through text. Instead, do what I've shown above (shallow copy is all you need for what you've described), or do this in rare cases where you need a deep copy. Happy coding!

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.